Skip to content

Latest commit

 

History

History
285 lines (216 loc) · 12.5 KB

TEXTEDITORS.md

File metadata and controls

285 lines (216 loc) · 12.5 KB

FLO Text Editors and Yesod/Haskell

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).

Text editor packages and settings

Atom

Atom is a modern, graphical, highly-extensible text-editor, good for beginners and advanced alike.

Atom settings

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

Atom packages

We recommend at least the Atom packages:

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).
  • 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 of yesod devel, run site via stack exec Snowdrift Development.

Other useful Atom packages to consider:

Emacs

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.

Emacs settings

Our included .dir-locals.el file makes Emacs use the recommended 4-space indentation.

Emacs packages and variants

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

Leksah is a Haskell-dedicated complete IDE in the works, but we're waiting for integration with Stack before we fully recommend it.

Vim

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.

Vim settings

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

Vim plugins

We recommend using a Vim plugin manager such as Vundle and the following plugins particularly relevant to snowdrift:

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.

Setting up tags to jump to function definitions

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.

Atom tag usage and updating

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.

Emacs tag usage

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)

Vim tag usage and updating

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.