GithubHelp home page GithubHelp logo

hsimport's Introduction

hsimport

Build Status Hackage

A command line program for extending the import list of a Haskell source file.

hsimport gets the module name and the symbol name to import as arguments, parses the given source file using the library haskell-src-exts and then tries to only extend the import list if it's necessary. If the symbol is already imported or if the whole module is already imported, then the given source file isn't changed.

Installation

cabal install hsimport

Examples

$> hsimport -m 'Control.Monad' SomeSource.hs
=> import Control.Monad

$> hsimport -m 'Control.Monad' -s 'when' SomeSource.hs
=> import Control.Monad (when)

$> hsimport -m 'Control.Monad' -q 'CM' SomeSource.hs
=> import qualified Control.Monad as CM

$> hsimport -m 'Control.Monad' --as 'CM' SomeSource.hs
=> import Control.Monad as CM

$> hsimport -m 'Data.Maybe' -s 'Maybe'
=> import Data.Maybe (Maybe)

$> hsimport -m 'Data.Maybe' -s 'Maybe' -a
=> import Data.Maybe (Maybe(..))

$> hsimport -m 'Data.Maybe' -s 'Maybe' -w 'Just'
=> import Data.Maybe (Maybe(Just))

$> hsimport -m 'Data.Maybe' -s 'Maybe' -w 'Just' -w 'Nothing'
=> import Data.Maybe (Maybe(Just, Nothing))

Configuration

The easiest way to configure hsimport is by creating a cabal project. An example for this is here.

The other way - which most likely isn't worth the hassle - is by writting a ~/.config/hsimport/hsimport.hs file:

-- ~/.config/hsimport/hsimport.hs
import qualified Language.Haskell.Exts as HS
import HsImport

main :: IO ()
main = hsimport $ defaultConfig { prettyPrint = prettyPrint, findImportPos = findImportPos }
   where
      -- This is a bogus implementation of prettyPrint, because it doesn't handle the
      -- qualified import case nor does it considers any explicitely imported or hidden symbols.
      prettyPrint :: ImportDecl -> String
      prettyPrint (ImportDecl { HS.importModule = HS.ModuleName _ modName }) =
         "import " ++ modName

      -- This findImportPos implementation will always add the new import declaration
      -- at the end of the current ones. The data type ImportPos has the two constructors
      -- After and Before.
      findImportPos :: ImportDecl -> [ImportDecl] -> Maybe ImportPos
      findImportPos         _             [] = Nothing
      findImportPos newImport currentImports = Just . After . last $ currentImports

The position of the configuration file depends on the result of getUserConfigDir "hsimport", which is a function from the package xdg-basedir, on linux like systems it is ~/.config/hsimport/hsimport.hs.

If you've modified the configuration file, then the next call of hsimport will ensure a rebuild. If you've installed hsimport with cabal install, without using a sandbox, then this should just work.

If you've build hsimport inside of a sandbox, then you most likely have to temporary modify the GHC_PACKAGE_PATH for the next call of hsimport, to point ghc to the global database and to the package database of the sandbox.

# global package database
$> export GLOBAL_PKG_DB=/usr/lib/ghc/package.conf.d/

# hsimport sandbox package database
$> export SANDBOX_PKG_DB=/home/you/hsimport-build-dir/.cabal-sandbox/*-packages.conf.d/

$> GHC_PACKAGE_PATH=$GLOBAL_PKG_DB:$SANDBOX_PKG_DB hsimport --help

Text Editor Integration

vim-hsimport

Command Line Usage

$> hsimport --help
hsimport [OPTIONS] [SOURCEFILE]
  A command line program for extending the import list of a Haskell source
  file.

Common flags:
  -m --modulename=ITEM     The module to import
  -s --symbolname=ITEM     The symbol to import, if empty, the entire module
                           is imported
  -a --all                 All constructors or methods of the symbol should
                           be imported: 'Symbol(..)'
  -w --with=ITEM           The constructors or methods of the symbol
                           should be imported: 'Symbol(With)'
  -q --qualifiedname=ITEM  The name to use for a qualified module import
  -o --outputsrcfile=FILE  Save modified source file to file, if empty, the
                           source file is modified inplace
  -h --help                Display help message
  -v --version             Print version information

Issues

There is some rudimentarily handling for code using CPP, but the import statements might be added at the wrong place, because the lines containing CPP directives are ignored and therefore they aren't considered in the source line count.

hsimport's People

Contributors

alanz avatar dan-t avatar fendor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hsimport's Issues

having an 'as' import

Currently it is possible to have a qualified import like import qualified Foo as Bar. Is it possible to have as import like import Foo as Bar? I can add a pr if you are interested.

Update version bump

Stackage moved tasty to version 1.2.
It looks like updating the version constraints on tasty allows this to build with newer package set without issue again.

Here's how to allow non-cabal users to `stack install hsimport`

Tried to stack install this so I don't have to keep a Cabal installation around just for playing with hsimport.. it gets stuck with this:

directory version 1.3.0.0 found
    - hsimport requires >=1.2.0.1 && <1.3

Does it have to be under 1.3 or can we up this? Experimentally I set it higher in hsimport.cabal in my local clone of this repo and after then running simply stack init to generate stack.yaml from your hsimport.cabal, now stack install proceeds just fine and the program builds/installs successfully.

Stack is quite the popular alternative to cabal, so why not apply this simple tweak to your hsimport.cabal! Since it's already on Stackage (apparently), anyone can then stack install hsimport just as with most of the other popular dev-helper tools

Add hiding parameter to import

Example:

> hsimport -m "Data.Text" --hiding "length"
import Data.Text hiding (length)

I would be happy to implement such a feature for hsimport if this is still in the scope of hsimport!

Update version constraints

Hello, hsimport looks super helpful! I had trouble installing it with Stack however. Ultimately I was able to do so by removing upper bounds on package versions in the cabal file, but I realize that's pretty drastic. Could you adjust the upper bounds? Here are the packages which packdeps says have moved ahead of your upper bounds.

$ packdeps hsimport.cabal
hsimport-0.6.5: Cannot accept the following packages
attoparsec 0.13.0.1
lens 4.13
tasty 0.11
tasty-golden 2.3.0.1

Add CI

Potential candidates:

  • azure
  • travis
  • circleci

Inserts module between haddock documentation and function.

Example is roughly taken from stack new test haskeleton
Example.hs

-- | An example module.
module Example (main) where

-- | An example function.
main :: IO ()
main = return ()

foo :: IO ()
foo = do
    _ <- async $ return ()
    return ()
> hsimport -m "Control.Concurrent.Async" Example.hs

Output:

-- | An example module.
module Example (main) where

-- | An example function.
import Control.Concurrent.Async
main :: IO ()
main = return ()

foo :: IO ()
foo = do
    _ <- async $ return ()
    return ()

Expected:

-- | An example module.
module Example (main) where

import Control.Concurrent.Async
-- | An example function.
main :: IO ()
main = return ()

foo :: IO ()
foo = do
    _ <- async $ return ()
    return ()

Interaction of import list and hiding lists

Currently, if we execute the following

> hsimport --hiding -m Data.Text -s isInfixOf Main.hs

on a file

import Data.Text (isInfixOf, isPrefixOf)

main = return ()

it results in:

import Data.Text (isInfixOf, isPrefixOf)
import Data.Text hiding (isInfixOf)

main = return ()

I would suggest, that it tries to be a little smarter, e.g. in this case, it should result in:

import Data.Text (isPrefixOf)

main = return ()

I imagine, the changed behaviour would increase the code complexity, but I think it makes a lot of sense.
If this is the better behaviour, I would be happy to provide a pr for it!

Infinite loop in `parseInvalidSource`

In some situations I found that parseInvalidSource loops forever.

I haven't put up a PR because I'm not 100% confident in the fix, but this seems to be working for me: jacobstanley@9aa61e5

I can't give you the file that had the problem unfortunately, but the cause was putting a call to a function on a line all by itself:

-- imports

pure

data Foo = Foo

GHC thinks pure is part of some template haskell, or something like that.

Odd behavior with errors.log

hasufell@localhost ~ $ echo "gaga" > ~/.cache/hsimport/errors.log && hsimport --help
hsimport: gaga

I got an error and then every subsequent call to hsimport just cats that error forever. What?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.