This guide covers our recommended options for FLO (Free/Libre/Open) text-editors and IDE development tools for hacking on Snowdrift (NB: most of this applies equally to any Yesod-based project).
Atom is a modern, graphical, highly-extensible text-editor, good for beginners and advanced alike.
Some general settings:
- In the main Atom settings, leave soft tabs checked and set 4-space tabs
- Packages/Tree View: consider "Hide Ignored Names" and "Hide VCS Ignored Files"
- Consider disabling the "metrics" package to turn off Google Analytics
We recommend at least the Atom packages:
- language-shakespeare
- in the language-shakespeare package settings, change the hamlet tab-length to 2, leave others at 4
- language-haskell
The ide-haskell package offers further development tools including error-checking, linting, and type information. To install ide-haskell for Atom:
- Run
stack install ghc-mod hlint stylish-haskell --resolver nightly-2015-12-14
- "--resolver…" is needed until we update our main resolver to one that includes ghc-mod (likely lts-4 series if we stick to lts).
- Install the required Atom packages:
apm install language-haskell haskell-ghc-mod ide-haskell autocomplete-haskell
- Make sure
$HOME/.local/bin
is on the PATH accessible to Atom.- If your path isn't set already, run
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
(although other methods exist, this offers the most flexibility and works for starting atom from the command line or from a GUI launcher). To make the path active, log out of your system and log back in (to avoid logging out,source ~/.profile
will get the path in your terminal, but you'll have to start atom from the command line for now).
- If your path isn't set already, run
- NB: this installation is the easiest for now and will work for any other projects that use the same GHC version but will not work if you switch between projects that use different GHC versions.
- Note: ghc-mod will fail if it sees a dist/ directory which is made when you
run snowdrift via
stack exec yesod devel
, so until yesod-bin is updated to use Stack directly, delete (or rename) the /dist directory and instead ofyesod devel
, run site viastack exec Snowdrift Development
.
Other useful Atom packages to consider:
- Various Git-related tools:
- tree-view-git-status
- git-blame
- show-origin
- search the packages for other git tools worth considering
- General nice tools like minimap, cursor-history, clipboard-history, multi-cursor
- vim-mode (if you like vim style editing)
- consider the Clipboard as Default Register and Smartcase Search options
- incidentally, many normal Atom editing operations still work as well
- search packages for "vim-mode" to see extra related addons
GNU Emacs is a traditional, robust, keyboard-centric text editor with substantial Haskell support.
If you are new to Emacs, Emacs Prelude is an enhanced distribution of Emacs with better default configuration. It includes things like Helm and Projectile by default.
If you are coming from Vim, consider Spacemacs, an Emacs distribution that includes Vim's modal keybindings by default along with much of Prelude's default configuration. Aside from Spacemacs, you can get the Vim keybindings in any Emacs distribution using evil-mode.
Our included .dir-locals.el
file
makes Emacs use
the recommended 4-space indentation.
Emacs users should install Haskell Mode and Shakespeare Mode.
Also of interest:
-
Magit is a high-quality Emacs git interface.
-
Structured Haskell Mode (same author as Haskell Mode) takes a lot of tedium out of Haskell editing.
-
HIndent (same author again) will pretty-print your Haskell-code along the same lines as SHM.
-
Haskell Interactive Mode will enable automatic regeneration of the TAGS file. (Our .dir-locals.el file tells haskell-interactive-mode to do that)
Leksah is a Haskell-dedicated complete IDE in the works, but we're waiting for integration with Stack before we fully recommend it.
Vim is a robust traditional editor with a command-line style interface and great Haskell support.
Note: we recommend all vim users install vim-gtk
to enable access to system
clipboards, regardless of then using terminal-based vim or the gvim interface
with visual menus.
For working on our code, your ~/.vimrc file should include:
set textwidth=80 expandtab shiftwidth=4 tabstop=4
au FileType hamlet setl sw=2 sts=2 et
au Filetype gitcommit setl spell textwidth=72
Though opinions vary, we also recommend the following minimal .vimrc settings:
syntax on
set number title hlsearch ignorecase smartcase showbreak=↪
set wildmenu wildmode=longest,list,full
We recommend using a Vim plugin manager such as Vundle and the following plugins particularly relevant to snowdrift:
- vim-syntax-shakespeare
- haskell-vim
- vim-markdown
- vim2hs
- optional: add
set nofoldenable
to .vimrc to stop vim2hs function folding
- optional: add
The plugins listed above mostly do syntax highlighting and do not affect commands or basic operations, so they are safe for everyone to use without hesitation or learning process.
As an optional tool, Vim can do integrated Haskell error-checking and get type
information via ghcmod-vim. Follow
its install instructions except run
stack install ghc-mod --resolver nightly-2015-12-14
(note: this "--resolver…" bit can be ignored once ghc-mod is in the LTS
version we use) instead of the instruction to run "cabal install ghc-mod" (and
make sure ~/.local/bin is on your path). You may want to also try the associated
auto-completion tool neco-ghc. Note:
ghc-mod will fail if it sees a dist/ directory which is made when you run
snowdrift via stack exec yesod devel
, so until yesod-bin is updated to use
Stack directly, use workarounds such as temporarily renaming the /dist directory
when you want to use ghc-mod, or avoid yesod devel
entirely and run the site
instead via stack exec Snowdrift Development
.
We suggest several other general vim plugins for consideration (probably best to add these one at a time and understand what each does and see if you like the idea rather than add mindlessly). Ordered roughly by most strongly recommended: vim-sensible, vim-repeat, vim-supertab, vim-gitgutter, vim-surround, vim-commentary, ctrl-P, vim-easyclip (warning: alters common vim behavior), undotree, vim-fugitive, gitv, NERD tree & NERD tree git plugin; ag.vim (takes extra setup besides just plugin), vim-airline.
Many other options exist, although we'd rather contributors generally focus more on building Snowdrift than maximizing their Vim expertise.
The following works for all text-editors that recognize tags files.
-
run
stack install hasktags
(and make sure ~/.local/bin is in your path) -
In the snowdrift directory, run this big command to generate your tags file:
git ls-tree -r HEAD --name-only | grep -E '*.hs' | xargs hasktags -x -c --ignore-close-implementation
- That command works for Atom, Vim, and other ctags-based editors.
- For Emacs, change
-x -c
to-e
For edification, that long command is a pipeline that finds all committed files in the git repository, filters to just the Haskell ones, and passes those for tag processing (technically, there are other types of Haskell files, such as *.hsc and *.lhs, but we don't have them in Snowdrift.)
For convenience, you can edit ~/.bashrc and add a line to make an alias for the long command above, as in:
alias git-hasktags="git ls-tree -r HEAD --name-only | grep -E '*.hs' | xargs hasktags -x -c --ignore-close-implementation"
To auto-update whenever you check out a new branch, put the command into .git/hooks/post-checkout and make the hook file executable:
cat >> .git/hooks/post-checkout <<EOF git ls-tree -r HEAD --name-only | grep -E '*.hs' | xargs hasktags -x -c --ignore-close-implementation EOF chmod u+x .git/hooks/post-checkout
Now, you can quickly jump to tags with whatever mechanism your text editor uses.
The setup above works for functions defined within our local codebase. To add
tags for all the dependencies too, install
codex via
stack install codex --resolver nightly-2015-12-14
(and see the codex docs for
how to use, including a vim-specific setting). Otherwise,
Stackage will have documentation on
almost all of our dependencies.
With tags generated, Atom uses Ctrl-Shift-R to search for any tag, Ctrl-Alt-Down to jump to the definition of the symbol under the cursor, and Ctrl-Alt-Up to return (with vim-mode, Ctrl-] and Ctrl-t also work).
We hope to document how to auto-update tags whenever saving files in Atom, but
until we have that clear, you'll need to manually re-run git-hasktags
(set as
alias in instructions above) as needed.
If you use Helm, as recommended above, you can run M-x helm-etags-select
to select from the TAGS
file.
If you use haskell-interactive-mode, linked above, Emacs will
automatically regenerate the TAGS file for you (provided you have loaded
a file with C-c C-l
beforehand). If you don't want to use
haskell-interactive-mode for whatever reason, you can generate the tags
file with
git ls-tree -r HEAD --name-only | grep -E '*.hs' | xargs hasktags -e --ignore-close-implementation
M-t
is a good keybinding for helm-etags-select
, provided you don't
use transpose-words
:
(global-set-key (kbd "M-t") 'helm-etags-select)
With a tags file in place, Vim can jump to the definition of the symbol under the cursor with Ctrl-] and jump back with Ctrl-t. Also, when typing in insert mode, Ctrl-x followed by Ctrl-] will offer autocompletion for known tags.
To auto-update tags in Vim whenever a Haskell file gets written, use fast-tags:
-
run
stack install fast-tags
-
add an autocommand to the Haskell plugin file:
mkdir -p ~/.vim/after/ftplugin cat >> ~/.vim/after/ftplugin/haskell.vim <<EOF augroup fasttag autocmd! autocmd BufWritePost <buffer> silent !fast-tags % augroup END EOF
NB: so that we don't generate extra tags files in internal directories, make sure to only open vim from the main snowdrift project directory from now on.