diff --git a/docvim.cabal b/docvim.cabal
--- a/docvim.cabal
+++ b/docvim.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.3.1.2
+version:             0.3.1.3
 
 -- A short (one-line) description of the package.
 synopsis:            Documentation generator for Vim plug-ins
@@ -206,7 +206,7 @@
 source-repository this
   type:     git
   location: https://github.com/wincent/docvim.git
-  tag:      0.3.1.2
+  tag:      0.3.1.3
 
 executable docvim
   -- .hs or .lhs file containing the Main module.
@@ -219,7 +219,7 @@
   -- other-extensions:
 
   -- Other library packages from which modules are imported.
-  build-depends:       base >=4.8 && <4.10
+  build-depends:       base >=4.6 && <5
                ,       docvim
 
   ghc-options:         -W -Wall
diff --git a/lib/Text/Docvim/CLI.hs b/lib/Text/Docvim/CLI.hs
--- a/lib/Text/Docvim/CLI.hs
+++ b/lib/Text/Docvim/CLI.hs
@@ -4,6 +4,7 @@
 module Text.Docvim.CLI (run) where
 
 import Control.Monad
+import Data.List
 import Data.Maybe
 import System.FilePath hiding (hasExtension)
 import System.IO
@@ -31,7 +32,7 @@
 run = do
   opts <- options
   paths <- readDir (directory opts)
-  let filtered = filter isVimScript paths
+  let filtered = filter isVimScript $ sort paths
   parsed <- mapM (\path -> do
       when (verbose opts) (hPutStrLn stderr ("Parsing " ++ path))
       parse path
diff --git a/lib/Text/Docvim/Optimize.hs b/lib/Text/Docvim/Optimize.hs
--- a/lib/Text/Docvim/Optimize.hs
+++ b/lib/Text/Docvim/Optimize.hs
@@ -1,6 +1,6 @@
 module Text.Docvim.Optimize (optimize) where
 
-import Control.Lens hiding (Empty)
+import Control.Lens (children, transform)
 import Text.Docvim.AST
 
 -- | "Optimize" a Project's AST by eliminating empty paths.
diff --git a/lib/Text/Docvim/Printer/Markdown.hs b/lib/Text/Docvim/Printer/Markdown.hs
--- a/lib/Text/Docvim/Printer/Markdown.hs
+++ b/lib/Text/Docvim/Printer/Markdown.hs
@@ -1,5 +1,6 @@
 module Text.Docvim.Printer.Markdown (markdown) where
 
+import Control.Applicative ((<$>))
 import Control.Monad.Reader
 import Data.List
 import Data.Maybe
diff --git a/lib/Text/Docvim/Printer/Vim.hs b/lib/Text/Docvim/Printer/Vim.hs
--- a/lib/Text/Docvim/Printer/Vim.hs
+++ b/lib/Text/Docvim/Printer/Vim.hs
@@ -2,6 +2,7 @@
 
 module Text.Docvim.Printer.Vim (vimHelp) where
 
+import Control.Applicative ((<$>))
 import Control.Arrow
 import Control.Monad
 import Control.Monad.Reader
@@ -24,7 +25,6 @@
 data Operation = Append String
                | Delete Int -- unconditional delete count of Char
                | Slurp String -- delete string if present
--- TODO: make this a Maybe String directly instead of a record
 data Metadata = Metadata { pluginName :: Maybe String }
 data Context = Context { lineBreak :: String
                        , partialLine :: String
@@ -116,8 +116,6 @@
 defaultLineBreak = "\n"
 
 nodes :: [Node] -> Env
--- TODO: may want to suppress line breaking on first node (temporarily set very
--- high text width, to deal with issues like #23)
 nodes ns = concat <$> mapM node ns
 
 node :: Node -> Env
diff --git a/lib/Text/Docvim/Visitor.hs b/lib/Text/Docvim/Visitor.hs
--- a/lib/Text/Docvim/Visitor.hs
+++ b/lib/Text/Docvim/Visitor.hs
@@ -49,7 +49,7 @@
             ~(block, remainder) = break stop xs
             ~(extracted, unextracted) = go remainder
 
-postorder :: Monad m => ((a -> m c) -> (a -> m b)) -> (b -> m c) -> (a -> m c)
+postorder :: Monad m => ((a -> m c) -> a -> m b) -> (b -> m c) -> a -> m c
 postorder t f = go
   where
     go = t go >=> f
diff --git a/tests/Tasty.hs b/tests/Tasty.hs
--- a/tests/Tasty.hs
+++ b/tests/Tasty.hs
@@ -2,6 +2,7 @@
 
 module Main (main) where
 
+import Control.Applicative ((<$>))
 import Control.DeepSeq
 import Control.Exception hiding (assert)
 import Data.ByteString.Lazy.Char8 (pack, unpack)
@@ -125,7 +126,7 @@
       let
         output = do
           inputs <- getFixtures $ source </> "input"
-          contents <- mapM readFile inputs
+          contents <- mapM readFile (sort inputs)
           return $ pack $ normalize $ process contents
         name = takeBaseName source
         golden = "tests/fixtures/integration" </> (takeBaseName source) </> "golden/" ++ kind ++ ".golden"
@@ -189,8 +190,8 @@
   integrationSources <- getIntegrationFixtures "tests/fixtures/integration"
   defaultMain $ testGroup "Test suite"
     [ unitTests
-    , goldenTests "parser" parserSources p
-    , goldenTests "Markdown printer" markdownSources pm
-    , goldenTests "Vim help printer" vimHelpSources pv
+    , goldenTests "parser" (sort parserSources) p
+    , goldenTests "Markdown printer" (sort markdownSources) pm
+    , goldenTests "Vim help printer" (sort vimHelpSources) pv
     , integrationTests integrationSources
     ]
diff --git a/tests/fixtures/integration/ferret/golden/ast.golden b/tests/fixtures/integration/ferret/golden/ast.golden
--- a/tests/fixtures/integration/ferret/golden/ast.golden
+++ b/tests/fixtures/integration/ferret/golden/ast.golden
@@ -829,330 +829,8 @@
   , Fenced [ ":call pathogen#helptags()" ]
   , Project
       [ Unit
-          [ LetStatement { letLexpr = "s:jobs" , letValue = "{}" }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "s:channel_id"
-              , functionArguments = ArgumentList [ Argument "channel" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ GenericStatement "return matchstr(a:channel, '\\d\\+')" ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "s:info_from_channel"
-              , functionArguments = ArgumentList [ Argument "channel" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ LetStatement
-                      { letLexpr = "l:channel_id"
-                      , letValue = "s:channel_id(a:channel)"
-                      }
-                  , GenericStatement "if has_key(s:jobs, l:channel_id)"
-                  , GenericStatement "return s:jobs[l:channel_id]"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#search"
-              , functionArguments =
-                  ArgumentList [ Argument "command" , Argument "ack" ]
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ GenericStatement "call ferret#private#async#cancel()"
-                  , GenericStatement
-                      "call ferret#private#autocmd('FerretAsyncStart')"
-                  , LetStatement
-                      { letLexpr = "l:command_and_args "
-                      , letValue = "extend(split(&grepprg), a:command)"
-                      }
-                  , LetStatement
-                      { letLexpr = "l:job"
-                      , letValue = "job_start(l:command_and_args, {"
-                      }
-                  , GenericStatement
-                      "\\ 'err_cb': 'ferret#private#async#err_cb', 'out_cb': 'ferret#private#async#out_cb', 'close_cb': 'ferret#private#async#close_cb', 'err_mode': 'raw', 'out_mode': 'raw' })"
-                  , LetStatement
-                      { letLexpr = "l:channel" , letValue = "job_getchannel(l:job)" }
-                  , LetStatement
-                      { letLexpr = "l:channel_id"
-                      , letValue = "s:channel_id(l:channel)"
-                      }
-                  , LetStatement
-                      { letLexpr = "s:jobs[l:channel_id]" , letValue = "{" }
-                  , GenericStatement
-                      "\\ 'channel_id': l:channel_id, 'job': l:job, 'errors': [], 'output': [], 'pending_error': '', 'pending_output': '', 'pending_error_length': 0, 'pending_output_length': 0, 'ack': a:ack, 'window': win_getid() }"
-                  ]
-              }
-          , LetStatement
-              { letLexpr = "s:max_line_length" , letValue = "32768" }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#err_cb"
-              , functionArguments =
-                  ArgumentList [ Argument "channel" , Argument "msg" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ LetStatement
-                      { letLexpr = "l:info"
-                      , letValue = "s:info_from_channel(a:channel)"
-                      }
-                  , GenericStatement "if type(l:info) == 4"
-                  , LetStatement { letLexpr = "l:start" , letValue = "0" }
-                  , GenericStatement "while 1"
-                  , LetStatement
-                      { letLexpr = "l:idx" , letValue = "match(a:msg, '\\n', l:start)" }
-                  , GenericStatement "if l:idx==-1"
-                  , GenericStatement
-                      "if l:info.pending_error_length < s:max_line_length"
-                  , LetStatement
-                      { letLexpr = "l:rest" , letValue = "strpart(a:msg, l:start)" }
-                  , LetStatement
-                      { letLexpr = "l:length" , letValue = "strlen(l:rest)" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_error." , letValue = "l:rest" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_error_length+"
-                      , letValue = "l:length"
-                      }
-                  , GenericStatement "endif"
-                  , GenericStatement "break"
-                  , GenericStatement "else"
-                  , GenericStatement
-                      "if l:info.pending_error_length < s:max_line_length"
-                  , LetStatement
-                      { letLexpr = "l:info.pending_error."
-                      , letValue = "strpart(a:msg, l:start, l:idx - l:start)"
-                      }
-                  , GenericStatement "endif"
-                  , GenericStatement "call add(l:info.errors, l:info.pending_error)"
-                  , LetStatement
-                      { letLexpr = "l:info.pending_error" , letValue = "''" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_error_length" , letValue = "0" }
-                  , GenericStatement "endif"
-                  , LetStatement { letLexpr = "l:start" , letValue = "l:idx + 1" }
-                  , GenericStatement "endwhile"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#out_cb"
-              , functionArguments =
-                  ArgumentList [ Argument "channel" , Argument "msg" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ LetStatement
-                      { letLexpr = "l:info"
-                      , letValue = "s:info_from_channel(a:channel)"
-                      }
-                  , GenericStatement "if type(l:info) == 4"
-                  , LetStatement { letLexpr = "l:start" , letValue = "0" }
-                  , GenericStatement "while 1"
-                  , LetStatement
-                      { letLexpr = "l:idx" , letValue = "match(a:msg, '\\n', l:start)" }
-                  , GenericStatement "if l:idx==-1"
-                  , GenericStatement
-                      "if l:info.pending_output_length < s:max_line_length"
-                  , LetStatement
-                      { letLexpr = "l:rest" , letValue = "strpart(a:msg, l:start)" }
-                  , LetStatement
-                      { letLexpr = "l:length" , letValue = "strlen(l:rest)" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_output." , letValue = "l:rest" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_output_length+"
-                      , letValue = "l:length"
-                      }
-                  , GenericStatement "endif"
-                  , GenericStatement "break"
-                  , GenericStatement "else"
-                  , GenericStatement
-                      "if l:info.pending_output_length < s:max_line_length"
-                  , LetStatement
-                      { letLexpr = "l:info.pending_output."
-                      , letValue = "strpart(a:msg, l:start, l:idx - l:start)"
-                      }
-                  , GenericStatement "endif"
-                  , GenericStatement "call add(l:info.output, l:info.pending_output)"
-                  , LetStatement
-                      { letLexpr = "l:info.pending_output" , letValue = "''" }
-                  , LetStatement
-                      { letLexpr = "l:info.pending_output_length" , letValue = "0" }
-                  , GenericStatement "endif"
-                  , LetStatement { letLexpr = "l:start" , letValue = "l:idx + 1" }
-                  , GenericStatement "endwhile"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#close_cb"
-              , functionArguments = ArgumentList [ Argument "channel" ]
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ LetStatement
-                      { letLexpr = "l:info"
-                      , letValue = "s:info_from_channel(a:channel)"
-                      }
-                  , GenericStatement "if type(l:info) == 4"
-                  , GenericStatement "call remove(s:jobs, l:info.channel_id)"
-                  , GenericStatement
-                      "call ferret#private#autocmd('FerretAsyncFinish')"
-                  , GenericStatement "if !l:info.ack"
-                  , GenericStatement "call win_gotoid(l:info.window)"
-                  , GenericStatement "endif"
-                  , GenericStatement
-                      "call s:finalize_search(l:info.output, l:info.ack)"
-                  , GenericStatement "for l:error in l:info.errors"
-                  , GenericStatement "unsilent echomsg l:error"
-                  , GenericStatement "endfor"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#pull"
-              , functionArguments = ArgumentList []
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ GenericStatement "for l:channel_id in keys(s:jobs)"
-                  , LetStatement
-                      { letLexpr = "l:info" , letValue = "s:jobs[l:channel_id]" }
-                  , GenericStatement
-                      "call s:finalize_search(l:info.output, l:info.ack)"
-                  , GenericStatement "endfor"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#cancel"
-              , functionArguments = ArgumentList []
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ LetStatement { letLexpr = "l:canceled" , letValue = "0" }
-                  , GenericStatement "for l:channel_id in keys(s:jobs)"
-                  , LetStatement
-                      { letLexpr = "l:info" , letValue = "s:jobs[l:channel_id]" }
-                  , GenericStatement "call job_stop(l:info.job)"
-                  , GenericStatement "call remove(s:jobs, l:channel_id)"
-                  , LetStatement { letLexpr = "l:canceled" , letValue = "1" }
-                  , GenericStatement "endfor"
-                  , GenericStatement "if l:canceled"
-                  , GenericStatement
-                      "call ferret#private#autocmd('FerretAsyncFinish')"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#async#debug"
-              , functionArguments = ArgumentList []
-              , functionAttributes = [ "abort" ]
-              , functionBody = [ GenericStatement "return s:jobs" ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "s:finalize_search"
-              , functionArguments =
-                  ArgumentList [ Argument "output" , Argument "ack" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ GenericStatement "if a:ack"
-                  , GenericStatement "cexpr a:output"
-                  , GenericStatement
-                      "execute get(g:, 'FerretQFHandler', 'botright cwindow')"
-                  , GenericStatement "call ferret#private#post('qf')"
-                  , GenericStatement "else"
-                  , LexprStatement { lexprBang = False , lexprExpr = "a:output" }
-                  , GenericStatement "execute get(g:, 'FerretLLHandler', 'lwindow')"
-                  , GenericStatement "call ferret#private#post('location')"
-                  , GenericStatement "endif"
-                  ]
-              }
-          ]
-      , Unit
           [ FunctionDeclaration
               { functionBang = True
-              , functionName = "ferret#private#dispatch#search"
-              , functionArguments = ArgumentList [ Argument "command" ]
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ GenericStatement "if has('autocmd')"
-                  , GenericStatement "augroup FerretPostQF"
-                  , GenericStatement "autocmd!"
-                  , GenericStatement
-                      "autocmd QuickfixCmdPost cgetfile call ferret#private#post('qf')"
-                  , GenericStatement "augroup END"
-                  , GenericStatement "endif"
-                  , LetStatement
-                      { letLexpr = "l:original_makeprg" , letValue = "&l:makeprg" }
-                  , LetStatement
-                      { letLexpr = "l:original_errorformat"
-                      , letValue = "&l:errorformat"
-                      }
-                  , GenericStatement "try"
-                  , LetStatement
-                      { letLexpr = "&l:makeprg"
-                      , letValue = "&grepprg . ' ' . a:command"
-                      }
-                  , LetStatement
-                      { letLexpr = "&l:errorformat" , letValue = "&grepformat" }
-                  , GenericStatement "echomsg &l:makeprg"
-                  , GenericStatement "Make"
-                  , GenericStatement "catch"
-                  , GenericStatement "call ferret#private#clearautocmd()"
-                  , GenericStatement "finally"
-                  , LetStatement
-                      { letLexpr = "&l:makeprg" , letValue = "l:original_makeprg" }
-                  , LetStatement
-                      { letLexpr = "&l:errorformat"
-                      , letValue = "l:original_errorformat"
-                      }
-                  , GenericStatement "endtry"
-                  ]
-              }
-          ]
-      , Unit
-          [ FunctionDeclaration
-              { functionBang = True
-              , functionName = "s:finalize_search"
-              , functionArguments =
-                  ArgumentList [ Argument "output" , Argument "ack" ]
-              , functionAttributes = []
-              , functionBody =
-                  [ GenericStatement "if a:ack"
-                  , GenericStatement "cexpr a:output"
-                  , GenericStatement
-                      "execute get(g:, 'FerretQFHandler', 'botright cwindow')"
-                  , GenericStatement "call ferret#private#post('qf')"
-                  , GenericStatement "else"
-                  , LexprStatement { lexprBang = False , lexprExpr = "a:output" }
-                  , GenericStatement "execute get(g:, 'FerretLLHandler', 'lwindow')"
-                  , GenericStatement "call ferret#private#post('location')"
-                  , GenericStatement "endif"
-                  ]
-              }
-          , FunctionDeclaration
-              { functionBang = True
-              , functionName = "ferret#private#vanilla#search"
-              , functionArguments =
-                  ArgumentList [ Argument "command" , Argument "ack" ]
-              , functionAttributes = [ "abort" ]
-              , functionBody =
-                  [ LetStatement
-                      { letLexpr = "l:output"
-                      , letValue = "system(&grepprg . ' ' . a:command)"
-                      }
-                  , GenericStatement "call s:finalize_search(l:output, a:ack)"
-                  ]
-              }
-          ]
-      , Unit
-          [ FunctionDeclaration
-              { functionBang = True
               , functionName = "s:delete"
               , functionArguments =
                   ArgumentList [ Argument "first" , Argument "last" ]
@@ -1594,6 +1272,328 @@
                   , GenericStatement "call s:delete(l:firstline, l:lastline)"
                   , LetStatement
                       { letLexpr = "&selection" , letValue = "l:selection" }
+                  ]
+              }
+          ]
+      , Unit
+          [ LetStatement { letLexpr = "s:jobs" , letValue = "{}" }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "s:channel_id"
+              , functionArguments = ArgumentList [ Argument "channel" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ GenericStatement "return matchstr(a:channel, '\\d\\+')" ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "s:info_from_channel"
+              , functionArguments = ArgumentList [ Argument "channel" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ LetStatement
+                      { letLexpr = "l:channel_id"
+                      , letValue = "s:channel_id(a:channel)"
+                      }
+                  , GenericStatement "if has_key(s:jobs, l:channel_id)"
+                  , GenericStatement "return s:jobs[l:channel_id]"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#search"
+              , functionArguments =
+                  ArgumentList [ Argument "command" , Argument "ack" ]
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ GenericStatement "call ferret#private#async#cancel()"
+                  , GenericStatement
+                      "call ferret#private#autocmd('FerretAsyncStart')"
+                  , LetStatement
+                      { letLexpr = "l:command_and_args "
+                      , letValue = "extend(split(&grepprg), a:command)"
+                      }
+                  , LetStatement
+                      { letLexpr = "l:job"
+                      , letValue = "job_start(l:command_and_args, {"
+                      }
+                  , GenericStatement
+                      "\\ 'err_cb': 'ferret#private#async#err_cb', 'out_cb': 'ferret#private#async#out_cb', 'close_cb': 'ferret#private#async#close_cb', 'err_mode': 'raw', 'out_mode': 'raw' })"
+                  , LetStatement
+                      { letLexpr = "l:channel" , letValue = "job_getchannel(l:job)" }
+                  , LetStatement
+                      { letLexpr = "l:channel_id"
+                      , letValue = "s:channel_id(l:channel)"
+                      }
+                  , LetStatement
+                      { letLexpr = "s:jobs[l:channel_id]" , letValue = "{" }
+                  , GenericStatement
+                      "\\ 'channel_id': l:channel_id, 'job': l:job, 'errors': [], 'output': [], 'pending_error': '', 'pending_output': '', 'pending_error_length': 0, 'pending_output_length': 0, 'ack': a:ack, 'window': win_getid() }"
+                  ]
+              }
+          , LetStatement
+              { letLexpr = "s:max_line_length" , letValue = "32768" }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#err_cb"
+              , functionArguments =
+                  ArgumentList [ Argument "channel" , Argument "msg" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ LetStatement
+                      { letLexpr = "l:info"
+                      , letValue = "s:info_from_channel(a:channel)"
+                      }
+                  , GenericStatement "if type(l:info) == 4"
+                  , LetStatement { letLexpr = "l:start" , letValue = "0" }
+                  , GenericStatement "while 1"
+                  , LetStatement
+                      { letLexpr = "l:idx" , letValue = "match(a:msg, '\\n', l:start)" }
+                  , GenericStatement "if l:idx==-1"
+                  , GenericStatement
+                      "if l:info.pending_error_length < s:max_line_length"
+                  , LetStatement
+                      { letLexpr = "l:rest" , letValue = "strpart(a:msg, l:start)" }
+                  , LetStatement
+                      { letLexpr = "l:length" , letValue = "strlen(l:rest)" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_error." , letValue = "l:rest" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_error_length+"
+                      , letValue = "l:length"
+                      }
+                  , GenericStatement "endif"
+                  , GenericStatement "break"
+                  , GenericStatement "else"
+                  , GenericStatement
+                      "if l:info.pending_error_length < s:max_line_length"
+                  , LetStatement
+                      { letLexpr = "l:info.pending_error."
+                      , letValue = "strpart(a:msg, l:start, l:idx - l:start)"
+                      }
+                  , GenericStatement "endif"
+                  , GenericStatement "call add(l:info.errors, l:info.pending_error)"
+                  , LetStatement
+                      { letLexpr = "l:info.pending_error" , letValue = "''" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_error_length" , letValue = "0" }
+                  , GenericStatement "endif"
+                  , LetStatement { letLexpr = "l:start" , letValue = "l:idx + 1" }
+                  , GenericStatement "endwhile"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#out_cb"
+              , functionArguments =
+                  ArgumentList [ Argument "channel" , Argument "msg" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ LetStatement
+                      { letLexpr = "l:info"
+                      , letValue = "s:info_from_channel(a:channel)"
+                      }
+                  , GenericStatement "if type(l:info) == 4"
+                  , LetStatement { letLexpr = "l:start" , letValue = "0" }
+                  , GenericStatement "while 1"
+                  , LetStatement
+                      { letLexpr = "l:idx" , letValue = "match(a:msg, '\\n', l:start)" }
+                  , GenericStatement "if l:idx==-1"
+                  , GenericStatement
+                      "if l:info.pending_output_length < s:max_line_length"
+                  , LetStatement
+                      { letLexpr = "l:rest" , letValue = "strpart(a:msg, l:start)" }
+                  , LetStatement
+                      { letLexpr = "l:length" , letValue = "strlen(l:rest)" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_output." , letValue = "l:rest" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_output_length+"
+                      , letValue = "l:length"
+                      }
+                  , GenericStatement "endif"
+                  , GenericStatement "break"
+                  , GenericStatement "else"
+                  , GenericStatement
+                      "if l:info.pending_output_length < s:max_line_length"
+                  , LetStatement
+                      { letLexpr = "l:info.pending_output."
+                      , letValue = "strpart(a:msg, l:start, l:idx - l:start)"
+                      }
+                  , GenericStatement "endif"
+                  , GenericStatement "call add(l:info.output, l:info.pending_output)"
+                  , LetStatement
+                      { letLexpr = "l:info.pending_output" , letValue = "''" }
+                  , LetStatement
+                      { letLexpr = "l:info.pending_output_length" , letValue = "0" }
+                  , GenericStatement "endif"
+                  , LetStatement { letLexpr = "l:start" , letValue = "l:idx + 1" }
+                  , GenericStatement "endwhile"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#close_cb"
+              , functionArguments = ArgumentList [ Argument "channel" ]
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ LetStatement
+                      { letLexpr = "l:info"
+                      , letValue = "s:info_from_channel(a:channel)"
+                      }
+                  , GenericStatement "if type(l:info) == 4"
+                  , GenericStatement "call remove(s:jobs, l:info.channel_id)"
+                  , GenericStatement
+                      "call ferret#private#autocmd('FerretAsyncFinish')"
+                  , GenericStatement "if !l:info.ack"
+                  , GenericStatement "call win_gotoid(l:info.window)"
+                  , GenericStatement "endif"
+                  , GenericStatement
+                      "call s:finalize_search(l:info.output, l:info.ack)"
+                  , GenericStatement "for l:error in l:info.errors"
+                  , GenericStatement "unsilent echomsg l:error"
+                  , GenericStatement "endfor"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#pull"
+              , functionArguments = ArgumentList []
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ GenericStatement "for l:channel_id in keys(s:jobs)"
+                  , LetStatement
+                      { letLexpr = "l:info" , letValue = "s:jobs[l:channel_id]" }
+                  , GenericStatement
+                      "call s:finalize_search(l:info.output, l:info.ack)"
+                  , GenericStatement "endfor"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#cancel"
+              , functionArguments = ArgumentList []
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ LetStatement { letLexpr = "l:canceled" , letValue = "0" }
+                  , GenericStatement "for l:channel_id in keys(s:jobs)"
+                  , LetStatement
+                      { letLexpr = "l:info" , letValue = "s:jobs[l:channel_id]" }
+                  , GenericStatement "call job_stop(l:info.job)"
+                  , GenericStatement "call remove(s:jobs, l:channel_id)"
+                  , LetStatement { letLexpr = "l:canceled" , letValue = "1" }
+                  , GenericStatement "endfor"
+                  , GenericStatement "if l:canceled"
+                  , GenericStatement
+                      "call ferret#private#autocmd('FerretAsyncFinish')"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#async#debug"
+              , functionArguments = ArgumentList []
+              , functionAttributes = [ "abort" ]
+              , functionBody = [ GenericStatement "return s:jobs" ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "s:finalize_search"
+              , functionArguments =
+                  ArgumentList [ Argument "output" , Argument "ack" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ GenericStatement "if a:ack"
+                  , GenericStatement "cexpr a:output"
+                  , GenericStatement
+                      "execute get(g:, 'FerretQFHandler', 'botright cwindow')"
+                  , GenericStatement "call ferret#private#post('qf')"
+                  , GenericStatement "else"
+                  , LexprStatement { lexprBang = False , lexprExpr = "a:output" }
+                  , GenericStatement "execute get(g:, 'FerretLLHandler', 'lwindow')"
+                  , GenericStatement "call ferret#private#post('location')"
+                  , GenericStatement "endif"
+                  ]
+              }
+          ]
+      , Unit
+          [ FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#dispatch#search"
+              , functionArguments = ArgumentList [ Argument "command" ]
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ GenericStatement "if has('autocmd')"
+                  , GenericStatement "augroup FerretPostQF"
+                  , GenericStatement "autocmd!"
+                  , GenericStatement
+                      "autocmd QuickfixCmdPost cgetfile call ferret#private#post('qf')"
+                  , GenericStatement "augroup END"
+                  , GenericStatement "endif"
+                  , LetStatement
+                      { letLexpr = "l:original_makeprg" , letValue = "&l:makeprg" }
+                  , LetStatement
+                      { letLexpr = "l:original_errorformat"
+                      , letValue = "&l:errorformat"
+                      }
+                  , GenericStatement "try"
+                  , LetStatement
+                      { letLexpr = "&l:makeprg"
+                      , letValue = "&grepprg . ' ' . a:command"
+                      }
+                  , LetStatement
+                      { letLexpr = "&l:errorformat" , letValue = "&grepformat" }
+                  , GenericStatement "echomsg &l:makeprg"
+                  , GenericStatement "Make"
+                  , GenericStatement "catch"
+                  , GenericStatement "call ferret#private#clearautocmd()"
+                  , GenericStatement "finally"
+                  , LetStatement
+                      { letLexpr = "&l:makeprg" , letValue = "l:original_makeprg" }
+                  , LetStatement
+                      { letLexpr = "&l:errorformat"
+                      , letValue = "l:original_errorformat"
+                      }
+                  , GenericStatement "endtry"
+                  ]
+              }
+          ]
+      , Unit
+          [ FunctionDeclaration
+              { functionBang = True
+              , functionName = "s:finalize_search"
+              , functionArguments =
+                  ArgumentList [ Argument "output" , Argument "ack" ]
+              , functionAttributes = []
+              , functionBody =
+                  [ GenericStatement "if a:ack"
+                  , GenericStatement "cexpr a:output"
+                  , GenericStatement
+                      "execute get(g:, 'FerretQFHandler', 'botright cwindow')"
+                  , GenericStatement "call ferret#private#post('qf')"
+                  , GenericStatement "else"
+                  , LexprStatement { lexprBang = False , lexprExpr = "a:output" }
+                  , GenericStatement "execute get(g:, 'FerretLLHandler', 'lwindow')"
+                  , GenericStatement "call ferret#private#post('location')"
+                  , GenericStatement "endif"
+                  ]
+              }
+          , FunctionDeclaration
+              { functionBang = True
+              , functionName = "ferret#private#vanilla#search"
+              , functionArguments =
+                  ArgumentList [ Argument "command" , Argument "ack" ]
+              , functionAttributes = [ "abort" ]
+              , functionBody =
+                  [ LetStatement
+                      { letLexpr = "l:output"
+                      , letValue = "system(&grepprg . ' ' . a:command)"
+                      }
+                  , GenericStatement "call s:finalize_search(l:output, a:ack)"
                   ]
               }
           ]
