From 3aefdbd21a18d5b83e42eaf4dc722b0c5918f6f2 Mon Sep 17 00:00:00 2001
From: Amir Salihefendic <amix@doist.com>
Date: Thu, 22 Aug 2019 17:36:17 +0200
Subject: [PATCH] Updated plugins

---
 sources_non_forked/ale/LICENSE                |    2 +-
 .../ale/ale_linters/asm/gcc.vim               |    5 +-
 .../ale/ale_linters/c/clangd.vim              |    8 +-
 .../ale/ale_linters/c/clangtidy.vim           |    9 +-
 .../ale/ale_linters/c/cppcheck.vim            |   22 +-
 .../ale/ale_linters/c/cquery.vim              |   10 +-
 sources_non_forked/ale/ale_linters/c/gcc.vim  |    6 +-
 .../ale/ale_linters/cpp/clangcheck.vim        |    3 +-
 .../ale/ale_linters/cpp/clangd.vim            |    8 +-
 .../ale/ale_linters/cpp/clangtidy.vim         |    9 +-
 .../ale/ale_linters/cpp/cppcheck.vim          |   22 +-
 .../ale/ale_linters/cpp/cquery.vim            |   10 +-
 .../ale/ale_linters/cpp/gcc.vim               |    6 +-
 sources_non_forked/ale/ale_linters/cs/csc.vim |   95 +
 .../ale/ale_linters/cs/mcsc.vim               |   34 +-
 .../ale/ale_linters/elm/elm_ls.vim            |   37 +
 .../ale/ale_linters/elm/elm_lsp.vim           |   22 -
 .../ale/ale_linters/erlang/dialyzer.vim       |   93 +
 .../ale/ale_linters/go/bingo.vim              |    6 +-
 .../ale/ale_linters/go/gobuild.vim            |    1 +
 .../ale/ale_linters/go/gofmt.vim              |    8 +-
 .../ale/ale_linters/go/golangci_lint.vim      |    3 +
 .../ale/ale_linters/go/golint.vim             |    2 +-
 .../ale/ale_linters/go/gometalinter.vim       |    2 +
 .../ale/ale_linters/go/gopls.vim              |    8 +-
 .../ale/ale_linters/go/gosimple.vim           |    3 +-
 .../ale/ale_linters/go/gotype.vim             |    3 +-
 .../ale/ale_linters/go/govet.vim              |    1 +
 .../ale/ale_linters/go/langserver.vim         |    3 +-
 .../ale/ale_linters/go/staticcheck.vim        |    5 +-
 .../ale/ale_linters/java/checkstyle.vim       |   35 +-
 .../ale/ale_linters/java/eclipselsp.vim       |   30 +-
 .../ale/ale_linters/java/javac.vim            |    5 +
 .../ale/ale_linters/java/javalsp.vim          |   36 +-
 .../ale/ale_linters/javascript/eslint.vim     |    2 +-
 .../ale/ale_linters/javascript/xo.vim         |    4 +-
 .../ale/ale_linters/objc/clangd.vim           |    8 +-
 .../ale/ale_linters/objcpp/clangd.vim         |    8 +-
 .../ale/ale_linters/php/phpcs.vim             |   11 +-
 .../ale/ale_linters/powershell/powershell.vim |   22 +-
 .../ale/ale_linters/pug/puglint.vim           |   16 +-
 .../ale/ale_linters/purescript/ls.vim         |   49 +
 .../ale/ale_linters/python/mypy.vim           |    1 +
 .../ale/ale_linters/reason/ls.vim             |   23 +
 .../ale/ale_linters/ruby/sorbet.vim           |   23 +
 .../ale/ale_linters/rust/cargo.vim            |   19 +-
 .../ale/ale_linters/terraform/terraform.vim   |   49 +
 .../ale/ale_linters/tex/texlab.vim            |   21 +
 .../ale/ale_linters/typescript/eslint.vim     |    2 +-
 .../ale/ale_linters/typescript/xo.vim         |    4 +-
 sources_non_forked/ale/autoload/ale.vim       |    2 +-
 sources_non_forked/ale/autoload/ale/ant.vim   |   41 +
 .../ale/autoload/ale/assert.vim               |   12 +
 sources_non_forked/ale/autoload/ale/c.vim     |  220 +-
 .../ale/autoload/ale/completion.vim           |  109 +-
 .../ale/autoload/ale/debugging.vim            |   13 +-
 .../ale/autoload/ale/engine.vim               |    4 +
 .../ale/autoload/ale/events.vim               |    2 +-
 sources_non_forked/ale/autoload/ale/fix.vim   |   61 +-
 .../ale/autoload/ale/fix/registry.vim         |   32 +-
 .../ale/autoload/ale/fixers/black.vim         |    4 +
 .../ale/autoload/ale/fixers/clangformat.vim   |   13 +-
 .../ale/autoload/ale/fixers/clangtidy.vim     |   52 +
 .../ale/autoload/ale/fixers/eslint.vim        |   18 +-
 .../ale/autoload/ale/fixers/gnatpp.vim        |   17 +
 .../ale/autoload/ale/fixers/gofmt.vim         |    3 +-
 .../ale/autoload/ale/fixers/goimports.vim     |    3 +-
 .../ale/autoload/ale/fixers/gomod.vim         |    3 +-
 .../ale/autoload/ale/fixers/hindent.vim       |   20 +
 .../ale/autoload/ale/fixers/pgformatter.vim   |   12 +
 .../ale/autoload/ale/fixers/prettier.vim      |   10 +-
 .../ale/fixers/reorder_python_imports.vim     |   25 +
 .../ale/autoload/ale/fixers/sorbet.vim        |   19 +
 sources_non_forked/ale/autoload/ale/go.vim    |   17 +
 .../ale/autoload/ale/handlers/ccls.vim        |   14 +-
 .../ale/autoload/ale/handlers/cppcheck.vim    |   41 +
 .../ale/autoload/ale/handlers/eslint.vim      |  143 +-
 .../ale/autoload/ale/handlers/gcc.vim         |   24 +
 .../ale/autoload/ale/handlers/rust.vim        |   10 +-
 .../ale/autoload/ale/highlight.vim            |  126 +-
 sources_non_forked/ale/autoload/ale/java.vim  |    6 +
 .../ale/autoload/ale/linter.vim               |    9 +-
 sources_non_forked/ale/autoload/ale/list.vim  |   84 +-
 .../ale/autoload/ale/loclist_jumping.vim      |    2 +-
 sources_non_forked/ale/autoload/ale/lsp.vim   |   93 +-
 .../ale/autoload/ale/lsp/message.vim          |    7 +-
 .../ale/autoload/ale/lsp/response.vim         |    2 +-
 .../ale/autoload/ale/lsp_linter.vim           |   55 +-
 sources_non_forked/ale/autoload/ale/path.vim  |   11 +-
 .../ale/autoload/ale/python.vim               |    2 +-
 sources_non_forked/ale/autoload/ale/sign.vim  |   28 +
 .../ale/autoload/asyncomplete/sources/ale.vim |   26 +
 sources_non_forked/ale/doc/ale-ada.txt        |   11 +
 sources_non_forked/ale/doc/ale-c.txt          |   19 +-
 sources_non_forked/ale/doc/ale-cpp.txt        |   19 +-
 sources_non_forked/ale/doc/ale-cs.txt         |   90 +-
 .../ale/doc/ale-development.txt               |    5 +-
 sources_non_forked/ale/doc/ale-elm.txt        |   38 +-
 sources_non_forked/ale/doc/ale-erlang.txt     |   29 +
 sources_non_forked/ale/doc/ale-go.txt         |   10 +
 sources_non_forked/ale/doc/ale-handlebars.txt |    7 +
 sources_non_forked/ale/doc/ale-haskell.txt    |   22 +
 sources_non_forked/ale/doc/ale-hcl.txt        |    2 +-
 sources_non_forked/ale/doc/ale-java.txt       |   96 +-
 sources_non_forked/ale/doc/ale-purescript.txt |   33 +
 sources_non_forked/ale/doc/ale-python.txt     |   32 +-
 sources_non_forked/ale/doc/ale-reasonml.txt   |   38 +-
 sources_non_forked/ale/doc/ale-ruby.txt       |   20 +
 sources_non_forked/ale/doc/ale-sql.txt        |   18 +
 .../doc/ale-supported-languages-and-tools.txt |   10 +
 sources_non_forked/ale/doc/ale-terraform.txt  |   14 +-
 sources_non_forked/ale/doc/ale-tex.txt        |   20 +
 sources_non_forked/ale/doc/ale.txt            |  138 +-
 sources_non_forked/ale/plugin/ale.vim         |   11 +-
 .../rplugin/python3/deoplete/sources/ale.py   |   16 +-
 sources_non_forked/ale/supported-tools.md     |   16 +-
 sources_non_forked/goyo.vim/autoload/goyo.vim |    2 +-
 sources_non_forked/lightline.vim/.travis.yml  |    4 +-
 sources_non_forked/lightline.vim/README.md    |    6 +
 .../lightline.vim/autoload/lightline.vim      |   10 +-
 .../lightline/colorscheme/ayu_mirage.vim      |   39 +
 .../lightline/colorscheme/powerlineish.vim    |   28 +
 .../lightline/colorscheme/selenized_dark.vim  |   50 +
 .../lightline.vim/doc/lightline.txt           |   19 +-
 .../lightline.vim/plugin/lightline.vim        |   12 +-
 .../lightline.vim/test/.themisrc              |    2 +
 .../lightline.vim/test/popup.vim              |   19 +
 .../lightline.vim/test/quickfix.vim           |   25 +
 .../nerdtree/.github/ISSUE_TEMPLATE.md        |   28 -
 .../nerdtree/.github/ISSUE_TEMPLATE/bug.md    |   45 +
 .../.github/ISSUE_TEMPLATE/feature_request.md |    8 +
 .../.github/ISSUE_TEMPLATE/question.md        |   24 +
 .../nerdtree/.github/PULL_REQUEST_TEMPLATE.md |   13 +
 sources_non_forked/nerdtree/CHANGELOG         |  179 -
 sources_non_forked/nerdtree/CHANGELOG.md      |  222 ++
 .../nerdtree/autoload/nerdtree.vim            |   41 +-
 .../nerdtree/autoload/nerdtree/ui_glue.vim    |   48 +-
 sources_non_forked/nerdtree/doc/NERDTree.txt  |  151 +-
 .../nerdtree/lib/nerdtree/bookmark.vim        |    4 +-
 .../nerdtree/lib/nerdtree/creator.vim         |   11 +-
 .../nerdtree/lib/nerdtree/menu_controller.vim |    8 +-
 .../nerdtree/lib/nerdtree/nerdtree.vim        |   16 +-
 .../nerdtree/lib/nerdtree/opener.vim          |   30 +-
 .../nerdtree/lib/nerdtree/path.vim            |   30 +-
 .../nerdtree/lib/nerdtree/tree_dir_node.vim   |    5 +
 .../nerdtree/lib/nerdtree/ui.vim              |   16 +-
 .../nerdtree/nerdtree_plugin/fs_menu.vim      |   32 +-
 .../nerdtree/plugin/NERD_tree.vim             |    1 +
 sources_non_forked/nginx.vim/README.md        |   40 +-
 .../nginx.vim/snippets/nginx.snippets         |  166 -
 .../vim-bundle-mako/indent/mako.vim           |   85 +-
 .../vim-fugitive/autoload/fugitive.vim        | 3356 +++++++++++------
 .../vim-fugitive/doc/fugitive.txt             |  340 +-
 .../vim-fugitive/plugin/fugitive.vim          |  121 +-
 .../vim-fugitive/syntax/fugitive.vim          |   31 +-
 .../vim-fugitive/syntax/fugitiveblame.vim     |    7 +
 .../vim-gitgutter/.github/issue_template.md   |    4 -
 sources_non_forked/vim-gitgutter/README.mkd   |   95 +-
 .../vim-gitgutter/autoload/gitgutter.vim      |   53 +-
 .../vim-gitgutter/autoload/gitgutter/diff.vim |   12 +-
 .../autoload/gitgutter/highlight.vim          |  103 +-
 .../vim-gitgutter/autoload/gitgutter/hunk.vim |   98 +-
 .../vim-gitgutter/autoload/gitgutter/sign.vim |  170 +-
 .../autoload/gitgutter/utility.vim            |   90 +-
 .../vim-gitgutter/doc/gitgutter.txt           |   97 +-
 .../vim-gitgutter/plugin/gitgutter.vim        |   31 +-
 sources_non_forked/vim-gitgutter/test/test    |    2 +-
 .../vim-gitgutter/test/test_gitgutter.vim     |  365 +-
 sources_non_forked/vim-go/.github/FUNDING.yml |    1 +
 .../vim-go/.github/ISSUE_TEMPLATE.md          |    7 +-
 sources_non_forked/vim-go/CHANGELOG.md        |   89 +
 sources_non_forked/vim-go/README.md           |   11 +-
 .../vim-go/autoload/go/auto.vim               |   12 +-
 sources_non_forked/vim-go/autoload/go/cmd.vim |    4 +-
 .../vim-go/autoload/go/complete.vim           |   29 +-
 .../vim-go/autoload/go/complete_test.vim      |   28 +-
 .../vim-go/autoload/go/config.vim             |   21 +-
 .../vim-go/autoload/go/debug.vim              |   23 +-
 .../vim-go/autoload/go/debug_test.vim         |   12 +
 sources_non_forked/vim-go/autoload/go/def.vim |    4 +-
 .../vim-go/autoload/go/def_test.vim           |  197 +-
 sources_non_forked/vim-go/autoload/go/doc.vim |   12 +
 .../vim-go/autoload/go/issue.vim              |   16 +-
 .../vim-go/autoload/go/lint.vim               |   34 +-
 .../vim-go/autoload/go/lint_test.vim          |  129 +-
 sources_non_forked/vim-go/autoload/go/lsp.vim |  486 ++-
 .../autoload/go/lsp/completionitemkind.vim    |   18 +-
 .../vim-go/autoload/go/lsp/lsp.vim            |   58 +
 .../vim-go/autoload/go/lsp/lsp_test.vim       |   32 +
 .../vim-go/autoload/go/lsp/message.vim        |   80 +-
 .../vim-go/autoload/go/lsp_test.vim           |   49 +
 sources_non_forked/vim-go/autoload/go/mod.vim |    8 +-
 .../vim-go/autoload/go/package.vim            |   76 +-
 .../vim-go/autoload/go/promise.vim            |   50 +
 .../vim-go/autoload/go/promise_test.vim       |   41 +
 .../vim-go/autoload/go/statusline.vim         |   16 +-
 .../vim-go/autoload/go/template.vim           |    9 +-
 .../vim-go/autoload/go/term.vim               |   28 +-
 .../vim-go/autoload/go/term_test.vim          |    2 +
 .../test/src/example/example_test.go          |   10 +
 .../vim-go/autoload/go/test.vim               |   13 +-
 .../vim-go/autoload/go/test_test.vim          |   15 +-
 .../vim-go/autoload/go/tool.vim               |   10 +-
 .../vim-go/autoload/go/util.vim               |   16 +-
 sources_non_forked/vim-go/autoload/gotest.vim |   21 +-
 sources_non_forked/vim-go/doc/vim-go.txt      |  113 +-
 .../vim-go/ftplugin/go/commands.vim           |    7 +
 .../vim-go/gosnippets/UltiSnips/go.snippets   |    4 +-
 sources_non_forked/vim-go/plugin/go.vim       |  102 +-
 sources_non_forked/vim-go/scripts/install-vim |    4 +-
 sources_non_forked/vim-go/scripts/runtest.vim |   10 +-
 sources_non_forked/vim-markdown/Makefile      |    6 +
 sources_non_forked/vim-markdown/README.md     |  303 +-
 .../vim-markdown/after/ftplugin/markdown.vim  |   53 +-
 .../vim-markdown/doc/vim-markdown.txt         |  269 +-
 .../vim-markdown/syntax/markdown.vim          |    4 +-
 .../vim-markdown/test/python-folding.vader    |   15 +-
 .../vim-markdown/test/toc.vader               |    4 -
 .../vim-multiple-cursors/README.md            |   28 +-
 .../doc/multiple_cursors.txt                  |   14 +-
 .../plugin/multiple_cursors.vim               |    4 +-
 .../spec/multiple_cursors_spec.rb             |    4 +-
 sources_non_forked/vim-repeat/README.markdown |    1 +
 .../vim-snippets/UltiSnips/html.snippets      |    4 +
 .../UltiSnips/javascript-node.snippets        |    2 +-
 .../vim-snippets/UltiSnips/lua.snippets       |    2 +-
 .../vim-snippets/UltiSnips/python.snippets    |    8 +-
 .../vim-snippets/UltiSnips/r.snippets         |    3 +-
 .../vim-snippets/UltiSnips/ruby.snippets      |    2 +-
 .../vim-snippets/UltiSnips/sh.snippets        |    8 +-
 .../vim-snippets/UltiSnips/tex.snippets       |    2 +-
 .../vim-snippets/UltiSnips/zsh.snippets       |    9 +-
 .../vim-snippets/snippets/cpp.snippets        |    4 +
 .../vim-snippets/snippets/css.snippets        |  223 +-
 .../vim-snippets/snippets/eelixir.snippets    |   34 +-
 .../vim-snippets/snippets/go.snippets         |    6 -
 .../javascript/javascript-react.snippets      |   17 +-
 .../javascript/javascript-redux.snippets      |   37 +
 .../javascript/javascript.es6.snippets        |   55 -
 .../snippets/javascript/javascript.snippets   |   65 +-
 .../vim-snippets/snippets/sass.snippets       |  228 ++
 .../vim-snippets/snippets/stylus.snippets     |  230 +-
 .../vim-snippets/snippets/tex.snippets        |    2 +-
 .../vim-surround/plugin/surround.vim          |   11 +-
 244 files changed, 9486 insertions(+), 3395 deletions(-)
 create mode 100644 sources_non_forked/ale/ale_linters/cs/csc.vim
 create mode 100644 sources_non_forked/ale/ale_linters/elm/elm_ls.vim
 delete mode 100644 sources_non_forked/ale/ale_linters/elm/elm_lsp.vim
 create mode 100644 sources_non_forked/ale/ale_linters/erlang/dialyzer.vim
 create mode 100644 sources_non_forked/ale/ale_linters/purescript/ls.vim
 create mode 100644 sources_non_forked/ale/ale_linters/reason/ls.vim
 create mode 100644 sources_non_forked/ale/ale_linters/ruby/sorbet.vim
 create mode 100644 sources_non_forked/ale/ale_linters/terraform/terraform.vim
 create mode 100644 sources_non_forked/ale/ale_linters/tex/texlab.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/ant.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/hindent.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim
 create mode 100644 sources_non_forked/ale/autoload/ale/fixers/sorbet.vim
 create mode 100644 sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim
 create mode 100644 sources_non_forked/ale/doc/ale-purescript.txt
 create mode 100644 sources_non_forked/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim
 create mode 100644 sources_non_forked/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim
 create mode 100644 sources_non_forked/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim
 create mode 100644 sources_non_forked/lightline.vim/test/popup.vim
 create mode 100644 sources_non_forked/lightline.vim/test/quickfix.vim
 delete mode 100644 sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE.md
 create mode 100644 sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/bug.md
 create mode 100644 sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md
 create mode 100644 sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/question.md
 create mode 100644 sources_non_forked/nerdtree/.github/PULL_REQUEST_TEMPLATE.md
 delete mode 100644 sources_non_forked/nerdtree/CHANGELOG
 create mode 100644 sources_non_forked/nerdtree/CHANGELOG.md
 delete mode 100644 sources_non_forked/nginx.vim/snippets/nginx.snippets
 create mode 100644 sources_non_forked/vim-fugitive/syntax/fugitiveblame.vim
 create mode 100644 sources_non_forked/vim-go/.github/FUNDING.yml
 create mode 100644 sources_non_forked/vim-go/autoload/go/lsp/lsp.vim
 create mode 100644 sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim
 create mode 100644 sources_non_forked/vim-go/autoload/go/lsp_test.vim
 create mode 100644 sources_non_forked/vim-go/autoload/go/promise.vim
 create mode 100644 sources_non_forked/vim-go/autoload/go/promise_test.vim
 create mode 100644 sources_non_forked/vim-go/autoload/go/test-fixtures/test/src/example/example_test.go
 create mode 100644 sources_non_forked/vim-snippets/snippets/javascript/javascript-redux.snippets
 delete mode 100644 sources_non_forked/vim-snippets/snippets/javascript/javascript.es6.snippets

diff --git a/sources_non_forked/ale/LICENSE b/sources_non_forked/ale/LICENSE
index 739ccae0..f8f3524d 100644
--- a/sources_non_forked/ale/LICENSE
+++ b/sources_non_forked/ale/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2018, w0rp <devw0rp@gmail.com>
+Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/sources_non_forked/ale/ale_linters/asm/gcc.vim b/sources_non_forked/ale/ale_linters/asm/gcc.vim
index 72b293c0..eecab6ef 100644
--- a/sources_non_forked/ale/ale_linters/asm/gcc.vim
+++ b/sources_non_forked/ale/ale_linters/asm/gcc.vim
@@ -5,7 +5,10 @@ call ale#Set('asm_gcc_executable', 'gcc')
 call ale#Set('asm_gcc_options', '-Wall')
 
 function! ale_linters#asm#gcc#GetCommand(buffer) abort
-    return '%e -x assembler -fsyntax-only '
+    " `-o /dev/null` or `-o null` is needed to catch all errors,
+    " -fsyntax-only doesn't catch everything.
+    return '%e -x assembler'
+    \   . ' -o ' . g:ale#util#nul_file
     \   . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
     \   . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
 endfunction
diff --git a/sources_non_forked/ale/ale_linters/c/clangd.vim b/sources_non_forked/ale/ale_linters/c/clangd.vim
index 918eadcc..79b600fa 100644
--- a/sources_non_forked/ale/ale_linters/c/clangd.vim
+++ b/sources_non_forked/ale/ale_linters/c/clangd.vim
@@ -4,12 +4,6 @@
 call ale#Set('c_clangd_executable', 'clangd')
 call ale#Set('c_clangd_options', '')
 
-function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
-endfunction
-
 function! ale_linters#c#clangd#GetCommand(buffer) abort
     return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
 endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('c', {
 \   'lsp': 'stdio',
 \   'executable': {b -> ale#Var(b, 'c_clangd_executable')},
 \   'command': function('ale_linters#c#clangd#GetCommand'),
-\   'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
+\   'project_root': function('ale#c#FindProjectRoot'),
 \})
diff --git a/sources_non_forked/ale/ale_linters/c/clangtidy.vim b/sources_non_forked/ale/ale_linters/c/clangtidy.vim
index 6484f8af..f998866a 100644
--- a/sources_non_forked/ale/ale_linters/c/clangtidy.vim
+++ b/sources_non_forked/ale/ale_linters/c/clangtidy.vim
@@ -11,9 +11,12 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
 " http://clang.llvm.org/extra/clang-tidy/checks/list.html
 
 call ale#Set('c_clangtidy_checks', [])
-" Set this option to manually set some options for clang-tidy.
+" Set this option to manually set some options for clang-tidy to use as compile
+" flags.
 " This will disable compile_commands.json detection.
 call ale#Set('c_clangtidy_options', '')
+" Set this option to manually set options for clang-tidy directly.
+call ale#Set('c_clangtidy_extra_options', '')
 call ale#Set('c_build_dir', '')
 
 function! ale_linters#c#clangtidy#GetCommand(buffer) abort
@@ -25,8 +28,12 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort
     \   ? ale#Var(a:buffer, 'c_clangtidy_options')
     \   : ''
 
+    " Get the options to pass directly to clang-tidy
+    let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
+
     return '%e'
     \   . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
+    \   . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
     \   . ' %s'
     \   . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
     \   . (!empty(l:options) ? ' -- ' . l:options : '')
diff --git a/sources_non_forked/ale/ale_linters/c/cppcheck.vim b/sources_non_forked/ale/ale_linters/c/cppcheck.vim
index 851f9f11..309b2851 100644
--- a/sources_non_forked/ale/ale_linters/c/cppcheck.vim
+++ b/sources_non_forked/ale/ale_linters/c/cppcheck.vim
@@ -5,23 +5,17 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
 call ale#Set('c_cppcheck_options', '--enable=style')
 
 function! ale_linters#c#cppcheck#GetCommand(buffer) abort
-    " Search upwards from the file for compile_commands.json.
-    "
-    " If we find it, we'll `cd` to where the compile_commands.json file is,
-    " then use the file to set up import paths, etc.
-    let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    let l:cd_command = !empty(l:compile_commmands_path)
-    \   ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
-    \   : ''
-    let l:compile_commands_option = !empty(l:compile_commmands_path)
-    \   ? '--project=compile_commands.json '
+    let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
+    let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
+    let l:buffer_path_include = empty(l:compile_commands_option)
+    \   ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
     \   : ''
 
     return l:cd_command
-    \   . '%e -q --language=c '
-    \   . l:compile_commands_option
-    \   . ale#Var(a:buffer, 'c_cppcheck_options')
+    \   . '%e -q --language=c'
+    \   . ale#Pad(l:compile_commands_option)
+    \   . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
+    \   . l:buffer_path_include
     \   . ' %t'
 endfunction
 
diff --git a/sources_non_forked/ale/ale_linters/c/cquery.vim b/sources_non_forked/ale/ale_linters/c/cquery.vim
index d2be9cd9..ff0f34af 100644
--- a/sources_non_forked/ale/ale_linters/c/cquery.vim
+++ b/sources_non_forked/ale/ale_linters/c/cquery.vim
@@ -5,13 +5,15 @@ call ale#Set('c_cquery_executable', 'cquery')
 call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
 
 function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
+    " Try to find cquery configuration files first.
+    let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
 
-    if empty(l:project_root)
-        let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
     endif
 
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
+    " Fall back on default project root detection.
+    return ale#c#FindProjectRoot(a:buffer)
 endfunction
 
 function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort
diff --git a/sources_non_forked/ale/ale_linters/c/gcc.vim b/sources_non_forked/ale/ale_linters/c/gcc.vim
index d965965d..1df1018e 100644
--- a/sources_non_forked/ale/ale_linters/c/gcc.vim
+++ b/sources_non_forked/ale/ale_linters/c/gcc.vim
@@ -9,7 +9,11 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort
 
     " -iquote with the directory the file is in makes #include work for
     "  headers in the same directory.
-    return '%e -S -x c -fsyntax-only'
+    "
+    " `-o /dev/null` or `-o null` is needed to catch all errors,
+    " -fsyntax-only doesn't catch everything.
+    return '%e -S -x c'
+    \   . ' -o ' . g:ale#util#nul_file
     \   . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
     \   . ale#Pad(l:cflags)
     \   . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
diff --git a/sources_non_forked/ale/ale_linters/cpp/clangcheck.vim b/sources_non_forked/ale/ale_linters/cpp/clangcheck.vim
index b511a413..7d32a57c 100644
--- a/sources_non_forked/ale/ale_linters/cpp/clangcheck.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/clangcheck.vim
@@ -12,7 +12,8 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
     let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
 
     if empty(l:build_dir)
-        let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
+        let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
+        let l:build_dir = ale#path#Dirname(l:json_file)
     endif
 
     " The extra arguments in the command are used to prevent .plist files from
diff --git a/sources_non_forked/ale/ale_linters/cpp/clangd.vim b/sources_non_forked/ale/ale_linters/cpp/clangd.vim
index 4a8ff4f6..fab605f4 100644
--- a/sources_non_forked/ale/ale_linters/cpp/clangd.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/clangd.vim
@@ -4,12 +4,6 @@
 call ale#Set('cpp_clangd_executable', 'clangd')
 call ale#Set('cpp_clangd_options', '')
 
-function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
-endfunction
-
 function! ale_linters#cpp#clangd#GetCommand(buffer) abort
     return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
 endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('cpp', {
 \   'lsp': 'stdio',
 \   'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
 \   'command': function('ale_linters#cpp#clangd#GetCommand'),
-\   'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
+\   'project_root': function('ale#c#FindProjectRoot'),
 \})
diff --git a/sources_non_forked/ale/ale_linters/cpp/clangtidy.vim b/sources_non_forked/ale/ale_linters/cpp/clangtidy.vim
index 841b795f..085bc332 100644
--- a/sources_non_forked/ale/ale_linters/cpp/clangtidy.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/clangtidy.vim
@@ -5,9 +5,12 @@
 call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
 " Set this option to check the checks clang-tidy will apply.
 call ale#Set('cpp_clangtidy_checks', [])
-" Set this option to manually set some options for clang-tidy.
+" Set this option to manually set some options for clang-tidy to use as compile
+" flags.
 " This will disable compile_commands.json detection.
 call ale#Set('cpp_clangtidy_options', '')
+" Set this option to manually set options for clang-tidy directly.
+call ale#Set('cpp_clangtidy_extra_options', '')
 call ale#Set('c_build_dir', '')
 
 function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
@@ -19,8 +22,12 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
     \   ? ale#Var(a:buffer, 'cpp_clangtidy_options')
     \   : ''
 
+    " Get the options to pass directly to clang-tidy
+    let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
+
     return '%e'
     \   . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
+    \   . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
     \   . ' %s'
     \   . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
     \   . (!empty(l:options) ? ' -- ' . l:options : '')
diff --git a/sources_non_forked/ale/ale_linters/cpp/cppcheck.vim b/sources_non_forked/ale/ale_linters/cpp/cppcheck.vim
index 5173d698..7cd80dbc 100644
--- a/sources_non_forked/ale/ale_linters/cpp/cppcheck.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/cppcheck.vim
@@ -5,23 +5,17 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
 call ale#Set('cpp_cppcheck_options', '--enable=style')
 
 function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
-    " Search upwards from the file for compile_commands.json.
-    "
-    " If we find it, we'll `cd` to where the compile_commands.json file is,
-    " then use the file to set up import paths, etc.
-    let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    let l:cd_command = !empty(l:compile_commmands_path)
-    \   ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
-    \   : ''
-    let l:compile_commands_option = !empty(l:compile_commmands_path)
-    \   ? '--project=compile_commands.json '
+    let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
+    let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
+    let l:buffer_path_include = empty(l:compile_commands_option)
+    \   ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
     \   : ''
 
     return l:cd_command
-    \   . '%e -q --language=c++ '
-    \   . l:compile_commands_option
-    \   . ale#Var(a:buffer, 'cpp_cppcheck_options')
+    \   . '%e -q --language=c++'
+    \   . ale#Pad(l:compile_commands_option)
+    \   . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
+    \   . l:buffer_path_include
     \   . ' %t'
 endfunction
 
diff --git a/sources_non_forked/ale/ale_linters/cpp/cquery.vim b/sources_non_forked/ale/ale_linters/cpp/cquery.vim
index 0dd9f6ad..2971cdcb 100644
--- a/sources_non_forked/ale/ale_linters/cpp/cquery.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/cquery.vim
@@ -5,13 +5,15 @@ call ale#Set('cpp_cquery_executable', 'cquery')
 call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
 
 function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
+    " Try to find cquery configuration files first.
+    let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
 
-    if empty(l:project_root)
-        let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
     endif
 
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
+    " Fall back on default project root detection.
+    return ale#c#FindProjectRoot(a:buffer)
 endfunction
 
 function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort
diff --git a/sources_non_forked/ale/ale_linters/cpp/gcc.vim b/sources_non_forked/ale/ale_linters/cpp/gcc.vim
index c427020b..108d6d70 100644
--- a/sources_non_forked/ale/ale_linters/cpp/gcc.vim
+++ b/sources_non_forked/ale/ale_linters/cpp/gcc.vim
@@ -9,7 +9,11 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
 
     " -iquote with the directory the file is in makes #include work for
     "  headers in the same directory.
-    return '%e -S -x c++ -fsyntax-only'
+    "
+    " `-o /dev/null` or `-o null` is needed to catch all errors,
+    " -fsyntax-only doesn't catch everything.
+    return '%e -S -x c++'
+    \   . ' -o ' . g:ale#util#nul_file
     \   . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
     \   . ale#Pad(l:cflags)
     \   . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
diff --git a/sources_non_forked/ale/ale_linters/cs/csc.vim b/sources_non_forked/ale/ale_linters/cs/csc.vim
new file mode 100644
index 00000000..308abc77
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/cs/csc.vim
@@ -0,0 +1,95 @@
+call ale#Set('cs_csc_options', '')
+call ale#Set('cs_csc_source', '')
+call ale#Set('cs_csc_assembly_path', [])
+call ale#Set('cs_csc_assemblies', [])
+
+function! s:GetWorkingDirectory(buffer) abort
+    let l:working_directory = ale#Var(a:buffer, 'cs_csc_source')
+
+    if !empty(l:working_directory)
+        return l:working_directory
+    endif
+
+    return expand('#' . a:buffer . ':p:h')
+endfunction
+
+function! ale_linters#cs#csc#GetCommand(buffer) abort
+    " Pass assembly paths via the -lib: parameter.
+    let l:path_list = ale#Var(a:buffer, 'cs_csc_assembly_path')
+
+    let l:lib_option = !empty(l:path_list)
+    \   ? '/lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',')
+    \   : ''
+
+    " Pass paths to DLL files via the -r: parameter.
+    let l:assembly_list = ale#Var(a:buffer, 'cs_csc_assemblies')
+
+    let l:r_option = !empty(l:assembly_list)
+    \   ? '/r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',')
+    \   : ''
+
+    " register temporary module target file with ale
+    " register temporary module target file with ALE.
+    let l:out = ale#command#CreateFile(a:buffer)
+
+    " The code is compiled as a module and the output is redirected to a
+    " temporary file.
+    return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
+    \    . 'csc /unsafe'
+    \    . ale#Pad(ale#Var(a:buffer, 'cs_csc_options'))
+    \    . ale#Pad(l:lib_option)
+    \    . ale#Pad(l:r_option)
+    \    . ' /out:' . l:out
+    \    . ' /t:module'
+    \    . ' /recurse:' . ale#Escape('*.cs')
+endfunction
+
+function! ale_linters#cs#csc#Handle(buffer, lines) abort
+    " Look for lines like the following.
+    "
+    " Tests.cs(12,29): error CSXXXX: ; expected
+    "
+    " NOTE: pattern also captures file name as linter compiles all
+    " files within the source tree rooted at the specified source
+    " path and not just the file loaded in the buffer
+    let l:patterns = [
+    \    '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
+    \    '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
+    \]
+    let l:output = []
+
+    let l:dir = s:GetWorkingDirectory(a:buffer)
+
+    for l:match in ale#util#GetMatches(a:lines, l:patterns)
+        if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
+            call add(l:output, {
+            \   'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
+            \   'lnum': l:match[2] + 0,
+            \   'col': l:match[3] + 0,
+            \   'type': l:match[4] is# 'error' ? 'E' : 'W',
+            \   'code': l:match[5],
+            \   'text': l:match[6] ,
+            \})
+        elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
+            call add(l:output, {
+            \   'filename':'<csc>',
+            \   'lnum': -1,
+            \   'col': -1,
+            \   'type': l:match[1] is# 'error' ? 'E' : 'W',
+            \   'code': l:match[2],
+            \   'text': l:match[3],
+            \})
+        endif
+    endfor
+
+    return l:output
+endfunction
+
+call ale#linter#Define('cs',{
+\   'name': 'csc',
+\   'output_stream': 'stdout',
+\   'executable': 'csc',
+\   'command': function('ale_linters#cs#csc#GetCommand'),
+\   'callback': 'ale_linters#cs#csc#Handle',
+\   'lint_file': 1
+\})
diff --git a/sources_non_forked/ale/ale_linters/cs/mcsc.vim b/sources_non_forked/ale/ale_linters/cs/mcsc.vim
index dd067eba..0e4e5667 100644
--- a/sources_non_forked/ale/ale_linters/cs/mcsc.vim
+++ b/sources_non_forked/ale/ale_linters/cs/mcsc.vim
@@ -52,20 +52,34 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
     " NOTE: pattern also captures file name as linter compiles all
     " files within the source tree rooted at the specified source
     " path and not just the file loaded in the buffer
-    let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
+    let l:patterns = [
+    \    '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
+    \    '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
+    \]
     let l:output = []
 
     let l:dir = s:GetWorkingDirectory(a:buffer)
 
-    for l:match in ale#util#GetMatches(a:lines, l:pattern)
-        call add(l:output, {
-        \   'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
-        \   'lnum': l:match[2] + 0,
-        \   'col': l:match[3] + 0,
-        \   'type': l:match[4] is# 'error' ? 'E' : 'W',
-        \   'code': l:match[5],
-        \   'text': l:match[6],
-        \})
+    for l:match in ale#util#GetMatches(a:lines, l:patterns)
+        if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
+            call add(l:output, {
+            \   'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
+            \   'lnum': l:match[2] + 0,
+            \   'col': l:match[3] + 0,
+            \   'type': l:match[4] is# 'error' ? 'E' : 'W',
+            \   'code': l:match[5],
+            \   'text': l:match[6] ,
+            \})
+        elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
+            call add(l:output, {
+            \   'filename':'<mcs>',
+            \   'lnum': -1,
+            \   'col': -1,
+            \   'type': l:match[1] is# 'error' ? 'E' : 'W',
+            \   'code': l:match[2],
+            \   'text': l:match[3],
+            \})
+        endif
     endfor
 
     return l:output
diff --git a/sources_non_forked/ale/ale_linters/elm/elm_ls.vim b/sources_non_forked/ale/ale_linters/elm/elm_ls.vim
new file mode 100644
index 00000000..374ef8de
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/elm/elm_ls.vim
@@ -0,0 +1,37 @@
+" Author: antew - https://github.com/antew
+" Description: elm-language-server integration for elm (diagnostics, formatting, and more)
+
+call ale#Set('elm_ls_executable', 'elm-language-server')
+call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1))
+call ale#Set('elm_ls_elm_path', 'elm')
+call ale#Set('elm_ls_elm_format_path', 'elm-format')
+call ale#Set('elm_ls_elm_test_path', 'elm-test')
+
+function! elm_ls#GetRootDir(buffer) abort
+    let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
+
+    return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
+endfunction
+
+function! elm_ls#GetOptions(buffer) abort
+    return {
+    \   'runtime': 'node',
+    \   'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
+    \   'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
+    \   'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
+    \}
+endfunction
+
+call ale#linter#Define('elm', {
+\   'name': 'elm_ls',
+\   'lsp': 'stdio',
+\   'executable': {b -> ale#node#FindExecutable(b, 'elm_ls', [
+\       'node_modules/.bin/elm-language-server',
+\       'node_modules/.bin/elm-lsp',
+\       'elm-lsp'
+\   ])},
+\   'command': '%e --stdio',
+\   'project_root': function('elm_ls#GetRootDir'),
+\   'language': 'elm',
+\   'initialization_options': function('elm_ls#GetOptions')
+\})
diff --git a/sources_non_forked/ale/ale_linters/elm/elm_lsp.vim b/sources_non_forked/ale/ale_linters/elm/elm_lsp.vim
deleted file mode 100644
index 2259286f..00000000
--- a/sources_non_forked/ale/ale_linters/elm/elm_lsp.vim
+++ /dev/null
@@ -1,22 +0,0 @@
-" Author: antew - https://github.com/antew
-" Description: LSP integration for elm, currently supports diagnostics (linting)
-
-call ale#Set('elm_lsp_executable', 'elm-lsp')
-call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0))
-
-function! elm_lsp#GetRootDir(buffer) abort
-    let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
-
-    return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
-endfunction
-
-call ale#linter#Define('elm', {
-\   'name': 'elm_lsp',
-\   'lsp': 'stdio',
-\   'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [
-\       'node_modules/.bin/elm-lsp',
-\   ])},
-\   'command': '%e --stdio',
-\   'project_root': function('elm_lsp#GetRootDir'),
-\   'language': 'elm'
-\})
diff --git a/sources_non_forked/ale/ale_linters/erlang/dialyzer.vim b/sources_non_forked/ale/ale_linters/erlang/dialyzer.vim
new file mode 100644
index 00000000..7af64c4f
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/erlang/dialyzer.vim
@@ -0,0 +1,93 @@
+" Author: Autoine Gagne - https://github.com/AntoineGagne
+" Description: Define a checker that runs dialyzer on Erlang files.
+
+let g:ale_erlang_dialyzer_executable =
+\   get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer')
+let g:ale_erlang_dialyzer_plt_file =
+\   get(g:, 'ale_erlang_dialyzer_plt_file', '')
+let g:ale_erlang_dialyzer_rebar3_profile =
+\   get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default')
+
+function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort
+    return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile')
+endfunction
+
+function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
+    let l:plt_file = ''
+    let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
+    let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
+
+    if !empty(l:plt_file_directory)
+        let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
+    endif
+
+    if !empty(l:plt_file)
+        return l:plt_file[0]
+    endif
+
+    if !empty($REBAR_PLT_DIR)
+        return expand('$REBAR_PLT_DIR/dialyzer/plt')
+    endif
+
+    return expand('$HOME/.dialyzer_plt')
+endfunction
+
+function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort
+    let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file')
+
+    if !empty(l:plt_file)
+        return l:plt_file
+    endif
+
+    return ale_linters#erlang#dialyzer#FindPlt(a:buffer)
+endfunction
+
+function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort
+    return ale#Var(a:buffer, 'erlang_dialyzer_executable')
+endfunction
+
+function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort
+    let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer))
+    \   . ' -n'
+    \   . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer))
+    \   . ' -Wunmatched_returns'
+    \   . ' -Werror_handling'
+    \   . ' -Wrace_conditions'
+    \   . ' -Wunderspecs'
+    \   . ' %s'
+
+    return l:command
+endfunction
+
+function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort
+    " Match patterns like the following:
+    "
+    " erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available
+    let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$'
+    let l:output = []
+
+    for l:line in a:lines
+        let l:match = matchlist(l:line, l:pattern)
+
+        if len(l:match) != 0
+            let l:code = l:match[2]
+
+            call add(l:output, {
+            \   'lnum': str2nr(l:match[1]),
+            \   'lcol': 0,
+            \   'text': l:code,
+            \   'type': 'W'
+            \})
+        endif
+    endfor
+
+    return l:output
+endfunction
+
+call ale#linter#Define('erlang', {
+\   'name': 'dialyzer',
+\   'executable': function('ale_linters#erlang#dialyzer#GetExecutable'),
+\   'command': function('ale_linters#erlang#dialyzer#GetCommand'),
+\   'callback': function('ale_linters#erlang#dialyzer#Handle'),
+\   'lint_file': 1
+\})
diff --git a/sources_non_forked/ale/ale_linters/go/bingo.vim b/sources_non_forked/ale/ale_linters/go/bingo.vim
index e446bdcc..1e43f8e4 100644
--- a/sources_non_forked/ale/ale_linters/go/bingo.vim
+++ b/sources_non_forked/ale/ale_linters/go/bingo.vim
@@ -5,11 +5,13 @@ call ale#Set('go_bingo_executable', 'bingo')
 call ale#Set('go_bingo_options', '--mode stdio')
 
 function! ale_linters#go#bingo#GetCommand(buffer) abort
-    return '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
+    return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
 endfunction
 
 function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
+    let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
+    let l:project_root = l:go_modules_off ?
+    \ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
     let l:mods = ':h'
 
     if empty(l:project_root)
diff --git a/sources_non_forked/ale/ale_linters/go/gobuild.vim b/sources_non_forked/ale/ale_linters/go/gobuild.vim
index 374ded35..1dfb6daa 100644
--- a/sources_non_forked/ale/ale_linters/go/gobuild.vim
+++ b/sources_non_forked/ale/ale_linters/go/gobuild.vim
@@ -11,6 +11,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort
 
     " Run go test in local directory with relative path
     return ale#path#BufferCdString(a:buffer)
+    \   . ale#go#EnvString(a:buffer)
     \   . ale#Var(a:buffer, 'go_go_executable') . ' test'
     \   . (!empty(l:options) ? ' ' . l:options : '')
     \   . ' -c -o /dev/null ./'
diff --git a/sources_non_forked/ale/ale_linters/go/gofmt.vim b/sources_non_forked/ale/ale_linters/go/gofmt.vim
index 337deef8..a233b422 100644
--- a/sources_non_forked/ale/ale_linters/go/gofmt.vim
+++ b/sources_non_forked/ale/ale_linters/go/gofmt.vim
@@ -1,10 +1,16 @@
 " Author: neersighted <bjorn@neersighted.com>
 " Description: gofmt for Go files
 
+function! ale_linters#go#gofmt#GetCommand(buffer) abort
+    return ale#go#EnvString(a:buffer)
+    \   . '%e -e %t'
+endfunction
+
+
 call ale#linter#Define('go', {
 \   'name': 'gofmt',
 \   'output_stream': 'stderr',
 \   'executable': 'gofmt',
-\   'command': 'gofmt -e %t',
+\   'command': function('ale_linters#go#gofmt#GetCommand'),
 \   'callback': 'ale#handlers#unix#HandleAsError',
 \})
diff --git a/sources_non_forked/ale/ale_linters/go/golangci_lint.vim b/sources_non_forked/ale/ale_linters/go/golangci_lint.vim
index 357f7949..dd0e975a 100644
--- a/sources_non_forked/ale/ale_linters/go/golangci_lint.vim
+++ b/sources_non_forked/ale/ale_linters/go/golangci_lint.vim
@@ -10,13 +10,16 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
     let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
     let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
 
+
     if l:lint_package
         return ale#path#BufferCdString(a:buffer)
+        \   . ale#go#EnvString(a:buffer)
         \   . '%e run '
         \   .  l:options
     endif
 
     return ale#path#BufferCdString(a:buffer)
+    \   . ale#go#EnvString(a:buffer)
     \   . '%e run '
     \   . ale#Escape(l:filename)
     \   . ' ' . l:options
diff --git a/sources_non_forked/ale/ale_linters/go/golint.vim b/sources_non_forked/ale/ale_linters/go/golint.vim
index 765e1477..79bfaeb5 100644
--- a/sources_non_forked/ale/ale_linters/go/golint.vim
+++ b/sources_non_forked/ale/ale_linters/go/golint.vim
@@ -7,7 +7,7 @@ call ale#Set('go_golint_options', '')
 function! ale_linters#go#golint#GetCommand(buffer) abort
     let l:options = ale#Var(a:buffer, 'go_golint_options')
 
-    return '%e'
+    return ale#go#EnvString(a:buffer) . '%e'
     \   . (!empty(l:options) ? ' ' . l:options : '')
     \   . ' %t'
 endfunction
diff --git a/sources_non_forked/ale/ale_linters/go/gometalinter.vim b/sources_non_forked/ale/ale_linters/go/gometalinter.vim
index 19d70a81..eed9550a 100644
--- a/sources_non_forked/ale/ale_linters/go/gometalinter.vim
+++ b/sources_non_forked/ale/ale_linters/go/gometalinter.vim
@@ -14,11 +14,13 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort
     " be calculated to absolute paths in the Handler
     if l:lint_package
         return ale#path#BufferCdString(a:buffer)
+        \   . ale#go#EnvString(a:buffer)
         \   . '%e'
         \   . (!empty(l:options) ? ' ' . l:options : '') . ' .'
     endif
 
     return ale#path#BufferCdString(a:buffer)
+    \   . ale#go#EnvString(a:buffer)
     \   . '%e'
     \   . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
     \   . (!empty(l:options) ? ' ' . l:options : '') . ' .'
diff --git a/sources_non_forked/ale/ale_linters/go/gopls.vim b/sources_non_forked/ale/ale_linters/go/gopls.vim
index c411dc2b..dcff5ec7 100644
--- a/sources_non_forked/ale/ale_linters/go/gopls.vim
+++ b/sources_non_forked/ale/ale_linters/go/gopls.vim
@@ -6,11 +6,15 @@ call ale#Set('go_gopls_executable', 'gopls')
 call ale#Set('go_gopls_options', '--mode stdio')
 
 function! ale_linters#go#gopls#GetCommand(buffer) abort
-    return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
+    return ale#go#EnvString(a:buffer)
+    \   . '%e'
+    \   . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
 endfunction
 
 function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
+    let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
+    let l:project_root = l:go_modules_off ?
+    \ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
     let l:mods = ':h'
 
     if empty(l:project_root)
diff --git a/sources_non_forked/ale/ale_linters/go/gosimple.vim b/sources_non_forked/ale/ale_linters/go/gosimple.vim
index 281a0e53..ad52c621 100644
--- a/sources_non_forked/ale/ale_linters/go/gosimple.vim
+++ b/sources_non_forked/ale/ale_linters/go/gosimple.vim
@@ -2,7 +2,8 @@
 " Description: gosimple for Go files
 
 function! ale_linters#go#gosimple#GetCommand(buffer) abort
-    return ale#path#BufferCdString(a:buffer) . ' gosimple .'
+    return ale#path#BufferCdString(a:buffer) . ' '
+    \   . ale#go#EnvString(a:buffer) . 'gosimple .'
 endfunction
 
 call ale#linter#Define('go', {
diff --git a/sources_non_forked/ale/ale_linters/go/gotype.vim b/sources_non_forked/ale/ale_linters/go/gotype.vim
index d5d563aa..6a5149ca 100644
--- a/sources_non_forked/ale/ale_linters/go/gotype.vim
+++ b/sources_non_forked/ale/ale_linters/go/gotype.vim
@@ -6,7 +6,8 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
         return ''
     endif
 
-    return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
+    return ale#path#BufferCdString(a:buffer) . ' '
+    \   . ale#go#EnvString(a:buffer) . 'gotype -e .'
 endfunction
 
 call ale#linter#Define('go', {
diff --git a/sources_non_forked/ale/ale_linters/go/govet.vim b/sources_non_forked/ale/ale_linters/go/govet.vim
index bb81d5d0..dddafe17 100644
--- a/sources_non_forked/ale/ale_linters/go/govet.vim
+++ b/sources_non_forked/ale/ale_linters/go/govet.vim
@@ -11,6 +11,7 @@ function! ale_linters#go#govet#GetCommand(buffer) abort
     let l:options = ale#Var(a:buffer, 'go_govet_options')
 
     return ale#path#BufferCdString(a:buffer) . ' '
+    \   . ale#go#EnvString(a:buffer)
     \   . ale#Var(a:buffer, 'go_go_executable') . ' vet '
     \   . (!empty(l:options) ? ' ' . l:options : '')
     \   . ' .'
diff --git a/sources_non_forked/ale/ale_linters/go/langserver.vim b/sources_non_forked/ale/ale_linters/go/langserver.vim
index 776186c7..7130db40 100644
--- a/sources_non_forked/ale/ale_linters/go/langserver.vim
+++ b/sources_non_forked/ale/ale_linters/go/langserver.vim
@@ -15,8 +15,9 @@ function! ale_linters#go#langserver#GetCommand(buffer) abort
     endif
 
     let l:options = uniq(sort(l:options))
+    let l:env = ale#go#EnvString(a:buffer)
 
-    return join(extend(l:executable, l:options), ' ')
+    return l:env . join(extend(l:executable, l:options), ' ')
 endfunction
 
 call ale#linter#Define('go', {
diff --git a/sources_non_forked/ale/ale_linters/go/staticcheck.vim b/sources_non_forked/ale/ale_linters/go/staticcheck.vim
index 26fe0193..ed40c6c2 100644
--- a/sources_non_forked/ale/ale_linters/go/staticcheck.vim
+++ b/sources_non_forked/ale/ale_linters/go/staticcheck.vim
@@ -8,17 +8,18 @@ function! ale_linters#go#staticcheck#GetCommand(buffer) abort
     let l:filename = expand('#' . a:buffer . ':t')
     let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
     let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
+    let l:env = ale#go#EnvString(a:buffer)
 
     " BufferCdString is used so that we can be sure the paths output from
     " staticcheck can be calculated to absolute paths in the Handler
     if l:lint_package
         return ale#path#BufferCdString(a:buffer)
-        \   . 'staticcheck'
+        \   . l:env . 'staticcheck'
         \   . (!empty(l:options) ? ' ' . l:options : '') . ' .'
     endif
 
     return ale#path#BufferCdString(a:buffer)
-    \   . 'staticcheck'
+    \   . l:env . 'staticcheck'
     \   . (!empty(l:options) ? ' ' . l:options : '')
     \   . ' ' . ale#Escape(l:filename)
 endfunction
diff --git a/sources_non_forked/ale/ale_linters/java/checkstyle.vim b/sources_non_forked/ale/ale_linters/java/checkstyle.vim
index 3159cd55..7901ff7e 100644
--- a/sources_non_forked/ale/ale_linters/java/checkstyle.vim
+++ b/sources_non_forked/ale/ale_linters/java/checkstyle.vim
@@ -1,6 +1,10 @@
 " Author: Devon Meunier <devon.meunier@gmail.com>
 " Description: checkstyle for Java files
 
+call ale#Set('java_checkstyle_executable', 'checkstyle')
+call ale#Set('java_checkstyle_config', '/google_checks.xml')
+call ale#Set('java_checkstyle_options', '')
+
 function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
     let l:output = []
 
@@ -17,6 +21,10 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
         \})
     endfor
 
+    if !empty(l:output)
+        return l:output
+    endif
+
     " old checkstyle versions
     let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
 
@@ -31,19 +39,32 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
     return l:output
 endfunction
 
+function! s:GetConfig(buffer, config) abort
+    if ale#path#IsAbsolute(a:config)
+        return a:config
+    endif
+
+    let s:file = ale#path#FindNearestFile(a:buffer, a:config)
+
+    return !empty(s:file) ? s:file : a:config
+endfunction
+
 function! ale_linters#java#checkstyle#GetCommand(buffer) abort
-    return 'checkstyle '
-    \ . ale#Var(a:buffer, 'java_checkstyle_options')
+    let l:options = ale#Var(a:buffer, 'java_checkstyle_options')
+    let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config')
+    let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
+    \   ? s:GetConfig(a:buffer, l:config_option)
+    \   : ''
+
+    return '%e'
+    \ . ale#Pad(l:options)
+    \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
     \ . ' %s'
 endfunction
 
-if !exists('g:ale_java_checkstyle_options')
-    let g:ale_java_checkstyle_options = '-c /google_checks.xml'
-endif
-
 call ale#linter#Define('java', {
 \   'name': 'checkstyle',
-\   'executable': 'checkstyle',
+\   'executable': {b -> ale#Var(b, 'java_checkstyle_executable')},
 \   'command': function('ale_linters#java#checkstyle#GetCommand'),
 \   'callback': 'ale_linters#java#checkstyle#Handle',
 \   'lint_file': 1,
diff --git a/sources_non_forked/ale/ale_linters/java/eclipselsp.vim b/sources_non_forked/ale/ale_linters/java/eclipselsp.vim
index d0ea9d6c..2648893b 100644
--- a/sources_non_forked/ale/ale_linters/java/eclipselsp.vim
+++ b/sources_non_forked/ale/ale_linters/java/eclipselsp.vim
@@ -4,6 +4,8 @@
 let s:version_cache = {}
 
 call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
+call ale#Set('java_eclipselsp_config_path', '')
+call ale#Set('java_eclipselsp_workspace_path', '')
 call ale#Set('java_eclipselsp_executable', 'java')
 
 function! ale_linters#java#eclipselsp#Executable(buffer) abort
@@ -32,11 +34,23 @@ function! ale_linters#java#eclipselsp#JarPath(buffer) abort
         return l:files[0]
     endif
 
+    " Search jar file within system package path
+    let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
+
+    if len(l:files) == 1
+        return l:files[0]
+    endif
+
     return ''
 endfunction
 
 function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
     let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
+    let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path')
+
+    if !empty(l:config_path)
+        return ale#path#Simplify(l:config_path)
+    endif
 
     if has('win32')
         let l:path = l:path . '/config_win'
@@ -76,6 +90,16 @@ function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines,
     return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
 endfunction
 
+function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
+    let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path')
+
+    if !empty(l:wspath)
+        return l:wspath
+    endif
+
+    return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
+endfunction
+
 function! ale_linters#java#eclipselsp#Command(buffer, version) abort
     let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
 
@@ -89,11 +113,11 @@ function! ale_linters#java#eclipselsp#Command(buffer, version) abort
     \ '-noverify',
     \ '-Xmx1G',
     \ '-jar',
-    \ ale_linters#java#eclipselsp#JarPath(a:buffer),
+    \ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)),
     \ '-configuration',
-    \ ale_linters#java#eclipselsp#ConfigurationPath(a:buffer),
+    \ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)),
     \ '-data',
-    \ ale#java#FindProjectRoot(a:buffer)
+    \ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer))
     \ ]
 
     if ale#semver#GTE(a:version, [1, 9])
diff --git a/sources_non_forked/ale/ale_linters/java/javac.vim b/sources_non_forked/ale/ale_linters/java/javac.vim
index 3883783b..8bb52c0b 100644
--- a/sources_non_forked/ale/ale_linters/java/javac.vim
+++ b/sources_non_forked/ale/ale_linters/java/javac.vim
@@ -21,6 +21,11 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
         let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
     endif
 
+    " Try to use Ant if Gradle and Maven aren't available
+    if empty(l:command)
+        let l:command = ale#ant#BuildClasspathCommand(a:buffer)
+    endif
+
     if empty(l:command)
         return ale_linters#java#javac#GetCommand(a:buffer, [], {})
     endif
diff --git a/sources_non_forked/ale/ale_linters/java/javalsp.vim b/sources_non_forked/ale/ale_linters/java/javalsp.vim
index a327363d..baf584c8 100644
--- a/sources_non_forked/ale/ale_linters/java/javalsp.vim
+++ b/sources_non_forked/ale/ale_linters/java/javalsp.vim
@@ -1,16 +1,47 @@
 " Author: Horacio Sanson <https://github.com/hsanson>
 " Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
 
-call ale#Set('java_javalsp_executable', 'java')
+call ale#Set('java_javalsp_executable', '')
+call ale#Set('java_javalsp_config', {})
 
 function! ale_linters#java#javalsp#Executable(buffer) abort
     return ale#Var(a:buffer, 'java_javalsp_executable')
 endfunction
 
+function! ale_linters#java#javalsp#Config(buffer) abort
+    let l:defaults = { 'java': { 'classPath': [], 'externalDependencies': [] } }
+    let l:config = ale#Var(a:buffer, 'java_javalsp_config')
+
+    " Ensure the config dictionary contains both classPath and
+    " externalDependencies keys to avoid a NPE crash on Java Language Server.
+    call extend(l:config, l:defaults, 'keep')
+    call extend(l:config['java'], l:defaults['java'], 'keep')
+
+    return l:config
+endfunction
+
 function! ale_linters#java#javalsp#Command(buffer) abort
     let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
 
-    return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main'
+    if fnamemodify(l:executable, ':t') is# 'java'
+        " For backward compatibility.
+        let l:cmd = [
+        \ ale#Escape(l:executable),
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs',
+        \ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs',
+        \ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs',
+        \ '-m javacs/org.javacs.Main',
+        \]
+
+        return join(l:cmd, ' ')
+    else
+        return ale#Escape(l:executable)
+    endif
 endfunction
 
 call ale#linter#Define('java', {
@@ -20,4 +51,5 @@ call ale#linter#Define('java', {
 \   'command': function('ale_linters#java#javalsp#Command'),
 \   'language': 'java',
 \   'project_root': function('ale#java#FindProjectRoot'),
+\   'lsp_config': function('ale_linters#java#javalsp#Config')
 \})
diff --git a/sources_non_forked/ale/ale_linters/javascript/eslint.vim b/sources_non_forked/ale/ale_linters/javascript/eslint.vim
index 8aeac2d8..31fb413f 100644
--- a/sources_non_forked/ale/ale_linters/javascript/eslint.vim
+++ b/sources_non_forked/ale/ale_linters/javascript/eslint.vim
@@ -6,5 +6,5 @@ call ale#linter#Define('javascript', {
 \   'output_stream': 'both',
 \   'executable': function('ale#handlers#eslint#GetExecutable'),
 \   'command': function('ale#handlers#eslint#GetCommand'),
-\   'callback': 'ale#handlers#eslint#Handle',
+\   'callback': 'ale#handlers#eslint#HandleJSON',
 \})
diff --git a/sources_non_forked/ale/ale_linters/javascript/xo.vim b/sources_non_forked/ale/ale_linters/javascript/xo.vim
index 4ba39101..e24f4a82 100644
--- a/sources_non_forked/ale/ale_linters/javascript/xo.vim
+++ b/sources_non_forked/ale/ale_linters/javascript/xo.vim
@@ -14,7 +14,7 @@ endfunction
 function! ale_linters#javascript#xo#GetCommand(buffer) abort
     return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
     \   . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
-    \   . ' --reporter unix --stdin --stdin-filename %s'
+    \   . ' --reporter json --stdin --stdin-filename %s'
 endfunction
 
 " xo uses eslint and the output format is the same
@@ -22,5 +22,5 @@ call ale#linter#Define('javascript', {
 \   'name': 'xo',
 \   'executable': function('ale_linters#javascript#xo#GetExecutable'),
 \   'command': function('ale_linters#javascript#xo#GetCommand'),
-\   'callback': 'ale#handlers#eslint#Handle',
+\   'callback': 'ale#handlers#eslint#HandleJSON',
 \})
diff --git a/sources_non_forked/ale/ale_linters/objc/clangd.vim b/sources_non_forked/ale/ale_linters/objc/clangd.vim
index ab52fec3..318d85b5 100644
--- a/sources_non_forked/ale/ale_linters/objc/clangd.vim
+++ b/sources_non_forked/ale/ale_linters/objc/clangd.vim
@@ -4,12 +4,6 @@
 call ale#Set('objc_clangd_executable', 'clangd')
 call ale#Set('objc_clangd_options', '')
 
-function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
-endfunction
-
 function! ale_linters#objc#clangd#GetCommand(buffer) abort
     return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
 endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('objc', {
 \   'lsp': 'stdio',
 \   'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
 \   'command': function('ale_linters#objc#clangd#GetCommand'),
-\   'project_root': function('ale_linters#objc#clangd#GetProjectRoot'),
+\   'project_root': function('ale#c#FindProjectRoot'),
 \})
diff --git a/sources_non_forked/ale/ale_linters/objcpp/clangd.vim b/sources_non_forked/ale/ale_linters/objcpp/clangd.vim
index 3991d2ac..29455325 100644
--- a/sources_non_forked/ale/ale_linters/objcpp/clangd.vim
+++ b/sources_non_forked/ale/ale_linters/objcpp/clangd.vim
@@ -4,12 +4,6 @@
 call ale#Set('objcpp_clangd_executable', 'clangd')
 call ale#Set('objcpp_clangd_options', '')
 
-function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
-
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
-endfunction
-
 function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
     return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
 endfunction
@@ -19,5 +13,5 @@ call ale#linter#Define('objcpp', {
 \   'lsp': 'stdio',
 \   'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
 \   'command': function('ale_linters#objcpp#clangd#GetCommand'),
-\   'project_root': function('ale_linters#objcpp#clangd#GetProjectRoot'),
+\   'project_root': function('ale#c#FindProjectRoot'),
 \})
diff --git a/sources_non_forked/ale/ale_linters/php/phpcs.vim b/sources_non_forked/ale/ale_linters/php/phpcs.vim
index 1c92bbb2..11b81e84 100644
--- a/sources_non_forked/ale/ale_linters/php/phpcs.vim
+++ b/sources_non_forked/ale/ale_linters/php/phpcs.vim
@@ -10,13 +10,13 @@ call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
 function! ale_linters#php#phpcs#GetCommand(buffer) abort
     let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
     let l:standard_option = !empty(l:standard)
-    \   ? '--standard=' . l:standard
+    \   ? '--standard=' . ale#Escape(l:standard)
     \   : ''
-    let l:options = ale#Var(a:buffer, 'php_phpcs_options')
 
-    return '%e -s --report=emacs --stdin-path=%s'
-    \    . ale#Pad(l:standard_option)
-    \    . ale#Pad(l:options)
+    return ale#path#BufferCdString(a:buffer)
+    \   . '%e -s --report=emacs --stdin-path=%s'
+    \   . ale#Pad(l:standard_option)
+    \   . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
 endfunction
 
 function! ale_linters#php#phpcs#Handle(buffer, lines) abort
@@ -36,6 +36,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
         \   'col': l:match[2] + 0,
         \   'text': l:text,
         \   'type': l:type is# 'error' ? 'E' : 'W',
+        \   'sub_type': 'style',
         \})
     endfor
 
diff --git a/sources_non_forked/ale/ale_linters/powershell/powershell.vim b/sources_non_forked/ale/ale_linters/powershell/powershell.vim
index 51ded71d..a63191fd 100644
--- a/sources_non_forked/ale/ale_linters/powershell/powershell.vim
+++ b/sources_non_forked/ale/ale_linters/powershell/powershell.vim
@@ -49,11 +49,19 @@ function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
                 let l:matchcount = 1
             endif
 
-            let l:item = {
-            \   'lnum': str2nr(l:match[1]),
-            \   'col': str2nr(l:match[2]),
-            \   'type': 'E',
-            \}
+            " If the match is 0, it was a failed match
+            " probably due to an unexpected token which
+            " contained a newline. Reset matchcount. to
+            " continue to the next match
+            if !empty(l:match[1])
+                let l:item = {
+                \   'lnum': str2nr(l:match[1]),
+                \   'col': str2nr(l:match[2]),
+                \   'type': 'E',
+                \}
+            else
+                let l:matchcount = 0
+            endif
         elseif l:matchcount == 2
             " Second match[0] grabs the full line in order
             " to handles the text
@@ -84,8 +92,8 @@ endfunction
 
 call ale#linter#Define('powershell', {
 \   'name': 'powershell',
-\   'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
-\   'command_callback': 'ale_linters#powershell#powershell#GetCommand',
+\   'executable': function('ale_linters#powershell#powershell#GetExecutable'),
+\   'command': function('ale_linters#powershell#powershell#GetCommand'),
 \   'output_stream': 'stdout',
 \   'callback': 'ale_linters#powershell#powershell#Handle',
 \})
diff --git a/sources_non_forked/ale/ale_linters/pug/puglint.vim b/sources_non_forked/ale/ale_linters/pug/puglint.vim
index c4e0e233..c819cc45 100644
--- a/sources_non_forked/ale/ale_linters/pug/puglint.vim
+++ b/sources_non_forked/ale/ale_linters/pug/puglint.vim
@@ -31,6 +31,20 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
     \   . ' -r inline %t'
 endfunction
 
+function! ale_linters#pug#puglint#Handle(buffer, lines) abort
+    for l:line in a:lines[:10]
+        if l:line =~# '^SyntaxError: '
+            return [{
+            \   'lnum': 1,
+            \   'text': 'puglint configuration error (type :ALEDetail for more information)',
+            \   'detail': join(a:lines, "\n"),
+            \}]
+        endif
+    endfor
+
+    return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
+endfunction
+
 call ale#linter#Define('pug', {
 \   'name': 'puglint',
 \   'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
@@ -38,5 +52,5 @@ call ale#linter#Define('pug', {
 \   ])},
 \   'output_stream': 'stderr',
 \   'command': function('ale_linters#pug#puglint#GetCommand'),
-\   'callback': 'ale#handlers#unix#HandleAsError',
+\   'callback': 'ale_linters#pug#puglint#Handle',
 \})
diff --git a/sources_non_forked/ale/ale_linters/purescript/ls.vim b/sources_non_forked/ale/ale_linters/purescript/ls.vim
new file mode 100644
index 00000000..1c5f937f
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/purescript/ls.vim
@@ -0,0 +1,49 @@
+" Author: Drew Olson <drew@drewolson.org>
+" Description: Integrate ALE with purescript-language-server.
+
+call ale#Set('purescript_ls_executable', 'purescript-language-server')
+call ale#Set('purescript_ls_use_global', get(g:, 'ale_use_global_executables', 0))
+call ale#Set('purescript_ls_config', {})
+
+function! ale_linters#purescript#ls#GetExecutable(buffer) abort
+    return ale#node#FindExecutable(a:buffer, 'purescript_ls', [
+    \   'node_modules/.bin/purescript-language-server',
+    \])
+endfunction
+
+function! ale_linters#purescript#ls#GetCommand(buffer) abort
+    let l:executable = ale_linters#purescript#ls#GetExecutable(a:buffer)
+
+    return ale#Escape(l:executable) . ' --stdio'
+endfunction
+
+function! ale_linters#purescript#ls#FindProjectRoot(buffer) abort
+    let l:config = ale#path#FindNearestFile(a:buffer, 'bower.json')
+
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
+    endif
+
+    let l:config = ale#path#FindNearestFile(a:buffer, 'psc-package.json')
+
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
+    endif
+
+    let l:config = ale#path#FindNearestFile(a:buffer, 'spago.dhall')
+
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
+    endif
+
+    return ''
+endfunction
+
+call ale#linter#Define('purescript', {
+\   'name': 'purescript-language-server',
+\   'lsp': 'stdio',
+\   'executable': function('ale_linters#purescript#ls#GetExecutable'),
+\   'command': function('ale_linters#purescript#ls#GetCommand'),
+\   'project_root': function('ale_linters#purescript#ls#FindProjectRoot'),
+\   'lsp_config': {b -> ale#Var(b, 'purescript_ls_config')},
+\})
diff --git a/sources_non_forked/ale/ale_linters/python/mypy.vim b/sources_non_forked/ale/ale_linters/python/mypy.vim
index c4c6507f..dc4044e6 100644
--- a/sources_non_forked/ale/ale_linters/python/mypy.vim
+++ b/sources_non_forked/ale/ale_linters/python/mypy.vim
@@ -78,4 +78,5 @@ call ale#linter#Define('python', {
 \   'executable': function('ale_linters#python#mypy#GetExecutable'),
 \   'command': function('ale_linters#python#mypy#GetCommand'),
 \   'callback': 'ale_linters#python#mypy#Handle',
+\   'output_stream': 'both'
 \})
diff --git a/sources_non_forked/ale/ale_linters/reason/ls.vim b/sources_non_forked/ale/ale_linters/reason/ls.vim
new file mode 100644
index 00000000..fb1114ae
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/reason/ls.vim
@@ -0,0 +1,23 @@
+" Author: David Buchan-Swanson <github@deecewan.com>
+" Description: Integrate ALE with reason-language-server.
+
+call ale#Set('reason_ls_executable', '')
+
+function! ale_linters#reason#ls#FindProjectRoot(buffer) abort
+    let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json')
+
+    if !empty(l:reason_config)
+        return fnamemodify(l:reason_config, ':h')
+    endif
+
+    return ''
+endfunction
+
+call ale#linter#Define('reason', {
+\   'name': 'reason-language-server',
+\   'lsp': 'stdio',
+\   'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
+\   'command': '%e',
+\   'project_root': function('ale_linters#reason#ls#FindProjectRoot'),
+\   'language': 'reason',
+\})
diff --git a/sources_non_forked/ale/ale_linters/ruby/sorbet.vim b/sources_non_forked/ale/ale_linters/ruby/sorbet.vim
new file mode 100644
index 00000000..ee765a6e
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/ruby/sorbet.vim
@@ -0,0 +1,23 @@
+call ale#Set('ruby_sorbet_executable', 'srb')
+call ale#Set('ruby_sorbet_options', '')
+
+function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
+    let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
+    let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
+
+    return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
+    \   . ' tc'
+    \   . (!empty(l:options) ? ' ' . l:options : '')
+    \   . ' --lsp --disable-watchman'
+endfunction
+
+call ale#linter#Define('ruby', {
+\   'name': 'sorbet',
+\   'aliases': ['srb'],
+\   'lsp': 'stdio',
+\   'language': 'ruby',
+\   'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')},
+\   'command': function('ale_linters#ruby#sorbet#GetCommand'),
+\   'project_root': function('ale#ruby#FindProjectRoot')
+\})
+
diff --git a/sources_non_forked/ale/ale_linters/rust/cargo.vim b/sources_non_forked/ale/ale_linters/rust/cargo.vim
index f98dee9b..99178585 100644
--- a/sources_non_forked/ale/ale_linters/rust/cargo.vim
+++ b/sources_non_forked/ale/ale_linters/rust/cargo.vim
@@ -25,14 +25,11 @@ endfunction
 function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
     let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
     \   && ale#semver#GTE(a:version, [0, 17, 0])
-    let l:use_all_targets = l:use_check
-    \   && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
+    let l:use_all_targets = ale#Var(a:buffer, 'rust_cargo_check_all_targets')
     \   && ale#semver#GTE(a:version, [0, 22, 0])
-    let l:use_examples = l:use_check
-    \   && ale#Var(a:buffer, 'rust_cargo_check_examples')
+    let l:use_examples = ale#Var(a:buffer, 'rust_cargo_check_examples')
     \   && ale#semver#GTE(a:version, [0, 22, 0])
-    let l:use_tests = l:use_check
-    \   && ale#Var(a:buffer, 'rust_cargo_check_tests')
+    let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests')
     \   && ale#semver#GTE(a:version, [0, 22, 0])
 
     let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
@@ -69,7 +66,15 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
 
     if ale#Var(a:buffer, 'rust_cargo_use_clippy')
         let l:subcommand = 'clippy'
-        let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
+        let l:clippy_options = ale#Var(a:buffer, 'rust_cargo_clippy_options')
+
+        if l:clippy_options =~# '^-- '
+            let l:clippy_options = join(split(l:clippy_options, '-- '))
+        endif
+
+        if l:clippy_options isnot# ''
+            let l:clippy_options = ' -- ' . l:clippy_options
+        endif
     endif
 
     return l:nearest_cargo_prefix . 'cargo '
diff --git a/sources_non_forked/ale/ale_linters/terraform/terraform.vim b/sources_non_forked/ale/ale_linters/terraform/terraform.vim
new file mode 100644
index 00000000..0429cb7a
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/terraform/terraform.vim
@@ -0,0 +1,49 @@
+" Author: Keith Maxwell <keith.maxwell@gmail.com>
+" Description: terraform fmt to check for errors
+
+call ale#Set('terraform_terraform_executable', 'terraform')
+
+function! ale_linters#terraform#terraform#GetExecutable(buffer) abort
+    return ale#Var(a:buffer, 'terraform_terraform_executable')
+endfunction
+
+function! ale_linters#terraform#terraform#GetCommand(buffer) abort
+    return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer))
+    \   . ' fmt -no-color --check=true -'
+endfunction
+
+function! ale_linters#terraform#terraform#Handle(buffer, lines) abort
+    let l:head = '^Error running fmt: In <standard input>: '
+    let l:output = []
+    let l:patterns = [
+    \   l:head.'At \(\d\+\):\(\d\+\): \(.*\)$',
+    \   l:head.'\(.*\)$'
+    \]
+
+    for l:match in ale#util#GetMatches(a:lines, l:patterns)
+        if len(l:match[2]) > 0
+            call add(l:output, {
+            \   'lnum': str2nr(l:match[1]),
+            \   'col': str2nr(l:match[2]),
+            \   'text': l:match[3],
+            \   'type': 'E',
+            \})
+        else
+            call add(l:output, {
+            \   'lnum': line('$'),
+            \   'text': l:match[1],
+            \   'type': 'E',
+            \})
+        endif
+    endfor
+
+    return l:output
+endfunction
+
+call ale#linter#Define('terraform', {
+\   'name': 'terraform',
+\   'output_stream': 'stderr',
+\   'executable': function('ale_linters#terraform#terraform#GetExecutable'),
+\   'command': function('ale_linters#terraform#terraform#GetCommand'),
+\   'callback': 'ale_linters#terraform#terraform#Handle',
+\})
diff --git a/sources_non_forked/ale/ale_linters/tex/texlab.vim b/sources_non_forked/ale/ale_linters/tex/texlab.vim
new file mode 100644
index 00000000..5ead74b4
--- /dev/null
+++ b/sources_non_forked/ale/ale_linters/tex/texlab.vim
@@ -0,0 +1,21 @@
+" Author: Ricardo Liang <ricardoliang@gmail.com>
+" Description: Texlab language server (Rust rewrite)
+
+call ale#Set('tex_texlab_executable', 'texlab')
+call ale#Set('tex_texlab_options', '')
+
+function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
+    return ''
+endfunction
+
+function! ale_linters#tex#texlab#GetCommand(buffer) abort
+    return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
+endfunction
+
+call ale#linter#Define('tex', {
+\   'name': 'texlab',
+\   'lsp': 'stdio',
+\   'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
+\   'command': function('ale_linters#tex#texlab#GetCommand'),
+\   'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
+\})
diff --git a/sources_non_forked/ale/ale_linters/typescript/eslint.vim b/sources_non_forked/ale/ale_linters/typescript/eslint.vim
index bf849337..33a21440 100644
--- a/sources_non_forked/ale/ale_linters/typescript/eslint.vim
+++ b/sources_non_forked/ale/ale_linters/typescript/eslint.vim
@@ -5,5 +5,5 @@ call ale#linter#Define('typescript', {
 \   'name': 'eslint',
 \   'executable': function('ale#handlers#eslint#GetExecutable'),
 \   'command': function('ale#handlers#eslint#GetCommand'),
-\   'callback': 'ale#handlers#eslint#Handle',
+\   'callback': 'ale#handlers#eslint#HandleJSON',
 \})
diff --git a/sources_non_forked/ale/ale_linters/typescript/xo.vim b/sources_non_forked/ale/ale_linters/typescript/xo.vim
index 8b015efd..0a3a717b 100644
--- a/sources_non_forked/ale/ale_linters/typescript/xo.vim
+++ b/sources_non_forked/ale/ale_linters/typescript/xo.vim
@@ -11,7 +11,7 @@ endfunction
 function! ale_linters#typescript#xo#GetCommand(buffer) abort
     return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
     \   . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
-    \   . ' --reporter unix --stdin --stdin-filename %s'
+    \   . ' --reporter json --stdin --stdin-filename %s'
 endfunction
 
 " xo uses eslint and the output format is the same
@@ -19,5 +19,5 @@ call ale#linter#Define('typescript', {
 \   'name': 'xo',
 \   'executable': function('ale_linters#typescript#xo#GetExecutable'),
 \   'command': function('ale_linters#typescript#xo#GetCommand'),
-\   'callback': 'ale#handlers#eslint#Handle',
+\   'callback': 'ale#handlers#eslint#HandleJSON',
 \})
diff --git a/sources_non_forked/ale/autoload/ale.vim b/sources_non_forked/ale/autoload/ale.vim
index 04329dfd..3a4e79c8 100644
--- a/sources_non_forked/ale/autoload/ale.vim
+++ b/sources_non_forked/ale/autoload/ale.vim
@@ -156,7 +156,7 @@ function! ale#Queue(delay, ...) abort
     endif
 endfunction
 
-let s:current_ale_version = [2, 4, 0]
+let s:current_ale_version = [2, 5, 0]
 
 " A function used to check for ALE features in files outside of the project.
 function! ale#Has(feature) abort
diff --git a/sources_non_forked/ale/autoload/ale/ant.vim b/sources_non_forked/ale/autoload/ale/ant.vim
new file mode 100644
index 00000000..689b444b
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/ant.vim
@@ -0,0 +1,41 @@
+" Author: Andrew Lee <andrewl@mbda.fun>.
+" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
+" Description: Functions for working with Ant projects.
+
+" Given a buffer number, find an Ant project root
+function! ale#ant#FindProjectRoot(buffer) abort
+    let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
+
+    if !empty(l:build_xml_path)
+        return fnamemodify(l:build_xml_path, ':h')
+    endif
+
+    return ''
+endfunction
+
+" Given a buffer number, find the path to the `ant` executable. Returns an empty
+" string if cannot find the executable.
+function! ale#ant#FindExecutable(buffer) abort
+    if executable('ant')
+        return 'ant'
+    endif
+
+    return ''
+endfunction
+
+" Given a buffer number, build a command to print the classpath of the root
+" project. Returns an empty string if cannot build the command.
+function! ale#ant#BuildClasspathCommand(buffer) abort
+    let l:executable = ale#ant#FindExecutable(a:buffer)
+    let l:project_root = ale#ant#FindProjectRoot(a:buffer)
+
+    if !empty(l:executable) && !empty(l:project_root)
+        return ale#path#CdString(l:project_root)
+        \   . ale#Escape(l:executable)
+        \   . ' classpath'
+        \   . ' -S'
+        \   . ' -q'
+    endif
+
+    return ''
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/assert.vim b/sources_non_forked/ale/autoload/ale/assert.vim
index ed90792d..dac5efb7 100644
--- a/sources_non_forked/ale/autoload/ale/assert.vim
+++ b/sources_non_forked/ale/autoload/ale/assert.vim
@@ -96,6 +96,13 @@ function! ale#assert#Fixer(expected_result) abort
     AssertEqual a:expected_result, l:result
 endfunction
 
+function! ale#assert#FixerNotExecuted() abort
+    let l:buffer = bufnr('')
+    let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
+
+    Assert empty(l:result), "The fixer will be executed when it shouldn't be"
+endfunction
+
 function! ale#assert#LinterNotExecuted() abort
     let l:buffer = bufnr('')
     let l:linter = s:GetLinter()
@@ -158,6 +165,7 @@ endfunction
 function! ale#assert#SetUpFixerTestCommands() abort
     command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
     command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
+    command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
 endfunction
 
 " A dummy function for making sure this module is loaded.
@@ -316,4 +324,8 @@ function! ale#assert#TearDownFixerTest() abort
     if exists(':AssertFixer')
         delcommand AssertFixer
     endif
+
+    if exists(':AssertFixerNotExecuted')
+        delcommand AssertFixerNotExecuted
+    endif
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/c.vim b/sources_non_forked/ale/autoload/ale/c.vim
index a9289e22..5540ec14 100644
--- a/sources_non_forked/ale/autoload/ale/c.vim
+++ b/sources_non_forked/ale/autoload/ale/c.vim
@@ -23,104 +23,117 @@ function! ale#c#GetBuildDirectory(buffer) abort
         return l:build_dir
     endif
 
-    return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
+    let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
+
+    return ale#path#Dirname(l:json_file)
 endfunction
 
-
-function! ale#c#FindProjectRoot(buffer) abort
-    for l:project_filename in g:__ale_c_project_filenames
-        let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
-
-        if !empty(l:full_path)
-            let l:path = fnamemodify(l:full_path, ':h')
-
-            " Correct .git path detection.
-            if fnamemodify(l:path, ':t') is# '.git'
-                let l:path = fnamemodify(l:path, ':h')
-            endif
-
-            return l:path
-        endif
-    endfor
-
-    return ''
-endfunction
-
-function! ale#c#AreSpecialCharsBalanced(option) abort
-    " Escape \"
-    let l:option_escaped = substitute(a:option, '\\"', '', 'g')
-
-    " Retain special chars only
-    let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
-    let l:special_chars = split(l:special_chars, '\zs')
-
-    " Check if they are balanced
+function! ale#c#ShellSplit(line) abort
     let l:stack = []
+    let l:args = ['']
+    let l:prev = ''
 
-    for l:char in l:special_chars
-        if l:char is# ')'
-            if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
-                return 0
-            endif
-
-            call remove(l:stack, -1)
-        elseif l:char is# '('
-            call add(l:stack, l:char)
-        else
-            if len(l:stack) > 0 && get(l:stack, -1) is# l:char
+    for l:char in split(a:line, '\zs')
+        if l:char is# ''''
+            if len(l:stack) > 0 && get(l:stack, -1) is# ''''
                 call remove(l:stack, -1)
-            else
+            elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
                 call add(l:stack, l:char)
             endif
+        elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
+            if len(l:stack) > 0 && get(l:stack, -1) is# l:char
+                call remove(l:stack, -1)
+            elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
+                call add(l:stack, l:char)
+            endif
+        elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
+            if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
+                call add(l:stack, l:char)
+            endif
+        elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
+            if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
+                call remove(l:stack, -1)
+            endif
+        elseif l:char is# ' ' && len(l:stack) == 0
+            if len(get(l:args, -1)) > 0
+                call add(l:args, '')
+            endif
+
+            continue
         endif
+
+        let l:args[-1] = get(l:args, -1) . l:char
     endfor
 
-    return len(l:stack) == 0
+    return l:args
 endfunction
 
 function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
-    let l:split_lines = split(a:cflag_line)
+    let l:cflags_list = []
+
+    let l:split_lines = ale#c#ShellSplit(a:cflag_line)
     let l:option_index = 0
 
     while l:option_index < len(l:split_lines)
-        let l:next_option_index = l:option_index + 1
-
-        " Join space-separated option
-        while l:next_option_index < len(l:split_lines)
-        \&& stridx(l:split_lines[l:next_option_index], '-') != 0
-            let l:next_option_index += 1
-        endwhile
-
-        let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ')
-        call remove(l:split_lines, l:option_index, l:next_option_index-1)
-        call insert(l:split_lines, l:option, l:option_index)
-
-        " Ignore invalid or conflicting options
-        if stridx(l:option, '-') != 0
-        \|| stridx(l:option, '-o') == 0
-        \|| stridx(l:option, '-c') == 0
-            call remove(l:split_lines, l:option_index)
-            let l:option_index = l:option_index - 1
-        " Fix relative path
-        elseif stridx(l:option, '-I') == 0
-            if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0)
-                let l:option = '-I' . a:path_prefix . s:sep . l:option[2:]
-                call remove(l:split_lines, l:option_index)
-                call insert(l:split_lines, l:option, l:option_index)
-            endif
-        endif
-
+        let l:option = l:split_lines[l:option_index]
         let l:option_index = l:option_index + 1
+
+        " Include options, that may need relative path fix
+        if stridx(l:option, '-I') == 0
+        \ || stridx(l:option, '-iquote') == 0
+        \ || stridx(l:option, '-isystem') == 0
+        \ || stridx(l:option, '-idirafter') == 0
+            if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
+                let l:arg = join(split(l:option, '\zs')[2:], '')
+                let l:option = '-I'
+            else
+                let l:arg = l:split_lines[l:option_index]
+                let l:option_index = l:option_index + 1
+            endif
+
+            " Fix relative paths if needed
+            if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
+                let l:rel_path = substitute(l:arg, '"', '', 'g')
+                let l:rel_path = substitute(l:rel_path, '''', '', 'g')
+                let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
+            endif
+
+            call add(l:cflags_list, l:option)
+            call add(l:cflags_list, l:arg)
+        " Options with arg that can be grouped with the option or separate
+        elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
+            call add(l:cflags_list, l:option)
+
+            if l:option is# '-D' || l:option is# '-B'
+                call add(l:cflags_list, l:split_lines[l:option_index])
+                let l:option_index = l:option_index + 1
+            endif
+        " Options that have an argument (always separate)
+        elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
+        \ || l:option is# '-isysroot' || l:option is# '-imultilib'
+            call add(l:cflags_list, l:option)
+            call add(l:cflags_list, l:split_lines[l:option_index])
+            let l:option_index = l:option_index + 1
+        " Options without argument
+        elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
+        \ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
+        \ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
+        \ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0)
+        \ || stridx(l:option, '-O') == 0
+        \ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
+        \ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
+        \ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
+        \ || stridx(l:option, '-m') == 0
+            call add(l:cflags_list, l:option)
+        endif
     endwhile
 
-    call uniq(l:split_lines)
-
-    return join(l:split_lines, ' ')
+    return join(l:cflags_list, ' ')
 endfunction
 
 function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
     if !g:ale_c_parse_makefile
-        return ''
+        return v:null
     endif
 
     let l:buffer_filename = expand('#' . a:buffer . ':t')
@@ -140,14 +153,17 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
     return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
 endfunction
 
-" Given a buffer number, find the build subdirectory with compile commands
-" The subdirectory is returned without the trailing /
+" Given a buffer number, find the project directory containing
+" compile_commands.json, and the path to the compile_commands.json file.
+"
+" If compile_commands.json cannot be found, two empty strings will be
+" returned.
 function! ale#c#FindCompileCommands(buffer) abort
     " Look above the current source file to find compile_commands.json
     let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
 
     if !empty(l:json_file)
-        return l:json_file
+        return [fnamemodify(l:json_file, ':h'), l:json_file]
     endif
 
     " Search in build directories if we can't find it in the project.
@@ -157,12 +173,42 @@ function! ale#c#FindCompileCommands(buffer) abort
             let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
 
             if filereadable(l:json_file)
-                return l:json_file
+                return [l:path, l:json_file]
             endif
         endfor
     endfor
 
-    return ''
+    return ['', '']
+endfunction
+
+" Find the project root for C/C++ projects.
+"
+" The location of compile_commands.json will be used to find project roots.
+"
+" If compile_commands.json cannot be found, other common configuration files
+" will be used to detect the project root.
+function! ale#c#FindProjectRoot(buffer) abort
+    let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
+
+    " Fall back on detecting the project root based on other filenames.
+    if empty(l:root)
+        for l:project_filename in g:__ale_c_project_filenames
+            let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
+
+            if !empty(l:full_path)
+                let l:path = fnamemodify(l:full_path, ':h')
+
+                " Correct .git path detection.
+                if fnamemodify(l:path, ':t') is# '.git'
+                    let l:path = fnamemodify(l:path, ':h')
+                endif
+
+                return l:path
+            endif
+        endfor
+    endif
+
+    return l:root
 endfunction
 
 " Cache compile_commands.json data in a Dictionary, so we don't need to read
@@ -194,10 +240,14 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
     let l:raw_data = []
     silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
 
+    if type(l:raw_data) isnot v:t_list
+        let l:raw_data = []
+    endif
+
     let l:file_lookup = {}
     let l:dir_lookup = {}
 
-    for l:entry in l:raw_data
+    for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
         let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
         let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
 
@@ -274,25 +324,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
 endfunction
 
 function! ale#c#GetCFlags(buffer, output) abort
-    let l:cflags = ' '
+    let l:cflags = v:null
 
     if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
         let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
     endif
 
     if ale#Var(a:buffer, 'c_parse_compile_commands')
-        let l:json_file = ale#c#FindCompileCommands(a:buffer)
+        let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
 
         if !empty(l:json_file)
             let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
         endif
     endif
 
-    if l:cflags is# ' '
+    if l:cflags is v:null
         let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
     endif
 
-    return l:cflags
+    return l:cflags isnot v:null ? l:cflags : ''
 endfunction
 
 function! ale#c#GetMakeCommand(buffer) abort
diff --git a/sources_non_forked/ale/autoload/ale/completion.vim b/sources_non_forked/ale/autoload/ale/completion.vim
index 03cc6471..ebf32909 100644
--- a/sources_non_forked/ale/autoload/ale/completion.vim
+++ b/sources_non_forked/ale/autoload/ale/completion.vim
@@ -52,6 +52,7 @@ let s:should_complete_map = {
 \   'lisp': s:lisp_regex,
 \   'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
 \   'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
+\   'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$',
 \}
 
 " Regular expressions for finding the start column to replace with completion.
@@ -59,11 +60,13 @@ let s:omni_start_map = {
 \   '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
 \}
 
-" A map of exact characters for triggering LSP completions.
+" A map of exact characters for triggering LSP completions. Do not forget to
+" update self.input_patterns in ale.py in updating entries in this map.
 let s:trigger_character_map = {
 \   '<default>': ['.'],
 \   'typescript': ['.', '''', '"'],
 \   'rust': ['.', '::'],
+\   'cpp': ['.', '::', '->'],
 \}
 
 function! s:GetFiletypeValue(map, filetype) abort
@@ -169,7 +172,7 @@ function! s:ReplaceCompletionOptions() abort
             let b:ale_old_omnifunc = &l:omnifunc
         endif
 
-        let &l:omnifunc = 'ale#completion#OmniFunc'
+        let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
     endif
 
     if l:source is# 'ale-automatic'
@@ -215,19 +218,11 @@ function! ale#completion#GetCompletionPosition() abort
     return l:column - len(l:match) - 1
 endfunction
 
+function! ale#completion#GetCompletionPositionForDeoplete(input) abort
+    return match(a:input, '\k*$')
+endfunction
+
 function! ale#completion#GetCompletionResult() abort
-    " Parse a new response if there is one.
-    if exists('b:ale_completion_response')
-    \&& exists('b:ale_completion_parser')
-        let l:response = b:ale_completion_response
-        let l:parser = b:ale_completion_parser
-
-        unlet b:ale_completion_response
-        unlet b:ale_completion_parser
-
-        let b:ale_completion_result = function(l:parser)(l:response)
-    endif
-
     if exists('b:ale_completion_result')
         return b:ale_completion_result
     endif
@@ -235,7 +230,7 @@ function! ale#completion#GetCompletionResult() abort
     return v:null
 endfunction
 
-function! ale#completion#OmniFunc(findstart, base) abort
+function! ale#completion#AutomaticOmniFunc(findstart, base) abort
     if a:findstart
         return ale#completion#GetCompletionPosition()
     else
@@ -247,15 +242,20 @@ function! ale#completion#OmniFunc(findstart, base) abort
     endif
 endfunction
 
-function! ale#completion#Show(response, completion_parser) abort
+function! ale#completion#Show(result) abort
     if ale#util#Mode() isnot# 'i'
         return
     endif
 
     " Set the list in the buffer, temporarily replace omnifunc with our
     " function, and then start omni-completion.
-    let b:ale_completion_response = a:response
-    let b:ale_completion_parser = a:completion_parser
+    let b:ale_completion_result = a:result
+
+    " Don't try to open the completion menu if there's nothing to show.
+    if empty(b:ale_completion_result)
+        return
+    endif
+
     " Replace completion options shortly before opening the menu.
     call s:ReplaceCompletionOptions()
 
@@ -267,6 +267,14 @@ function! ale#completion#Show(response, completion_parser) abort
         \   {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
         \)
     endif
+
+    if l:source is# 'ale-callback'
+        call b:CompleteCallback(b:ale_completion_result)
+    endif
+endfunction
+
+function! ale#completion#GetAllTriggers() abort
+    return deepcopy(s:trigger_character_map)
 endfunction
 
 function! s:CompletionStillValid(request_id) abort
@@ -279,6 +287,8 @@ function! s:CompletionStillValid(request_id) abort
     \&& (
     \   b:ale_completion_info.column == l:column
     \   || b:ale_completion_info.source is# 'deoplete'
+    \   || b:ale_completion_info.source is# 'ale-omnifunc'
+    \   || b:ale_completion_info.source is# 'ale-callback'
     \)
 endfunction
 
@@ -474,8 +484,7 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
         endif
     elseif l:command is# 'completionEntryDetails'
         call ale#completion#Show(
-        \   a:response,
-        \   'ale#completion#ParseTSServerCompletionEntryDetails',
+        \   ale#completion#ParseTSServerCompletionEntryDetails(a:response),
         \)
     endif
 endfunction
@@ -487,8 +496,7 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
     endif
 
     call ale#completion#Show(
-    \   a:response,
-    \   'ale#completion#ParseLSPCompletions',
+    \   ale#completion#ParseLSPCompletions(a:response),
     \)
 endfunction
 
@@ -529,10 +537,7 @@ function! s:OnReady(linter, lsp_details) abort
         let l:message = ale#lsp#message#Completion(
         \   l:buffer,
         \   b:ale_completion_info.line,
-        \   min([
-        \       b:ale_completion_info.line_length,
-        \       b:ale_completion_info.column,
-        \   ]) + 1,
+        \   b:ale_completion_info.column,
         \   ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
         \)
     endif
@@ -564,13 +569,26 @@ endfunction
 
 " This function can be used to manually trigger autocomplete, even when
 " g:ale_completion_enabled is set to false
-function! ale#completion#GetCompletions(source) abort
+function! ale#completion#GetCompletions(...) abort
+    let l:source = get(a:000, 0, '')
+    let l:options = get(a:000, 1, {})
+
+    if len(a:000) > 2
+        throw 'Too many arguments!'
+    endif
+
+    let l:CompleteCallback = get(l:options, 'callback', v:null)
+
+    if l:CompleteCallback isnot v:null
+        let b:CompleteCallback = l:CompleteCallback
+    endif
+
     let [l:line, l:column] = getpos('.')[1:2]
 
     let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
 
-    if a:source is# 'ale-automatic' && empty(l:prefix)
-        return
+    if l:source is# 'ale-automatic' && empty(l:prefix)
+        return 0
     endif
 
     let l:line_length = len(getline('.'))
@@ -582,18 +600,47 @@ function! ale#completion#GetCompletions(source) abort
     \   'prefix': l:prefix,
     \   'conn_id': 0,
     \   'request_id': 0,
-    \   'source': a:source,
+    \   'source': l:source,
     \}
     unlet! b:ale_completion_result
 
     let l:buffer = bufnr('')
     let l:Callback = function('s:OnReady')
 
+    let l:started = 0
+
     for l:linter in ale#linter#Get(&filetype)
         if !empty(l:linter.lsp)
-            call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
+            if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
+                let l:started = 1
+            endif
         endif
     endfor
+
+    return l:started
+endfunction
+
+function! ale#completion#OmniFunc(findstart, base) abort
+    if a:findstart
+        let l:started = ale#completion#GetCompletions('ale-omnifunc')
+
+        if !l:started
+            " This is the special value for cancelling completions silently.
+            " See :help complete-functions
+            return -3
+        endif
+
+        return ale#completion#GetCompletionPosition()
+    else
+        let l:result = ale#completion#GetCompletionResult()
+
+        while l:result is v:null && !complete_check()
+            sleep 2ms
+            let l:result = ale#completion#GetCompletionResult()
+        endwhile
+
+        return l:result isnot v:null ? l:result : []
+    endif
 endfunction
 
 function! s:TimerHandler(...) abort
diff --git a/sources_non_forked/ale/autoload/ale/debugging.vim b/sources_non_forked/ale/autoload/ale/debugging.vim
index e4bf5e7e..379c0d73 100644
--- a/sources_non_forked/ale/autoload/ale/debugging.vim
+++ b/sources_non_forked/ale/autoload/ale/debugging.vim
@@ -62,7 +62,7 @@ function! s:Echo(message) abort
     execute 'echo a:message'
 endfunction
 
-function! s:GetLinterVariables(filetype, linter_names) abort
+function! s:GetLinterVariables(filetype, exclude_linter_names) abort
     let l:variable_list = []
     let l:filetype_parts = split(a:filetype, '\.')
 
@@ -73,7 +73,7 @@ function! s:GetLinterVariables(filetype, linter_names) abort
         " Include matching variables.
         if !empty(l:match)
         \&& index(l:filetype_parts, l:match[1]) >= 0
-        \&& index(a:linter_names, l:match[2]) >= 0
+        \&& index(a:exclude_linter_names, l:match[2]) == -1
             call add(l:variable_list, l:key)
         endif
     endfor
@@ -211,10 +211,11 @@ function! ale#debugging#Info() abort
 
     let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
     let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
+    let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1')
 
     " Load linter variables to display
     " This must be done after linters are loaded.
-    let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
+    let l:variable_list = s:GetLinterVariables(l:filetype, l:exclude_names)
 
     let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
     let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
@@ -238,6 +239,12 @@ function! ale#debugging#Info() abort
 endfunction
 
 function! ale#debugging#InfoToClipboard() abort
+    if !has('clipboard')
+        call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
+
+        return
+    endif
+
     redir => l:output
         silent call ale#debugging#Info()
     redir END
diff --git a/sources_non_forked/ale/autoload/ale/engine.vim b/sources_non_forked/ale/autoload/ale/engine.vim
index 7db808d6..491d3c2e 100644
--- a/sources_non_forked/ale/autoload/ale/engine.vim
+++ b/sources_non_forked/ale/autoload/ale/engine.vim
@@ -710,6 +710,10 @@ function! ale#engine#Cleanup(buffer) abort
         return
     endif
 
+    if exists('*ale#lsp#CloseDocument')
+        call ale#lsp#CloseDocument(a:buffer)
+    endif
+
     if !has_key(g:ale_buffer_info, a:buffer)
         return
     endif
diff --git a/sources_non_forked/ale/autoload/ale/events.vim b/sources_non_forked/ale/autoload/ale/events.vim
index c3dbd378..da554ef9 100644
--- a/sources_non_forked/ale/autoload/ale/events.vim
+++ b/sources_non_forked/ale/autoload/ale/events.vim
@@ -128,7 +128,7 @@ function! ale#events#Init() abort
             endif
 
             if g:ale_lint_on_insert_leave
-                autocmd InsertLeave * call ale#Queue(0)
+                autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
             endif
 
             if g:ale_echo_cursor || g:ale_cursor_detail
diff --git a/sources_non_forked/ale/autoload/ale/fix.vim b/sources_non_forked/ale/autoload/ale/fix.vim
index 92ae3e14..9987fbdd 100644
--- a/sources_non_forked/ale/autoload/ale/fix.vim
+++ b/sources_non_forked/ale/autoload/ale/fix.vim
@@ -2,46 +2,60 @@ call ale#Set('fix_on_save_ignore', {})
 
 " Apply fixes queued up for buffers which may be hidden.
 " Vim doesn't let you modify hidden buffers.
-function! ale#fix#ApplyQueuedFixes() abort
-    let l:buffer = bufnr('')
-    let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
+function! ale#fix#ApplyQueuedFixes(buffer) abort
+    let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
+    let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline')
 
-    if !l:data.done
+    if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
         return
     endif
 
-    call remove(g:ale_fix_buffer_data, l:buffer)
+    call remove(g:ale_fix_buffer_data, a:buffer)
 
     if l:data.changes_made
-        let l:start_line = len(l:data.output) + 1
-        let l:end_line = len(l:data.lines_before)
-
-        if l:end_line >= l:start_line
-            let l:save = winsaveview()
-            silent execute l:start_line . ',' . l:end_line . 'd_'
-            call winrestview(l:save)
-        endif
-
         " If the file is in DOS mode, we have to remove carriage returns from
         " the ends of lines before calling setline(), or we will see them
         " twice.
-        let l:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
+        let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
         \   ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
         \   : l:data.output
+        let l:first_line_to_remove = len(l:new_lines) + 1
 
-        call setline(1, l:lines_to_set)
+        " Use a Vim API for setting lines in other buffers, if available.
+        if l:has_bufline_api
+            call setbufline(a:buffer, 1, l:new_lines)
+            call deletebufline(a:buffer, l:first_line_to_remove, '$')
+        " Fall back on setting lines the old way, for the current buffer.
+        else
+            let l:old_line_length = len(l:data.lines_before)
+
+            if l:old_line_length >= l:first_line_to_remove
+                let l:save = winsaveview()
+                silent execute
+                \   l:first_line_to_remove . ',' . l:old_line_length . 'd_'
+                call winrestview(l:save)
+            endif
+
+            call setline(1, l:new_lines)
+        endif
 
         if l:data.should_save
-            if empty(&buftype)
-                noautocmd :w!
+            if a:buffer is bufnr('')
+                if empty(&buftype)
+                    noautocmd :w!
+                else
+                    set nomodified
+                endif
             else
-                set nomodified
+                call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
+                call setbufvar(a:buffer, '&modified', 0)
             endif
         endif
     endif
 
     if l:data.should_save
-        let l:should_lint = g:ale_fix_on_save
+        let l:should_lint = ale#Var(a:buffer, 'fix_on_save')
+        \   && ale#Var(a:buffer, 'lint_on_save')
     else
         let l:should_lint = l:data.changes_made
     endif
@@ -52,7 +66,7 @@ function! ale#fix#ApplyQueuedFixes() abort
     " fixing problems.
     if g:ale_enabled
     \&& l:should_lint
-    \&& !ale#events#QuitRecently(l:buffer)
+    \&& !ale#events#QuitRecently(a:buffer)
         call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
     endif
 endfunction
@@ -83,7 +97,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
 
     " We can only change the lines of a buffer which is currently open,
     " so try and apply the fixes to the current buffer.
-    call ale#fix#ApplyQueuedFixes()
+    call ale#fix#ApplyQueuedFixes(a:buffer)
 endfunction
 
 function! s:HandleExit(job_info, buffer, job_output, data) abort
@@ -399,5 +413,4 @@ endfunction
 " Set up an autocmd command to try and apply buffer fixes when available.
 augroup ALEBufferFixGroup
     autocmd!
-    autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
-augroup END
+    autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))
diff --git a/sources_non_forked/ale/autoload/ale/fix/registry.vim b/sources_non_forked/ale/autoload/ale/fix/registry.vim
index 3a36f367..7a553ccc 100644
--- a/sources_non_forked/ale/autoload/ale/fix/registry.vim
+++ b/sources_non_forked/ale/autoload/ale/fix/registry.vim
@@ -115,6 +115,11 @@ let s:default_registry = {
 \       'suggested_filetypes': ['scala'],
 \       'description': 'Fix Scala files using scalafmt',
 \   },
+\   'sorbet': {
+\       'function': 'ale#fixers#sorbet#Fix',
+\       'suggested_filetypes': ['ruby'],
+\       'description': 'Fix ruby files with srb tc --autocorrect.',
+\   },
 \   'standard': {
 \       'function': 'ale#fixers#standard#Fix',
 \       'suggested_filetypes': ['javascript'],
@@ -145,6 +150,11 @@ let s:default_registry = {
 \       'suggested_filetypes': ['php'],
 \       'description': 'Fix PHP files with php-cs-fixer.',
 \   },
+\   'clangtidy': {
+\       'function': 'ale#fixers#clangtidy#Fix',
+\       'suggested_filetypes': ['c', 'cpp', 'objc'],
+\       'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.',
+\   },
 \   'clang-format': {
 \       'function': 'ale#fixers#clangformat#Fix',
 \       'suggested_filetypes': ['c', 'cpp', 'cuda'],
@@ -205,6 +215,11 @@ let s:default_registry = {
 \       'suggested_filetypes': ['haskell'],
 \       'description': 'Fix Haskell files with brittany.',
 \   },
+\   'hindent': {
+\       'function': 'ale#fixers#hindent#Fix',
+\       'suggested_filetypes': ['haskell'],
+\       'description': 'Fix Haskell files with hindent.',
+\   },
 \   'hlint': {
 \       'function': 'ale#fixers#hlint#Fix',
 \       'suggested_filetypes': ['haskell'],
@@ -297,7 +312,7 @@ let s:default_registry = {
 \   },
 \   'styler': {
 \       'function': 'ale#fixers#styler#Fix',
-\       'suggested_filetypes': ['r'],
+\       'suggested_filetypes': ['r', 'rmarkdown'],
 \       'description': 'Fix R files with styler.',
 \   },
 \   'latexindent': {
@@ -305,6 +320,21 @@ let s:default_registry = {
 \       'suggested_filetypes': ['tex'],
 \       'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
 \   },
+\   'pgformatter': {
+\       'function': 'ale#fixers#pgformatter#Fix',
+\       'suggested_filetypes': ['sql'],
+\       'description': 'A PostgreSQL SQL syntax beautifier',
+\   },
+\   'reorder-python-imports': {
+\       'function': 'ale#fixers#reorder_python_imports#Fix',
+\       'suggested_filetypes': ['python'],
+\       'description': 'Sort Python imports with reorder-python-imports.',
+\   },
+\   'gnatpp': {
+\       'function': 'ale#fixers#gnatpp#Fix',
+\       'suggested_filetypes': ['ada'],
+\       'description': 'Format Ada files with gnatpp.',
+\   },
 \}
 
 " Reset the function registry to the default entries.
diff --git a/sources_non_forked/ale/autoload/ale/fixers/black.vim b/sources_non_forked/ale/autoload/ale/fixers/black.vim
index 367b8d52..fba6c3b4 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/black.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/black.vim
@@ -29,6 +29,10 @@ function! ale#fixers#black#Fix(buffer) abort
 
     let l:options = ale#Var(a:buffer, 'python_black_options')
 
+    if expand('#' . a:buffer . ':e') is? 'pyi'
+        let l:options .= '--pyi'
+    endif
+
     return {
     \   'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
     \       . (!empty(l:options) ? ' ' . l:options : '')
diff --git a/sources_non_forked/ale/autoload/ale/fixers/clangformat.vim b/sources_non_forked/ale/autoload/ale/fixers/clangformat.vim
index eae1a7b4..ea5743a5 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/clangformat.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/clangformat.vim
@@ -13,10 +13,15 @@ function! ale#fixers#clangformat#GetExecutable(buffer) abort
 endfunction
 
 function! ale#fixers#clangformat#Fix(buffer) abort
+    let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
+    let l:filename = ale#Escape(bufname(a:buffer))
     let l:options = ale#Var(a:buffer, 'c_clangformat_options')
 
-    return {
-    \   'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
-    \       . ' ' . l:options,
-    \}
+    let l:command = l:executable . ' --assume-filename=' . l:filename
+
+    if l:options isnot# ''
+        let l:command .= ' ' . l:options
+    endif
+
+    return {'command': l:command}
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim b/sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim
new file mode 100644
index 00000000..b37360a7
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim
@@ -0,0 +1,52 @@
+scriptencoding utf-8
+" Author: ObserverOfTime <chronobserver@disroot.org>
+" Description: Fixing C/C++ files with clang-tidy.
+
+function! s:set_variables() abort
+    let l:use_global = get(g:, 'ale_use_global_executables', 0)
+
+    for l:ft in ['c', 'cpp']
+        call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy')
+        call ale#Set(l:ft . '_clangtidy_use_global', l:use_global)
+        call ale#Set(l:ft . '_clangtidy_checks', [])
+        call ale#Set(l:ft . '_clangtidy_options', '')
+        call ale#Set(l:ft . '_clangtidy_extra_options', '')
+        call ale#Set(l:ft . '_clangtidy_fix_errors', 1)
+    endfor
+
+    call ale#Set('c_build_dir', '')
+endfunction
+
+call s:set_variables()
+
+function! ale#fixers#clangtidy#Var(buffer, name) abort
+    let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
+    let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
+
+    return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name)
+endfunction
+
+function! ale#fixers#clangtidy#GetCommand(buffer) abort
+    let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',')
+    let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options')
+    let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
+    let l:options = empty(l:build_dir)
+    \   ? ale#fixers#clangtidy#Var(a:buffer, 'options') : ''
+    let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors')
+
+    return ' -fix' . (l:fix_errors ? ' -fix-errors' : '')
+    \   . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks))
+    \   . (empty(l:extra_options) ? '' : ' ' . l:extra_options)
+    \   . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir))
+    \   . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options)
+endfunction
+
+function! ale#fixers#clangtidy#Fix(buffer) abort
+    let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable')
+    let l:command = ale#fixers#clangtidy#GetCommand(a:buffer)
+
+    return {
+    \   'command': ale#Escape(l:executable) . l:command,
+    \   'read_temporary_file': 1,
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/eslint.vim b/sources_non_forked/ale/autoload/ale/fixers/eslint.vim
index 0f57cba6..62e692b1 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/eslint.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/eslint.vim
@@ -35,9 +35,18 @@ endfunction
 
 function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
     let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
-    let l:config = ale#handlers#eslint#FindConfig(a:buffer)
+    let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
 
-    if empty(l:config)
+    " Use the configuration file from the options, if configured.
+    if l:options =~# '\v(^| )-c|(^| )--config'
+        let l:config = ''
+        let l:has_config = 1
+    else
+        let l:config = ale#handlers#eslint#FindConfig(a:buffer)
+        let l:has_config = !empty(l:config)
+    endif
+
+    if !l:has_config
         return 0
     endif
 
@@ -45,6 +54,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
     if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
         return {
         \   'command': ale#node#Executable(a:buffer, l:executable)
+        \       . ale#Pad(l:options)
         \       . ' --stdin-filename %s --stdin --fix-to-stdout',
         \   'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
         \}
@@ -54,6 +64,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
     if ale#semver#GTE(a:version, [4, 9, 0])
         return {
         \   'command': ale#node#Executable(a:buffer, l:executable)
+        \       . ale#Pad(l:options)
         \       . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
         \   'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
         \}
@@ -61,7 +72,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
 
     return {
     \   'command': ale#node#Executable(a:buffer, l:executable)
-    \       . ' -c ' . ale#Escape(l:config)
+    \       . ale#Pad(l:options)
+    \       . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
     \       . ' --fix %t',
     \   'read_temporary_file': 1,
     \}
diff --git a/sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim b/sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim
new file mode 100644
index 00000000..bf3d484e
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim
@@ -0,0 +1,17 @@
+" Author: tim <tim@inept.tech>
+" Description: Fix files with gnatpp.
+
+call ale#Set('ada_gnatpp_executable', 'gnatpp')
+call ale#Set('ada_gnatpp_options', '')
+
+function! ale#fixers#gnatpp#Fix(buffer) abort
+    let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
+    let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
+
+    return {
+    \   'command': ale#Escape(l:executable)
+    \       . (!empty(l:options) ? ' ' . l:options : '')
+    \       . ' %t',
+    \   'read_temporary_file': 1,
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/gofmt.vim b/sources_non_forked/ale/autoload/ale/fixers/gofmt.vim
index 66b67a9e..d5a539b9 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/gofmt.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/gofmt.vim
@@ -7,9 +7,10 @@ call ale#Set('go_gofmt_options', '')
 function! ale#fixers#gofmt#Fix(buffer) abort
     let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
     let l:options = ale#Var(a:buffer, 'go_gofmt_options')
+    let l:env = ale#go#EnvString(a:buffer)
 
     return {
-    \   'command': ale#Escape(l:executable)
+    \   'command': l:env . ale#Escape(l:executable)
     \       . ' -l -w'
     \       . (empty(l:options) ? '' : ' ' . l:options)
     \       . ' %t',
diff --git a/sources_non_forked/ale/autoload/ale/fixers/goimports.vim b/sources_non_forked/ale/autoload/ale/fixers/goimports.vim
index 783d0206..65f0fd98 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/goimports.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/goimports.vim
@@ -7,13 +7,14 @@ call ale#Set('go_goimports_options', '')
 function! ale#fixers#goimports#Fix(buffer) abort
     let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
     let l:options = ale#Var(a:buffer, 'go_goimports_options')
+    let l:env = ale#go#EnvString(a:buffer)
 
     if !executable(l:executable)
         return 0
     endif
 
     return {
-    \   'command': ale#Escape(l:executable)
+    \   'command': l:env . ale#Escape(l:executable)
     \       . ' -l -w -srcdir %s'
     \       . (empty(l:options) ? '' : ' ' . l:options)
     \       . ' %t',
diff --git a/sources_non_forked/ale/autoload/ale/fixers/gomod.vim b/sources_non_forked/ale/autoload/ale/fixers/gomod.vim
index 68895f9b..ee8c46c9 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/gomod.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/gomod.vim
@@ -2,9 +2,10 @@ call ale#Set('go_go_executable', 'go')
 
 function! ale#fixers#gomod#Fix(buffer) abort
     let l:executable = ale#Var(a:buffer, 'go_go_executable')
+    let l:env = ale#go#EnvString(a:buffer)
 
     return {
-    \   'command': ale#Escape(l:executable) . ' mod edit -fmt %t',
+    \   'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t',
     \   'read_temporary_file': 1,
     \}
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/hindent.vim b/sources_non_forked/ale/autoload/ale/fixers/hindent.vim
new file mode 100644
index 00000000..b6009a2c
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/hindent.vim
@@ -0,0 +1,20 @@
+" Author: AlexeiDrake <drake.alexei@gmail.com>
+" Description: Integration of hindent formatting with ALE.
+"
+call ale#Set('haskell_hindent_executable', 'hindent')
+
+function! ale#fixers#hindent#GetExecutable(buffer) abort
+    let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable')
+
+    return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent')
+endfunction
+
+function! ale#fixers#hindent#Fix(buffer) abort
+    let l:executable = ale#fixers#hindent#GetExecutable(a:buffer)
+
+    return {
+    \   'command': l:executable
+    \       . ' %t',
+    \   'read_temporary_file': 1,
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim b/sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
new file mode 100644
index 00000000..9ea08ec6
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
@@ -0,0 +1,12 @@
+call ale#Set('sql_pgformatter_executable', 'pg_format')
+call ale#Set('sql_pgformatter_options', '')
+
+function! ale#fixers#pgformatter#Fix(buffer) abort
+    let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
+    let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
+
+    return {
+    \   'command': ale#Escape(l:executable)
+    \       . (empty(l:options) ? '' : ' ' . l:options),
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim
index b7f0ecd7..23120777 100644
--- a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim
+++ b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim
@@ -39,9 +39,15 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
     let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
     let l:parser = ''
 
+    let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
+
+    if index(l:filetypes, 'handlebars') > -1
+        let l:parser = 'glimmer'
+    endif
+
     " Append the --parser flag depending on the current filetype (unless it's
     " already set in g:javascript_prettier_options).
-    if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
+    if empty(expand('#' . a:buffer . ':e')) && l:parser is# ''  && match(l:options, '--parser') == -1
         " Mimic Prettier's defaults. In cases without a file extension or
         " filetype (scratch buffer), Prettier needs `parser` set to know how
         " to process the buffer.
@@ -65,7 +71,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
         \    'html': 'html',
         \}
 
-        for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
+        for l:filetype in l:filetypes
             if has_key(l:prettier_parsers, l:filetype)
                 let l:parser = l:prettier_parsers[l:filetype]
                 break
diff --git a/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim b/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim
new file mode 100644
index 00000000..42a0a6e2
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim
@@ -0,0 +1,25 @@
+" Author: jake <me@jake.computer>
+" Description: Fixing Python imports with reorder-python-imports.
+
+call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
+call ale#Set('python_reorder_python_imports_options', '')
+call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
+
+function! ale#fixers#reorder_python_imports#Fix(buffer) abort
+    let l:executable = ale#python#FindExecutable(
+    \   a:buffer,
+    \   'python_reorder_python_imports',
+    \   ['reorder-python-imports'],
+    \)
+
+    if !executable(l:executable)
+        return 0
+    endif
+
+    let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
+
+    return {
+    \   'command': ale#Escape(l:executable)
+    \       . (!empty(l:options) ? ' ' . l:options : '') . ' -',
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/fixers/sorbet.vim b/sources_non_forked/ale/autoload/ale/fixers/sorbet.vim
new file mode 100644
index 00000000..182f7300
--- /dev/null
+++ b/sources_non_forked/ale/autoload/ale/fixers/sorbet.vim
@@ -0,0 +1,19 @@
+call ale#Set('ruby_sorbet_executable', 'srb')
+call ale#Set('ruby_sorbet_options', '')
+
+function! ale#fixers#sorbet#GetCommand(buffer) abort
+    let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
+    let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
+
+    return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
+    \   . ' tc'
+    \   . (!empty(l:options) ? ' ' . l:options : '')
+    \   . ' --autocorrect --file %t'
+endfunction
+
+function! ale#fixers#sorbet#Fix(buffer) abort
+    return {
+    \   'command': ale#fixers#sorbet#GetCommand(a:buffer),
+    \   'read_temporary_file': 1,
+    \}
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/go.vim b/sources_non_forked/ale/autoload/ale/go.vim
index cd7d9503..4a21e596 100644
--- a/sources_non_forked/ale/autoload/ale/go.vim
+++ b/sources_non_forked/ale/autoload/ale/go.vim
@@ -25,3 +25,20 @@ function! ale#go#FindProjectRoot(buffer) abort
 
     return ''
 endfunction
+
+
+call ale#Set('go_go111module', '')
+
+" Return a string setting Go-specific environment variables
+function! ale#go#EnvString(buffer) abort
+    let l:env = ''
+
+    " GO111MODULE - turn go modules behavior on/off
+    let l:go111module = ale#Var(a:buffer, 'go_go111module')
+
+    if !empty(l:go111module)
+        let l:env = ale#Env('GO111MODULE', l:go111module) . l:env
+    endif
+
+    return l:env
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/handlers/ccls.vim b/sources_non_forked/ale/autoload/ale/handlers/ccls.vim
index 29dd6aed..1e2aa318 100644
--- a/sources_non_forked/ale/autoload/ale/handlers/ccls.vim
+++ b/sources_non_forked/ale/autoload/ale/handlers/ccls.vim
@@ -3,15 +3,17 @@ scriptencoding utf-8
 " Description: Utilities for ccls
 
 function! ale#handlers#ccls#GetProjectRoot(buffer) abort
-    let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
+    " Try to find ccls configuration files first.
+    let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
 
-    if empty(l:project_root)
-        let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
+    if empty(l:config)
+        let l:config = ale#path#FindNearestFile(a:buffer, '.ccls')
     endif
 
-    if empty(l:project_root)
-        let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
+    if !empty(l:config)
+        return fnamemodify(l:config, ':h')
     endif
 
-    return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
+    " Fall back on default project root detection.
+    return ale#c#FindProjectRoot(a:buffer)
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/handlers/cppcheck.vim b/sources_non_forked/ale/autoload/ale/handlers/cppcheck.vim
index dc56cd0b..6d8fa15d 100644
--- a/sources_non_forked/ale/autoload/ale/handlers/cppcheck.vim
+++ b/sources_non_forked/ale/autoload/ale/handlers/cppcheck.vim
@@ -1,5 +1,46 @@
 " Description: Handle errors for cppcheck.
 
+function! ale#handlers#cppcheck#GetCdCommand(buffer) abort
+    let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
+    let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
+
+    return l:cd_command
+endfunction
+
+function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
+    let l:buffer_path_include = ''
+
+    " Get path to this buffer so we can include it into cppcheck with -I
+    " This could be expanded to get more -I directives from the compile
+    " command in compile_commands.json, if it's found.
+    let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h')
+    let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path)
+
+    return l:buffer_path_include
+endfunction
+
+function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
+    " If the current buffer is modified, using compile_commands.json does no
+    " good, so include the file's directory instead. It's not quite as good as
+    " using --project, but is at least equivalent to running cppcheck on this
+    " file manually from the file's directory.
+    let l:modified = getbufvar(a:buffer, '&modified')
+
+    if l:modified
+        return ''
+    endif
+
+    " Search upwards from the file for compile_commands.json.
+    "
+    " If we find it, we'll `cd` to where the compile_commands.json file is,
+    " then use the file to set up import paths, etc.
+    let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
+
+    return !empty(l:json_path)
+    \   ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
+    \   : ''
+endfunction
+
 function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
     " Look for lines like the following.
     "
diff --git a/sources_non_forked/ale/autoload/ale/handlers/eslint.vim b/sources_non_forked/ale/autoload/ale/handlers/eslint.vim
index 5183f4cd..4d533ff2 100644
--- a/sources_non_forked/ale/autoload/ale/handlers/eslint.vim
+++ b/sources_non_forked/ale/autoload/ale/handlers/eslint.vim
@@ -44,16 +44,9 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
 
     return ale#node#Executable(a:buffer, l:executable)
     \   . (!empty(l:options) ? ' ' . l:options : '')
-    \   . ' -f unix --stdin --stdin-filename %s'
+    \   . ' -f json --stdin --stdin-filename %s'
 endfunction
 
-let s:col_end_patterns = [
-\   '\vParsing error: Unexpected token (.+) ?',
-\   '\v''(.+)'' is not defined.',
-\   '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
-\   '\vUnexpected (console) statement',
-\]
-
 function! s:AddHintsForTypeScriptParsingErrors(output) abort
     for l:item in a:output
         let l:item.text = substitute(
@@ -90,22 +83,71 @@ function! s:CheckForBadConfig(buffer, lines) abort
     return 0
 endfunction
 
-function! ale#handlers#eslint#Handle(buffer, lines) abort
-    if s:CheckForBadConfig(a:buffer, a:lines)
-        return [{
-        \   'lnum': 1,
-        \   'text': 'eslint configuration error (type :ALEDetail for more information)',
-        \   'detail': join(a:lines, "\n"),
-        \}]
+function! s:parseJSON(buffer, lines) abort
+    try
+        let l:parsed = json_decode(a:lines[-1])
+    catch
+        return []
+    endtry
+
+    if type(l:parsed) != v:t_list || empty(l:parsed)
+        return []
     endif
 
-    if a:lines == ['Could not connect']
-        return [{
-        \   'lnum': 1,
-        \   'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
-        \}]
+    let l:errors = l:parsed[0]['messages']
+
+    if empty(l:errors)
+        return []
     endif
 
+    let l:output = []
+
+    for l:error in l:errors
+        let l:obj = ({
+        \   'lnum': get(l:error, 'line', 0),
+        \   'text': get(l:error, 'message', ''),
+        \   'type': 'E',
+        \})
+
+        if get(l:error, 'severity', 0) is# 1
+            let l:obj.type = 'W'
+        endif
+
+        if has_key(l:error, 'ruleId')
+            let l:code = l:error['ruleId']
+
+            " Sometimes ESLint returns null here
+            if !empty(l:code)
+                let l:obj.code = l:code
+            endif
+        endif
+
+        if has_key(l:error, 'column')
+            let l:obj.col = l:error['column']
+        endif
+
+        if has_key(l:error, 'endColumn')
+            let l:obj.end_col = l:error['endColumn'] - 1
+        endif
+
+        if has_key(l:error, 'endLine')
+            let l:obj.end_lnum = l:error['endLine']
+        endif
+
+        call add(l:output, l:obj)
+    endfor
+
+    return l:output
+endfunction
+
+let s:col_end_patterns = [
+\   '\vParsing error: Unexpected token (.+) ?',
+\   '\v''(.+)'' is not defined.',
+\   '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
+\   '\vUnexpected (console) statement',
+\]
+
+function! s:parseLines(buffer, lines) abort
     " Matches patterns line the following:
     "
     " /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
@@ -120,12 +162,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
     for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
         let l:text = l:match[3]
 
-        if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
-            if l:text =~# '^File ignored'
-                continue
-            endif
-        endif
-
         let l:obj = {
         \   'lnum': l:match[1] + 0,
         \   'col': l:match[2] + 0,
@@ -143,11 +179,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
         " The code can be something like 'Error/foo/bar', or just 'Error'
         if !empty(get(l:split_code, 1))
             let l:obj.code = join(l:split_code[1:], '/')
-
-            if l:obj.code is# 'no-trailing-spaces'
-            \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
-                continue
-            endif
         endif
 
         for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns)
@@ -157,9 +188,59 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
         call add(l:output, l:obj)
     endfor
 
+    return l:output
+endfunction
+
+function! s:FilterResult(buffer, obj) abort
+    if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
+        if a:obj.text =~# '^File ignored'
+            return 0
+        endif
+    endif
+
+    if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces'
+    \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
+        return 0
+    endif
+
+    return 1
+endfunction
+
+function! s:HandleESLintOutput(buffer, lines, type) abort
+    if s:CheckForBadConfig(a:buffer, a:lines)
+        return [{
+        \   'lnum': 1,
+        \   'text': 'eslint configuration error (type :ALEDetail for more information)',
+        \   'detail': join(a:lines, "\n"),
+        \}]
+    endif
+
+    if a:lines == ['Could not connect']
+        return [{
+        \   'lnum': 1,
+        \   'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
+        \}]
+    endif
+
+    if a:type is# 'json'
+        let l:output = s:parseJSON(a:buffer, a:lines)
+    else
+        let l:output = s:parseLines(a:buffer, a:lines)
+    endif
+
+    call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)})
+
     if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
         call s:AddHintsForTypeScriptParsingErrors(l:output)
     endif
 
     return l:output
 endfunction
+
+function! ale#handlers#eslint#HandleJSON(buffer, lines) abort
+    return s:HandleESLintOutput(a:buffer, a:lines, 'json')
+endfunction
+
+function! ale#handlers#eslint#Handle(buffer, lines) abort
+    return s:HandleESLintOutput(a:buffer, a:lines, 'lines')
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/handlers/gcc.vim b/sources_non_forked/ale/autoload/ale/handlers/gcc.vim
index 72d639da..ec16b977 100644
--- a/sources_non_forked/ale/autoload/ale/handlers/gcc.vim
+++ b/sources_non_forked/ale/autoload/ale/handlers/gcc.vim
@@ -11,6 +11,7 @@ let s:pragma_error = '#pragma once in main file'
 " <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
 " -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
 let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
+let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
 
 function! s:IsHeaderFile(filename) abort
     return a:filename =~? '\v\.(h|hpp)$'
@@ -25,6 +26,28 @@ function! s:RemoveUnicodeQuotes(text) abort
     return l:text
 endfunction
 
+function! s:ParseInlinedFunctionProblems(buffer, lines) abort
+    let l:output = []
+    let l:pos_match = []
+
+    for l:line in a:lines
+        let l:match = matchlist(l:line, s:pattern)
+
+        if !empty(l:match) && !empty(l:pos_match)
+            call add(l:output, {
+            \   'lnum': str2nr(l:pos_match[1]),
+            \   'col': str2nr(l:pos_match[2]),
+            \   'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
+            \   'text': s:RemoveUnicodeQuotes(l:match[5]),
+            \})
+        endif
+
+        let l:pos_match = matchlist(l:line, s:inline_pattern)
+    endfor
+
+    return l:output
+endfunction
+
 " Report problems inside of header files just for gcc and clang
 function! s:ParseProblemsInHeaders(buffer, lines) abort
     let l:output = []
@@ -129,6 +152,7 @@ endfunction
 function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
     let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
 
+    call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
     call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
 
     return l:output
diff --git a/sources_non_forked/ale/autoload/ale/handlers/rust.vim b/sources_non_forked/ale/autoload/ale/handlers/rust.vim
index dda6466e..a7fac464 100644
--- a/sources_non_forked/ale/autoload/ale/handlers/rust.vim
+++ b/sources_non_forked/ale/autoload/ale/handlers/rust.vim
@@ -56,14 +56,20 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
             endif
 
             if !empty(l:span)
-                call add(l:output, {
+                let l:output_line = {
                 \   'lnum': l:span.line_start,
                 \   'end_lnum': l:span.line_end,
                 \   'col': l:span.column_start,
                 \   'end_col': l:span.column_end-1,
                 \   'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
                 \   'type': toupper(l:error.level[0]),
-                \})
+                \}
+
+                if has_key(l:error, 'rendered') && !empty(l:error.rendered)
+                    let l:output_line.detail = l:error.rendered
+                endif
+
+                call add(l:output, l:output_line)
             endif
         endfor
     endfor
diff --git a/sources_non_forked/ale/autoload/ale/highlight.vim b/sources_non_forked/ale/autoload/ale/highlight.vim
index 172f9d54..cb7911e1 100644
--- a/sources_non_forked/ale/autoload/ale/highlight.vim
+++ b/sources_non_forked/ale/autoload/ale/highlight.vim
@@ -26,41 +26,6 @@ endif
 let s:MAX_POS_VALUES = 8
 let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
 
-" Check if we have neovim's buffer highlight API
-"
-" Below we define some functions' implementation conditionally if this API
-" exists or not.
-"
-" The API itself is more ergonomic and neovim performs highlights positions
-" rebases during edits so we see less stalled highlights.
-let s:nvim_api = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
-
-function! ale#highlight#HasNeovimApi() abort
-    return s:nvim_api
-endfunction
-
-function! ale#highlight#nvim_buf_clear_namespace(...) abort
-    return call('nvim_buf_clear_namespace', a:000)
-endfunction
-
-function! ale#highlight#nvim_buf_add_highlight(...) abort
-    return call('nvim_buf_add_highlight', a:000)
-endfunction
-
-function! s:ale_nvim_highlight_id(bufnr) abort
-    let l:id = getbufvar(a:bufnr, 'ale_nvim_highlight_id', -1)
-
-    if l:id is -1
-        " NOTE: This will highlight nothing but will allocate new id
-        let l:id = ale#highlight#nvim_buf_add_highlight(
-        \   a:bufnr, 0, '', 0, 0, -1
-        \)
-        call setbufvar(a:bufnr, 'ale_nvim_highlight_id', l:id)
-    endif
-
-    return l:id
-endfunction
-
 function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
     if a:line >= a:end_line
         " For single lines, just return the one position.
@@ -86,88 +51,29 @@ endfunction
 " except these which have matching loclist item entries.
 
 function! ale#highlight#RemoveHighlights() abort
-    if ale#highlight#HasNeovimApi()
-        if get(b:, 'ale_nvim_highlight_id', 0)
-            let l:bufnr = bufnr('%')
-            " NOTE: 0, -1 means from 0 line till the end of buffer
-            call ale#highlight#nvim_buf_clear_namespace(
-            \   l:bufnr,
-            \   b:ale_nvim_highlight_id,
-            \   0, -1
-            \)
+    for l:match in getmatches()
+        if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
+            call matchdelete(l:match.id)
         endif
-    else
-        for l:match in getmatches()
-            if l:match.group =~# '^ALE'
-                call matchdelete(l:match.id)
-            endif
-        endfor
-    endif
+    endfor
 endfunction
 
 function! s:highlight_line(bufnr, lnum, group) abort
-    if ale#highlight#HasNeovimApi()
-        let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
-        call ale#highlight#nvim_buf_add_highlight(
-        \   a:bufnr, l:highlight_id, a:group,
-        \   a:lnum - 1, 0, -1
-        \)
-    else
-        call matchaddpos(a:group, [a:lnum])
-    endif
+    call matchaddpos(a:group, [a:lnum])
 endfunction
 
 function! s:highlight_range(bufnr, range, group) abort
-    if ale#highlight#HasNeovimApi()
-        let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
-        " NOTE: lines and columns indicies are 0-based in nvim_buf_* API.
-        let l:lnum = a:range.lnum - 1
-        let l:end_lnum = a:range.end_lnum - 1
-        let l:col = a:range.col - 1
-        let l:end_col = a:range.end_col
-
-        if l:lnum >= l:end_lnum
-            " For single lines, just return the one position.
-            call ale#highlight#nvim_buf_add_highlight(
-            \   a:bufnr, l:highlight_id, a:group,
-            \   l:lnum, l:col, l:end_col
-            \)
-        else
-            " highlight first line from start till the line end
-            call ale#highlight#nvim_buf_add_highlight(
-            \   a:bufnr, l:highlight_id, a:group,
-            \   l:lnum, l:col, -1
-            \)
-
-            " highlight all lines between the first and last entirely
-            let l:cur = l:lnum + 1
-
-            while l:cur < l:end_lnum
-                call ale#highlight#nvim_buf_add_highlight(
-                \   a:bufnr, l:highlight_id, a:group,
-                \   l:cur, 0, -1
-                \   )
-                let l:cur += 1
-            endwhile
-
-            call ale#highlight#nvim_buf_add_highlight(
-            \   a:bufnr, l:highlight_id, a:group,
-            \   l:end_lnum, 0, l:end_col
-            \)
-        endif
-    else
-        " Set all of the positions, which are chunked into Lists which
-        " are as large as will be accepted by matchaddpos.
-        call map(
-        \   ale#highlight#CreatePositions(
-        \       a:range.lnum,
-        \       a:range.col,
-        \       a:range.end_lnum,
-        \       a:range.end_col
-        \   ),
-        \   'matchaddpos(a:group, v:val)'
-        \)
-    endif
+    " Set all of the positions, which are chunked into Lists which
+    " are as large as will be accepted by matchaddpos.
+    call map(
+    \   ale#highlight#CreatePositions(
+    \       a:range.lnum,
+    \       a:range.col,
+    \       a:range.end_lnum,
+    \       a:range.end_col
+    \   ),
+    \   'matchaddpos(a:group, v:val)'
+    \)
 endfunction
 
 function! ale#highlight#UpdateHighlights() abort
diff --git a/sources_non_forked/ale/autoload/ale/java.vim b/sources_non_forked/ale/autoload/ale/java.vim
index b7fd10bd..e641ac6c 100644
--- a/sources_non_forked/ale/autoload/ale/java.vim
+++ b/sources_non_forked/ale/autoload/ale/java.vim
@@ -16,5 +16,11 @@ function! ale#java#FindProjectRoot(buffer) abort
         return fnamemodify(l:maven_pom_file, ':h')
     endif
 
+    let l:ant_root = ale#ant#FindProjectRoot(a:buffer)
+
+    if !empty(l:ant_root)
+        return l:ant_root
+    endif
+
     return ''
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/linter.vim b/sources_non_forked/ale/autoload/ale/linter.vim
index 8c657675..78dcd3a2 100644
--- a/sources_non_forked/ale/autoload/ale/linter.vim
+++ b/sources_non_forked/ale/autoload/ale/linter.vim
@@ -13,10 +13,13 @@ let s:default_ale_linter_aliases = {
 \   'Dockerfile': 'dockerfile',
 \   'csh': 'sh',
 \   'plaintex': 'tex',
+\   'rmarkdown': 'r',
 \   'systemverilog': 'verilog',
 \   'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
 \   'vimwiki': 'markdown',
 \   'vue': ['vue', 'javascript'],
+\   'xsd': ['xsd', 'xml'],
+\   'xslt': ['xslt', 'xml'],
 \   'zsh': 'sh',
 \}
 
@@ -355,12 +358,14 @@ function! ale#linter#Define(filetype, linter) abort
     " This command will throw from the sandbox.
     let &l:equalprg=&l:equalprg
 
+    let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
+
     if !has_key(s:linters, a:filetype)
         let s:linters[a:filetype] = []
     endif
 
-    let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
-
+    " Remove previously defined linters with the same name.
+    call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
     call add(s:linters[a:filetype], l:new_linter)
 endfunction
 
diff --git a/sources_non_forked/ale/autoload/ale/list.vim b/sources_non_forked/ale/autoload/ale/list.vim
index 63d97f35..4bfe2a7b 100644
--- a/sources_non_forked/ale/autoload/ale/list.vim
+++ b/sources_non_forked/ale/autoload/ale/list.vim
@@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort
     return l:new_list
 endfunction
 
-function! s:BufWinId(buffer) abort
-    return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
+function! s:WinFindBuf(buffer) abort
+    return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
 endfunction
 
 function! s:SetListsImpl(timer_id, buffer, loclist) abort
@@ -88,19 +88,24 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
             call setqflist([], 'r', {'title': l:title})
         endif
     elseif g:ale_set_loclist
-        " If windows support is off, bufwinid() may not exist.
+        " If windows support is off, win_findbuf() may not exist.
         " We'll set result in the current window, which might not be correct,
         " but it's better than nothing.
-        let l:id = s:BufWinId(a:buffer)
+        let l:ids = s:WinFindBuf(a:buffer)
 
-        if has('nvim')
-            call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
-        else
-            call setloclist(l:id, s:FixList(a:buffer, a:loclist))
-            call setloclist(l:id, [], 'r', {'title': l:title})
-        endif
+        for l:id in l:ids
+            if has('nvim')
+                call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
+            else
+                call setloclist(l:id, s:FixList(a:buffer, a:loclist))
+                call setloclist(l:id, [], 'r', {'title': l:title})
+            endif
+        endfor
     endif
 
+    " Save the current view before opening/closing any window
+    call setbufvar(a:buffer, 'ale_winview', winsaveview())
+
     " Open a window to show the problems if we need to.
     "
     " We'll check if the current buffer's List is not empty here, so the
@@ -108,8 +113,6 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
     if s:ShouldOpen(a:buffer) && !empty(a:loclist)
         let l:winnr = winnr()
         let l:mode = mode()
-        let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
-        let l:reset_character_selection = l:mode is? 's' || l:mode is# "\<c-s>"
 
         " open windows vertically instead of default horizontally
         let l:open_type = ''
@@ -131,15 +134,18 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
             wincmd p
         endif
 
-        if l:reset_visual_selection || l:reset_character_selection
-            " If we were in a selection mode before, select the last selection.
-            normal! gv
-
-            if l:reset_character_selection
-                " Switch back to Select mode, if we were in that.
+        " Return to original mode when applicable
+        if mode() != l:mode
+            if l:mode is? 'v' || l:mode is# "\<c-v>"
+                " Reset our last visual selection
+                normal! gv
+            elseif l:mode is? 's' || l:mode is# "\<c-s>"
+                " Reset our last character selection
                 normal! "\<c-g>"
             endif
         endif
+
+        call s:RestoreViewIfNeeded(a:buffer)
     endif
 
     " If ALE isn't currently checking for more problems, close the window if
@@ -150,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
     endif
 endfunction
 
+" Try to restore the window view after closing any of the lists to avoid making
+" the it moving around, especially useful when on insert mode
+function! s:RestoreViewIfNeeded(buffer) abort
+    let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
+
+    " Saved view is empty, can't do anything
+    if empty(l:saved_view)
+        return
+    endif
+
+    " Check wether the cursor has moved since linting was actually requested. If
+    " the user has indeed moved lines, do nothing
+    let l:current_view = winsaveview()
+
+    if l:current_view['lnum'] != l:saved_view['lnum']
+        return
+    endif
+
+    " Anchor view by topline if the list is set to open horizontally
+    if ale#Var(a:buffer, 'list_vertical') == 0
+        call winrestview({'topline': l:saved_view['topline']})
+    endif
+endfunction
+
 function! ale#list#SetLists(buffer, loclist) abort
     if get(g:, 'ale_set_lists_synchronously') == 1
     \|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
@@ -173,21 +203,31 @@ function! s:CloseWindowIfNeeded(buffer) abort
         return
     endif
 
+    let l:did_close_any_list = 0
+
     try
         " Only close windows if the quickfix list or loclist is completely empty,
         " including errors set through other means.
         if g:ale_set_quickfix
             if empty(getqflist())
                 cclose
+                let l:did_close_any_list = 1
             endif
         else
-            let l:win_id = s:BufWinId(a:buffer)
+            let l:win_ids = s:WinFindBuf(a:buffer)
 
-            if g:ale_set_loclist && empty(getloclist(l:win_id))
-                lclose
-            endif
+            for l:win_id in l:win_ids
+                if g:ale_set_loclist && empty(getloclist(l:win_id))
+                    lclose
+                    let l:did_close_any_list = 1
+                endif
+            endfor
         endif
     " Ignore 'Cannot close last window' errors.
     catch /E444/
     endtry
+
+    if l:did_close_any_list
+        call s:RestoreViewIfNeeded(a:buffer)
+    endif
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/loclist_jumping.vim b/sources_non_forked/ale/autoload/ale/loclist_jumping.vim
index 1d3ef7e5..55097d12 100644
--- a/sources_non_forked/ale/autoload/ale/loclist_jumping.vim
+++ b/sources_non_forked/ale/autoload/ale/loclist_jumping.vim
@@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
 
     if !empty(l:nearest)
         normal! m`
-        call cursor(l:nearest)
+        call cursor([l:nearest[0], max([l:nearest[1], 1])])
     endif
 endfunction
 
diff --git a/sources_non_forked/ale/autoload/ale/lsp.vim b/sources_non_forked/ale/autoload/ale/lsp.vim
index 7186d2a9..017096cd 100644
--- a/sources_non_forked/ale/autoload/ale/lsp.vim
+++ b/sources_non_forked/ale/autoload/ale/lsp.vim
@@ -321,7 +321,69 @@ endfunction
 
 function! s:SendInitMessage(conn) abort
     let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
-    \   ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
+    \   ale#lsp#message#Initialize(
+    \       a:conn.root,
+    \       a:conn.init_options,
+    \       {
+    \           'workspace': {
+    \               'applyEdit': v:false,
+    \               'didChangeConfiguration': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \               'symbol': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \               'workspaceFolders': v:false,
+    \               'configuration': v:false,
+    \           },
+    \           'textDocument': {
+    \               'synchronization': {
+    \                   'dynamicRegistration': v:false,
+    \                   'willSave': v:false,
+    \                   'willSaveWaitUntil': v:false,
+    \                   'didSave': v:true,
+    \               },
+    \               'completion': {
+    \                   'dynamicRegistration': v:false,
+    \                   'completionItem': {
+    \                       'snippetSupport': v:false,
+    \                       'commitCharactersSupport': v:false,
+    \                       'documentationFormat': ['plaintext'],
+    \                       'deprecatedSupport': v:false,
+    \                       'preselectSupport': v:false,
+    \                   },
+    \                   'contextSupport': v:false,
+    \               },
+    \               'hover': {
+    \                   'dynamicRegistration': v:false,
+    \                   'contentFormat': ['plaintext'],
+    \               },
+    \               'references': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \               'documentSymbol': {
+    \                   'dynamicRegistration': v:false,
+    \                   'hierarchicalDocumentSymbolSupport': v:false,
+    \               },
+    \               'definition': {
+    \                   'dynamicRegistration': v:false,
+    \                   'linkSupport': v:false,
+    \               },
+    \               'typeDefinition': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \               'publishDiagnostics': {
+    \                   'relatedInformation': v:true,
+    \               },
+    \               'codeAction': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \               'rename': {
+    \                   'dynamicRegistration': v:false,
+    \               },
+    \           },
+    \       },
+    \   ),
     \)
     let a:conn.init_request_id = l:init_id
     call s:SendMessageData(a:conn, l:init_data)
@@ -484,6 +546,35 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
     return l:opened
 endfunction
 
+" Notify LSP servers or tsserver that a document is closed, if opened before.
+" If a document is closed, 1 will be returned, otherwise 0 will be returned.
+"
+" Only the buffer number is required here. A message will be sent to every
+" language server that was notified previously of the document being opened.
+function! ale#lsp#CloseDocument(buffer) abort
+    let l:closed = 0
+
+    " The connection keys are sorted so the messages are easier to test, and
+    " so messages are sent in a consistent order.
+    for l:conn_id in sort(keys(s:connections))
+        let l:conn = s:connections[l:conn_id]
+
+        if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
+            if l:conn.is_tsserver
+                let l:message = ale#lsp#tsserver_message#Close(a:buffer)
+            else
+                let l:message = ale#lsp#message#DidClose(a:buffer)
+            endif
+
+            call ale#lsp#Send(l:conn_id, l:message)
+            call remove(l:conn.open_documents, a:buffer)
+            let l:closed = 1
+        endif
+    endfor
+
+    return l:closed
+endfunction
+
 " Notify LSP servers or tsserver that a document has changed, if needed.
 " If a notification is sent, 1 will be returned, otherwise 0 will be returned.
 function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
diff --git a/sources_non_forked/ale/autoload/ale/lsp/message.vim b/sources_non_forked/ale/autoload/ale/lsp/message.vim
index 4ad94c4b..b6b14a22 100644
--- a/sources_non_forked/ale/autoload/ale/lsp/message.vim
+++ b/sources_non_forked/ale/autoload/ale/lsp/message.vim
@@ -28,14 +28,13 @@ function! ale#lsp#message#GetNextVersionID() abort
     return l:id
 endfunction
 
-function! ale#lsp#message#Initialize(root_path, initialization_options) abort
-    " TODO: Define needed capabilities.
+function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
     " NOTE: rootPath is deprecated in favour of rootUri
     return [0, 'initialize', {
     \   'processId': getpid(),
     \   'rootPath': a:root_path,
-    \   'capabilities': {},
-    \   'initializationOptions': a:initialization_options,
+    \   'capabilities': a:capabilities,
+    \   'initializationOptions': a:options,
     \   'rootUri': ale#path#ToURI(a:root_path),
     \}]
 endfunction
diff --git a/sources_non_forked/ale/autoload/ale/lsp/response.vim b/sources_non_forked/ale/autoload/ale/lsp/response.vim
index 9ce05260..30da77e1 100644
--- a/sources_non_forked/ale/autoload/ale/lsp/response.vim
+++ b/sources_non_forked/ale/autoload/ale/lsp/response.vim
@@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
         \   'lnum': l:diagnostic.start.line,
         \   'col': l:diagnostic.start.offset,
         \   'end_lnum': l:diagnostic.end.line,
-        \   'end_col': l:diagnostic.end.offset,
+        \   'end_col': l:diagnostic.end.offset - 1,
         \}
 
         if has_key(l:diagnostic, 'code')
diff --git a/sources_non_forked/ale/autoload/ale/lsp_linter.vim b/sources_non_forked/ale/autoload/ale/lsp_linter.vim
index f70042dd..190a16b4 100644
--- a/sources_non_forked/ale/autoload/ale/lsp_linter.vim
+++ b/sources_non_forked/ale/autoload/ale/lsp_linter.vim
@@ -8,6 +8,9 @@ if !has_key(s:, 'lsp_linter_map')
     let s:lsp_linter_map = {}
 endif
 
+" A Dictionary to track one-shot handlers for custom LSP requests
+let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
+
 " Check if diagnostics for a particular linter should be ignored.
 function! s:ShouldIgnore(buffer, linter_name) abort
     " Ignore all diagnostics if LSP integration is disabled.
@@ -31,7 +34,7 @@ endfunction
 function! s:HandleLSPDiagnostics(conn_id, response) abort
     let l:linter_name = s:lsp_linter_map[a:conn_id]
     let l:filename = ale#path#FromURI(a:response.params.uri)
-    let l:buffer = bufnr(l:filename)
+    let l:buffer = bufnr('^' . l:filename . '$')
     let l:info = get(g:ale_buffer_info, l:buffer, {})
 
     if empty(l:info)
@@ -49,7 +52,7 @@ endfunction
 
 function! s:HandleTSServerDiagnostics(response, error_type) abort
     let l:linter_name = 'tsserver'
-    let l:buffer = bufnr(a:response.body.file)
+    let l:buffer = bufnr('^' . a:response.body.file . '$')
     let l:info = get(g:ale_buffer_info, l:buffer, {})
 
     if empty(l:info)
@@ -407,9 +410,57 @@ endfunction
 " Clear LSP linter data for the linting engine.
 function! ale#lsp_linter#ClearLSPData() abort
     let s:lsp_linter_map = {}
+    let s:custom_handlers_map = {}
 endfunction
 
 " Just for tests.
 function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
     let s:lsp_linter_map = a:replacement_map
 endfunction
+
+function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
+    if has_key(a:response, 'id')
+    \&& has_key(s:custom_handlers_map, a:response.id)
+        let l:Handler = remove(s:custom_handlers_map, a:response.id)
+        call l:Handler(a:response)
+    endif
+endfunction
+
+function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
+    let l:id = a:lsp_details.connection_id
+    let l:request_id = ale#lsp#Send(l:id, a:args.message)
+
+    if l:request_id > 0 && has_key(a:args, 'handler')
+        let l:Callback = function('s:HandleLSPResponseToCustomRequests')
+        call ale#lsp#RegisterCallback(l:id, l:Callback)
+        let s:custom_handlers_map[l:request_id] = a:args.handler
+    endif
+endfunction
+
+" Send a custom request to an LSP linter.
+function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
+    let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
+    let l:linter_list = ale#linter#GetAll(l:filetype)
+    let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
+
+    if len(l:linter_list) < 1
+        throw 'Linter "' . a:linter_name . '" not found!'
+    endif
+
+    let l:linter = l:linter_list[0]
+
+    if empty(l:linter.lsp)
+        throw 'Linter "' . a:linter_name . '" does not support LSP!'
+    endif
+
+    let l:is_notification = a:message[0]
+    let l:callback_args = {'message': a:message}
+
+    if !l:is_notification && a:0
+        let l:callback_args.handler = a:1
+    endif
+
+    let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
+
+    return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
+endfunction
diff --git a/sources_non_forked/ale/autoload/ale/path.vim b/sources_non_forked/ale/autoload/ale/path.vim
index 60d42eb5..84c26d0a 100644
--- a/sources_non_forked/ale/autoload/ale/path.vim
+++ b/sources_non_forked/ale/autoload/ale/path.vim
@@ -3,13 +3,20 @@
 
 " simplify a path, and fix annoying issues with paths on Windows.
 "
-" Forward slashes are changed to back slashes so path equality works better.
+" Forward slashes are changed to back slashes so path equality works better
+" on Windows. Back slashes are changed to forward slashes on Unix.
+"
+" Unix paths can technically contain back slashes, but in practice no path
+" should, and replacing back slashes with forward slashes makes linters work
+" in environments like MSYS.
 "
 " Paths starting with more than one forward slash are changed to only one
 " forward slash, to prevent the paths being treated as special MSYS paths.
 function! ale#path#Simplify(path) abort
     if has('unix')
-        return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks
+        let l:unix_path = substitute(a:path, '\\', '/', 'g')
+
+        return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
     endif
 
     let l:win_path = substitute(a:path, '/', '\\', 'g')
diff --git a/sources_non_forked/ale/autoload/ale/python.vim b/sources_non_forked/ale/autoload/ale/python.vim
index 2f28214b..7ed22367 100644
--- a/sources_non_forked/ale/autoload/ale/python.vim
+++ b/sources_non_forked/ale/autoload/ale/python.vim
@@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
         \|| filereadable(l:path . '/tox.ini')
         \|| filereadable(l:path . '/mypy.ini')
         \|| filereadable(l:path . '/pycodestyle.cfg')
-        \|| filereadable(l:path . '/flake8.cfg')
+        \|| filereadable(l:path . '/.flake8')
         \|| filereadable(l:path . '/.flake8rc')
         \|| filereadable(l:path . '/pylama.ini')
         \|| filereadable(l:path . '/pylintrc')
diff --git a/sources_non_forked/ale/autoload/ale/sign.vim b/sources_non_forked/ale/autoload/ale/sign.vim
index 7395b0e2..eb0dd1cd 100644
--- a/sources_non_forked/ale/autoload/ale/sign.vim
+++ b/sources_non_forked/ale/autoload/ale/sign.vim
@@ -82,6 +82,34 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
 \   . ' texthl=ALEInfoSign linehl=ALEInfoLine'
 sign define ALEDummySign
 
+if has('nvim-0.3.2')
+    if !hlexists('ALEErrorSignLineNr')
+        highlight link ALEErrorSignLineNr CursorLineNr
+    endif
+
+    if !hlexists('ALEStyleErrorSignLineNr')
+        highlight link ALEStyleErrorSignLineNr CursorLineNr
+    endif
+
+    if !hlexists('ALEWarningSignLineNr')
+        highlight link ALEWarningSignLineNr CursorLineNr
+    endif
+
+    if !hlexists('ALEStyleWarningSignLineNr')
+        highlight link ALEStyleWarningSignLineNr CursorLineNr
+    endif
+
+    if !hlexists('ALEInfoSignLineNr')
+        highlight link ALEInfoSignLineNr CursorLineNr
+    endif
+
+    sign define ALEErrorSign numhl=ALEErrorSignLineNr
+    sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr
+    sign define ALEWarningSign numhl=ALEWarningSignLineNr
+    sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr
+    sign define ALEInfoSign numhl=ALEInfoSignLineNr
+endif
+
 function! ale#sign#GetSignName(sublist) abort
     let l:priority = g:ale#util#style_warning_priority
 
diff --git a/sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim b/sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim
new file mode 100644
index 00000000..ce793773
--- /dev/null
+++ b/sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim
@@ -0,0 +1,26 @@
+function! asyncomplete#sources#ale#get_source_options(...) abort
+    let l:default = extend({
+    \     'name': 'ale',
+    \     'completor': function('asyncomplete#sources#ale#completor'),
+    \     'whitelist': ['*'],
+    \     'triggers': asyncomplete#sources#ale#get_triggers(),
+    \ }, a:0 >= 1 ? a:1 : {})
+
+    return extend(l:default, {'refresh_pattern': '\k\+$'})
+endfunction
+
+function! asyncomplete#sources#ale#get_triggers() abort
+    let l:triggers = ale#completion#GetAllTriggers()
+    let l:triggers['*'] = l:triggers['<default>']
+
+    return l:triggers
+endfunction
+
+function! asyncomplete#sources#ale#completor(options, context) abort
+    let l:keyword = matchstr(a:context.typed, '\w\+$')
+    let l:startcol = a:context.col - len(l:keyword)
+
+    call ale#completion#GetCompletions('ale-callback', { 'callback': {completions ->
+    \   asyncomplete#complete(a:options.name, a:context, l:startcol, completions)
+    \ }})
+endfunction
diff --git a/sources_non_forked/ale/doc/ale-ada.txt b/sources_non_forked/ale/doc/ale-ada.txt
index 93e3261a..2ac30c0a 100644
--- a/sources_non_forked/ale/doc/ale-ada.txt
+++ b/sources_non_forked/ale/doc/ale-ada.txt
@@ -21,5 +21,16 @@ g:ale_ada_gcc_options                                   *g:ale_ada_gcc_options*
   This variable can be set to pass additional options to gcc.
 
 
+===============================================================================
+gnatpp                                                         *ale-ada-gnatpp*
+
+g:ale_ada_gnatpp_options                             *g:ale_ada_gnatpp_options*
+                                                     *b:ale_ada_gnatpp_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be set to pass extra options to the gnatpp fixer.
+
+
 ===============================================================================
   vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale-c.txt b/sources_non_forked/ale/doc/ale-c.txt
index be0a3d77..c9eb79db 100644
--- a/sources_non_forked/ale/doc/ale-c.txt
+++ b/sources_non_forked/ale/doc/ale-c.txt
@@ -156,7 +156,7 @@ g:ale_c_clangtidy_options                           *g:ale_c_clangtidy_options*
   Type: |String|
   Default: `''`
 
-  This variable can be changed to modify flags given to clang-tidy.
+  This variable can be changed to modify compiler flags given to clang-tidy.
 
   - Setting this variable to a non-empty string,
   - and working in a buffer where no compilation database is found using
@@ -169,6 +169,23 @@ g:ale_c_clangtidy_options                           *g:ale_c_clangtidy_options*
   of the |g:ale_c_build_dir_names| directories of the project tree.
 
 
+g:ale_c_clangtidy_extra_options               *g:ale_c_clangtidy_extra_options*
+                                              *b:ale_c_clangtidy_extra_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be changed to modify flags given to clang-tidy.
+
+
+g:ale_c_clangtidy_fix_errors                     *g:ale_c_clangtidy_fix_errors*
+                                                 *b:ale_c_clangtidy_fix_errors*
+  Type: |Number|
+  Default: `1`
+
+  This variable can be changed to disable the `-fix-errors` option for the
+  |clangtidy| fixer.
+
+
 ===============================================================================
 cppcheck                                                       *ale-c-cppcheck*
 
diff --git a/sources_non_forked/ale/doc/ale-cpp.txt b/sources_non_forked/ale/doc/ale-cpp.txt
index e1f64ab5..ead3be28 100644
--- a/sources_non_forked/ale/doc/ale-cpp.txt
+++ b/sources_non_forked/ale/doc/ale-cpp.txt
@@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options                       *g:ale_cpp_clangtidy_options*
   Type: |String|
   Default: `''`
 
-  This variable can be changed to modify flags given to clang-tidy.
+  This variable can be changed to modify compiler flags given to clang-tidy.
 
   - Setting this variable to a non-empty string,
   - and working in a buffer where no compilation database is found using
@@ -138,6 +138,23 @@ g:ale_cpp_clangtidy_options                       *g:ale_cpp_clangtidy_options*
   of the |g:ale_c_build_dir_names| directories of the project tree.
 
 
+g:ale_cpp_clangtidy_extra_options           *g:ale_cpp_clangtidy_extra_options*
+                                            *b:ale_cpp_clangtidy_extra_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be changed to modify flags given to clang-tidy.
+
+
+g:ale_cpp_clangtidy_fix_errors                 *g:ale_cpp_clangtidy_fix_errors*
+                                               *b:ale_cpp_clangtidy_fix_errors*
+  Type: |Number|
+  Default: `1`
+
+  This variable can be changed to disable the `-fix-errors` option for the
+  |clangtidy| fixer.
+
+
 ===============================================================================
 clazy                                                           *ale-cpp-clazy*
 
diff --git a/sources_non_forked/ale/doc/ale-cs.txt b/sources_non_forked/ale/doc/ale-cs.txt
index 01e6348f..abcc43eb 100644
--- a/sources_non_forked/ale/doc/ale-cs.txt
+++ b/sources_non_forked/ale/doc/ale-cs.txt
@@ -6,11 +6,97 @@ In addition to the linters that are provided with ALE, C# code can be checked
 with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
 
 
+===============================================================================
+csc                                                                *ale-cs-csc*
+
+  The |ale-cs-csc| linter checks for semantic errors when files are opened or
+  saved.
+  
+  See |ale-lint-file-linters| for more information on linters which do not
+  check for problems while you type.
+
+  The csc linter uses the mono csc compiler providing full c# 7 and newer 
+  support to generate a temporary module target file (/t:module). The module
+  includes including all '*.cs' files  contained in the directory tree rooted
+  at the path defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source|
+  variabl and all sub directories.
+  
+  It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both
+  utilizer the mcsc compiler which according to mono porject ist further
+  developed and as of writint these lines only receives maintenance updates.
+  The down is that the csc compiler does not support the -sytax option any more
+  and therefore |ale-cs-csc| linter doese not offer any as you type syntax
+  checking like the |ale-cs-mcsc| linter doesn't.
+
+  The paths to search for additional assembly files can be specified using the
+  |g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables.
+
+  NOTE: ALE will not find any errors in files apart from syntax errors if any
+  one of the source files contains a syntax error. Syntax errors must be fixed
+  first before other errors will be shown.
+
+
+g:ale_cs_csc_options                                     *g:ale_cs_csc_options*
+                                                         *b:ale_cs_csc_options*
+  Type: |String|
+  Default: `''`
+
+  This option can be set to pass additional arguments to the `csc` compiler.
+
+  For example, to add the dotnet package which is not added per default: >
+
+      let g:ale_cs_mcs_options = ' /warn:4 /langversion:7.2'
+<
+  NOTE: the `/unsafe` option is always passed to `csc`.
+
+
+g:ale_cs_csc_source                                       *g:ale_cs_csc_source*
+                                                          *b:ale_cs_csc_source*
+  Type: |String|
+  Default: `''`
+
+  This variable defines the root path of the directory tree searched for the
+  '*.cs' files to be linted. If this option is empty, the source file's
+  directory will be used.
+
+  NOTE: Currently it is not possible to specify sub directories and
+  directory sub trees which shall not be searched for *.cs files.
+
+
+g:ale_cs_csc_assembly_path                         *g:ale_cs_csc_assembly_path*
+                                                   *b:ale_cs_csc_assembly_path*
+  Type: |List|
+  Default: `[]`
+
+  This variable defines a list of path strings to be searched for external
+  assembly files. The list is passed to the csc compiler using the `/lib:`
+  flag.
+
+
+g:ale_cs_csc_assemblies                               *g:ale_cs_csc_assemblies*
+                                                      *b:ale_cs_csc_assemblies*
+  Type: |List|
+  Default: `[]`
+
+  This variable defines a list of external assembly (*.dll) files required
+  by the mono mcs compiler to generate a valid module target. The list is
+  passed the csc compiler using the `/r:` flag.
+
+  For example: >
+
+    " Compile C# programs with the Unity engine DLL file on Mac.
+    let g:ale_cs_mcsc_assemblies = [
+    \ '/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll',
+    \ 'path-to-unityproject/obj/Debug',
+    \]
+<
+
 ===============================================================================
 mcs                                                                *ale-cs-mcs*
 
-  The `mcs` linter looks only for syntax errors while you type. See |ale-cs-mcsc|
-  for the separately configured linter for checking for semantic errors.
+  The `mcs` linter looks only for syntax errors while you type. See
+  |ale-cs-mcsc| for the separately configured linter for checking for semantic
+   errors.
 
 
 g:ale_cs_mcs_options                                     *g:ale_cs_mcs_options*
diff --git a/sources_non_forked/ale/doc/ale-development.txt b/sources_non_forked/ale/doc/ale-development.txt
index 9c9f0394..16b16483 100644
--- a/sources_non_forked/ale/doc/ale-development.txt
+++ b/sources_non_forked/ale/doc/ale-development.txt
@@ -151,9 +151,9 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
 runs tests with the following versions of Vim in the following environments.
 
 1. Vim 8.0.0027 on Linux via Travis CI.
-2. Vim 8.1.0204 on Linux via Travis CI.
+2. Vim 8.1.0519 on Linux via Travis CI.
 3. NeoVim 0.2.0 on Linux via Travis CI.
-4. NeoVim 0.3.0 on Linux via Travis CI.
+4. NeoVim 0.3.5 on Linux via Travis CI.
 5. Vim 8 (stable builds) on Windows via AppVeyor.
 
 If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
@@ -351,6 +351,7 @@ given the above setup are as follows.
 
 `GivenCommandOutput [...]`         - Define output for ale#command#Run.
 `AssertFixer results`              - Check the fixer results
+`AssertFixerNotExecuted`           - Check that fixers will not be executed.
 
 
 ===============================================================================
diff --git a/sources_non_forked/ale/doc/ale-elm.txt b/sources_non_forked/ale/doc/ale-elm.txt
index bb7a6132..823b53e1 100644
--- a/sources_non_forked/ale/doc/ale-elm.txt
+++ b/sources_non_forked/ale/doc/ale-elm.txt
@@ -29,20 +29,44 @@ g:ale_elm_format_options                             *g:ale_elm_format_options*
   This variable can be set to pass additional options to elm-format.
 
 ===============================================================================
-elm-lsp                                                       *ale-elm-elm-lsp*
+elm-ls                                                         *ale-elm-elm-ls*
 
-g:ale_elm_lsp_executable                             *g:ale_elm_lsp_executable*
-                                                     *b:ale_elm_lsp_executable*
+g:ale_elm_ls_executable                               *g:ale_elm_ls_executable*
+                                                      *b:ale_elm_ls_executable*
   Type: |String|
-  Default: `'elm-lsp'`
+  Default: `'elm-language-server'`
 
   See |ale-integrations-local-executables|
 
 
-g:ale_elm_lsp_use_global                             *g:ale_elm_lsp_use_global*
-                                                     *b:ale_elm_lsp_use_global*
+g:ale_elm_ls_use_global                               *g:ale_elm_ls_use_global*
+                                                      *b:ale_elm_ls_use_global*
   Type: |Number|
-  Default: `get(g:, 'ale_use_global_executables', 0)`
+  Default: `get(g:, 'ale_use_global_executables', 1)`
+
+  See |ale-integrations-local-executables|
+
+
+g:ale_elm_ls_elm_path                                   *g:ale_elm_ls_elm_path*
+                                                        *b:ale_elm_ls_elm_path*
+  Type: |String|
+  Default: `'elm'`
+
+  See |ale-integrations-local-executables|
+
+
+g:ale_elm_ls_elm_format_path                     *g:ale_elm_ls_elm_format_path*
+                                                 *b:ale_elm_ls_elm_format_path*
+  Type: |String|
+  Default: `'elm-format'`
+
+  See |ale-integrations-local-executables|
+
+
+g:ale_elm_ls_elm_test_path                         *g:ale_elm_ls_elm_test_path*
+                                                   *b:ale_elm_ls_elm_test_path*
+  Type: |String|
+  Default: `'elm-test'`
 
   See |ale-integrations-local-executables|
 
diff --git a/sources_non_forked/ale/doc/ale-erlang.txt b/sources_non_forked/ale/doc/ale-erlang.txt
index ad3c1e5a..59993a99 100644
--- a/sources_non_forked/ale/doc/ale-erlang.txt
+++ b/sources_non_forked/ale/doc/ale-erlang.txt
@@ -3,6 +3,35 @@ ALE Erlang Integration                                     *ale-erlang-options*
 
 
 ===============================================================================
+dialyzer                                                  *ale-erlang-dialyzer*
+
+g:ale_erlang_dialyzer_executable             *g:ale_erlang_dialyzer_executable*
+                                             *b:ale_erlang_dialyzer_executable*
+  Type: |String|
+  Default: `'dialyzer'`
+
+  This variable can be changed to specify the dialyzer executable.
+
+
+g:ale_erlang_dialyzer_plt_file                 *g:ale_erlang_dialyzer_plt_file*
+                                               *b:ale_erlang_dialyzer_plt_file*
+  Type: |String|
+
+  This variable can be changed to specify the path to the PLT file. By
+  default, it will search for the PLT file inside the `_build` directory. If
+  there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`.
+  Otherwise, it will default to `$HOME/.dialyzer_plt`.
+
+
+g:ale_erlang_dialyzer_rebar3_profile     *g:ale_erlang_dialyzer_rebar3_profile*
+                                         *b:ale_erlang_dialyzer_rebar3_profile*
+  Type: |String|
+  Default: `'default'`
+
+  This variable can be changed to specify the profile that is used to
+  run dialyzer with rebar3.
+
+-------------------------------------------------------------------------------
 erlc                                                          *ale-erlang-erlc*
 
 g:ale_erlang_erlc_options                           *g:ale_erlang_erlc_options*
diff --git a/sources_non_forked/ale/doc/ale-go.txt b/sources_non_forked/ale/doc/ale-go.txt
index 611e3fdd..be53783e 100644
--- a/sources_non_forked/ale/doc/ale-go.txt
+++ b/sources_non_forked/ale/doc/ale-go.txt
@@ -30,6 +30,16 @@ g:ale_go_go_executable                                    *g:ale_go_go_options*
   the `gomod` fixer.
 
 
+g:ale_go_go111module                                     *g:ale_go_go111module*
+                                                         *b:ale_go_go111module*
+  Type: |String|
+  Default: `''`
+
+  Override the value of the `$GO111MODULE` environment variable for
+  golang tools.
+
+
+
 ===============================================================================
 bingo                                                            *ale-go-bingo*
 
diff --git a/sources_non_forked/ale/doc/ale-handlebars.txt b/sources_non_forked/ale/doc/ale-handlebars.txt
index 061c5d3c..5daec5b3 100644
--- a/sources_non_forked/ale/doc/ale-handlebars.txt
+++ b/sources_non_forked/ale/doc/ale-handlebars.txt
@@ -2,6 +2,13 @@
 ALE Handlebars Integration                             *ale-handlebars-options*
 
 
+===============================================================================
+prettier                                              *ale-handlebars-prettier*
+
+See |ale-javascript-prettier| for information about the available options.
+Uses glimmer parser by default.
+
+
 ===============================================================================
 ember-template-lint                          *ale-handlebars-embertemplatelint*
 
diff --git a/sources_non_forked/ale/doc/ale-haskell.txt b/sources_non_forked/ale/doc/ale-haskell.txt
index e2073e37..5dd3ec15 100644
--- a/sources_non_forked/ale/doc/ale-haskell.txt
+++ b/sources_non_forked/ale/doc/ale-haskell.txt
@@ -12,6 +12,7 @@ g:ale_haskell_brittany_executable           *g:ale_haskell_brittany_executable*
 
   This variable can be changed to use a different executable for brittany.
 
+
 ===============================================================================
 floskell                                                 *ale-haskell-floskell*
 
@@ -22,6 +23,7 @@ g:ale_haskell_floskell_executable           *g:ale_haskell_floskell_executable*
 
   This variable can be changed to use a different executable for floskell.
 
+
 ===============================================================================
 ghc                                                           *ale-haskell-ghc*
 
@@ -32,6 +34,7 @@ g:ale_haskell_ghc_options                           *g:ale_haskell_ghc_options*
 
   This variable can be changed to modify flags given to ghc.
 
+
 ===============================================================================
 ghc-mod                                                   *ale-haskell-ghc-mod*
 
@@ -42,6 +45,7 @@ g:ale_haskell_ghc_mod_executable             *g:ale_haskell_ghc_mod_executable*
 
   This variable can be changed to use a different executable for ghc-mod.
 
+
 ===============================================================================
 cabal-ghc                                               *ale-haskell-cabal-ghc*
 
@@ -53,6 +57,7 @@ g:ale_haskell_cabal_ghc_options               *g:ale_haskell_cabal_ghc_options*
   This variable can be changed to modify flags given to ghc through cabal
   exec.
 
+
 ===============================================================================
 hdevtools                                               *ale-haskell-hdevtools*
 
@@ -87,6 +92,18 @@ g:ale_haskell_hfmt_executable                   *g:ale_haskell_hfmt_executable*
 
   This variable can be changed to use a different executable for hfmt.
 
+
+===============================================================================
+hindent                                                   *ale-haskell-hindent*
+
+g:ale_haskell_hindent_executable             *g:ale_haskell_hindent_executable*
+                                             *b:ale_haskell_hindent_executable*
+  Type: |String|
+  Default: `'hindent'`
+
+  This variable can be changed to use a different executable for hindent.
+
+
 ===============================================================================
 hlint                                                       *ale-haskell-hlint*
 
@@ -106,6 +123,7 @@ g:ale_haskell_hlint_options                       g:ale_haskell_hlint_options
   This variable can be used to pass extra options to the underlying hlint
   executable.
 
+
 ===============================================================================
 stack-build                                           *ale-haskell-stack-build*
 
@@ -117,6 +135,7 @@ g:ale_haskell_stack_build_options           *g:ale_haskell_stack_build_options*
   We default to using `'--fast'`. Since Stack generates binaries, your
   programs will be slower unless you separately rebuild them outside of ALE.
 
+
 ===============================================================================
 stack-ghc                                               *ale-haskell-stack-ghc*
 
@@ -128,6 +147,7 @@ g:ale_haskell_stack_ghc_options               *g:ale_haskell_stack_ghc_options*
   This variable can be changed to modify flags given to ghc through `stack
   ghc`
 
+
 ===============================================================================
 stylish-haskell                                   *ale-haskell-stylish-haskell*
 
@@ -139,6 +159,7 @@ g:ale_haskell_stylish_haskell_executable
 
   This variable can be changed to use a different executable for stylish-haskell.
 
+
 ===============================================================================
 hie                                                           *ale-haskell-hie*
 
@@ -150,5 +171,6 @@ g:ale_haskell_hie_executable                     *g:ale_haskell_hie_executable*
   This variable can be changed to use a different executable for the haskell
   ide engine. i.e. `'hie-wrapper'`
 
+
 ===============================================================================
   vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale-hcl.txt b/sources_non_forked/ale/doc/ale-hcl.txt
index 8060ac44..59b0a9da 100644
--- a/sources_non_forked/ale/doc/ale-hcl.txt
+++ b/sources_non_forked/ale/doc/ale-hcl.txt
@@ -5,7 +5,7 @@ ALE HCL Integration                                           *ale-hcl-options*
 ===============================================================================
 terraform-fmt                                           *ale-hcl-terraform-fmt*
 
-See |ale-terraform-fmt| for information about the available options.
+See |ale-terraform-fmt-fixer| for information about the available options.
 
 ===============================================================================
   vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale-java.txt b/sources_non_forked/ale/doc/ale-java.txt
index 2805c9c8..32f0e6eb 100644
--- a/sources_non_forked/ale/doc/ale-java.txt
+++ b/sources_non_forked/ale/doc/ale-java.txt
@@ -5,14 +5,41 @@ ALE Java Integration                                         *ale-java-options*
 ===============================================================================
 checkstyle                                                *ale-java-checkstyle*
 
+g:ale_java_checkstyle_config                     *g:ale_java_checkstyle_config*
+                                                 *b:ale_java_checkstyle_config*
+
+  Type: |String|
+  Default: `'/google_checks.xml'`
+
+  A path to a checkstyle configuration file.
+
+  If a configuration file is specified with |g:ale_java_checkstyle_options|,
+  it will be preferred over this setting.
+
+  The path to the configuration file can be an absolute path or a relative
+  path. ALE will search for the relative path in parent directories.
+
+
+g:ale_java_checkstyle_executable             *g:ale_java_checkstyle_executable*
+                                             *b:ale_java_checkstyle_executable*
+
+  Type: |String|
+  Default: 'checkstyle'
+
+  This variable can be changed to modify the executable used for checkstyle.
+
+
 g:ale_java_checkstyle_options                   *g:ale_java_checkstyle_options*
                                                 *b:ale_java_checkstyle_options*
 
-  Type: String
-  Default: '-c /google_checks.xml'
+  Type: |String|
+  Default: `''`
 
   This variable can be changed to modify flags given to checkstyle.
 
+  If a configuration file is specified with `-c`, it will be used instead of
+  configuration files set with |g:ale_java_checkstyle_config|.
+
 
 ===============================================================================
 javac                                                          *ale-java-javac*
@@ -90,16 +117,46 @@ or
 
 This generates a dist/mac or dist/windows directory that contains the
 language server. To let ALE use this language server you need to set the
-g:ale_java_javalsp_executable variable to the absolute path of the java
+g:ale_java_javalsp_executable variable to the absolute path of the launcher
 executable in this directory.
 
 g:ale_java_javalsp_executable                   *g:ale_java_javalsp_executable*
                                                 *b:ale_java_javalsp_executable*
   Type: |String|
-  Default: `'java'`
+  Default: `''`
 
-This variable can be changed to use a different executable for java.
+This variable must be set to the absolute path of the language server launcher
+executable. For example:
+>
+  let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
+<
 
+g:ale_java_javalsp_config                           *g:ale_java_javalsp_config*
+                                                    *b:ale_java_javalsp_config*
+  Type: |Dictionary|
+  Default: `{}`
+
+The javalsp linter automatically detects external depenencies for Maven and
+Gradle projects. In case the javalsp fails to detect some of them, you can
+specify them setting a dictionary to |g:ale_java_javalsp_config| variable.
+>
+  let g:ale_java_javalsp_executable =
+  \ {
+  \   'java': {
+  \     'externalDependencies': [
+  \       'junit:junit:jar:4.12:test',   " Maven format
+  \       'junit:junit:4.1'              " Gradle format
+  \     ],
+  \     'classPath': [
+  \       'lib/some-dependency.jar',
+  \       '/android-sdk/platforms/android-28.jar'
+  \     ]
+  \   }
+  \ }
+
+The Java language server will look for the dependencies you specify in
+`externalDependencies` array in your Maven and Gradle caches ~/.m2 and
+~/.gradle.
 
 ===============================================================================
 eclipselsp                                                *ale-java-eclipselsp*
@@ -118,7 +175,7 @@ located inside the repository folder `eclipse.jdt.ls`. Please ensure to set
 |g:ale_java_eclipselsp_path| to the absolute path of that folder.
 
 You could customize compiler options and code assists of the server.
-Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs` 
+Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs`
 with options presented at
 https://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/JavaCore.html.
 
@@ -130,7 +187,7 @@ g:ale_java_eclipselsp_path                         *g:ale_java_eclipselsp_path*
 
   Absolute path to the location of the eclipse.jdt.ls repository folder. Or if
   you have VSCode extension installed the absolute path to the VSCode extensions
-  folder (e.g. $HOME/.vscode/extensions in Linux).
+  folder (e.g. $HOME/.vscode/extensions/redhat.java-0.4x.0 in Linux).
 
 
 g:ale_java_eclipselsp_executable                *g:ale_java_eclipse_executable*
@@ -141,6 +198,31 @@ g:ale_java_eclipselsp_executable                *g:ale_java_eclipse_executable*
   This variable can be set to change the executable path used for java.
 
 
+g:ale_java_eclipselsp_config_path              *g:ale_java_eclipse_config_path*
+                                               *b:ale_java_eclipse_config_path*
+  Type: |String|
+  Default: `''`
+
+  Set this variable to change the configuration directory path used by
+  eclipselsp (e.g. `$HOME/.jdtls` in Linux).
+  By default ALE will attempt to use the configuration within the installation
+  directory.
+  This setting is particularly useful when eclipselsp is installed in a
+  non-writable directory like `/usr/share/java/jdtls`, as is the case when
+  installed via system package.
+
+
+g:ale_java_eclipselsp_workspace_path     *g:ale_java_eclipselsp_workspace_path*
+                                         *b:ale_java_eclipselsp_workspace_path*
+
+  Type: |String|
+  Default: `''`
+
+  If you have Eclipse installed is good idea to set this variable to the
+  absolute path of the Eclipse workspace. If not set this value will be set to
+  the parent folder of the project root.
+
+
 ===============================================================================
 uncrustify                                                *ale-java-uncrustify*
 
diff --git a/sources_non_forked/ale/doc/ale-purescript.txt b/sources_non_forked/ale/doc/ale-purescript.txt
new file mode 100644
index 00000000..33fd2429
--- /dev/null
+++ b/sources_non_forked/ale/doc/ale-purescript.txt
@@ -0,0 +1,33 @@
+===============================================================================
+ALE PureScript Integration                             *ale-purescript-options*
+
+
+===============================================================================
+purescript-language-server                     *ale-purescript-language-server*
+
+PureScript Language Server
+  (https://github.com/nwolverson/purescript-language-server)
+
+g:ale_purescript_ls_executable                 g:ale_purescript_ls_executable
+                                               b:ale_purescript_ls_executable
+  Type: |String|
+  Default: `'purescript-language-server'`
+
+  PureScript language server executable.
+
+g:ale_purescript_ls_config                         g:ale_purescript_ls_config
+                                                   b:ale_purescript_ls_config
+  Type: |Dictionary|
+  Default: `{}`
+
+  Dictionary containing configuration settings that will be passed to the
+  language server. For example, with a spago project:
+		{
+		\  'purescript': {
+		\    'addSpagoSources': v:true,
+		\    'addNpmPath': v:true,
+		\    'buildCommand': 'spago build -- --json-errors'
+		\  }
+		\}
+===============================================================================
+  vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale-python.txt b/sources_non_forked/ale/doc/ale-python.txt
index 7dd3b65d..9d5846d2 100644
--- a/sources_non_forked/ale/doc/ale-python.txt
+++ b/sources_non_forked/ale/doc/ale-python.txt
@@ -29,7 +29,7 @@ ALE will look for configuration files with the following filenames. >
   tox.ini
   mypy.ini
   pycodestyle.cfg
-  flake8.cfg
+  .flake8
   .flake8rc
   pylama.ini
   pylintrc
@@ -672,6 +672,36 @@ g:ale_python_pyre_auto_pipenv                   *g:ale_python_pyre_auto_pipenv*
   if true. This is overridden by a manually-set executable.
 
 
+===============================================================================
+reorder-python-imports                      *ale-python-reorder_python_imports*
+
+g:ale_python_reorder_python_imports_executable
+                               *g:ale_python_reorder_python_imports_executable*
+                               *b:ale_python_reorder_python_imports_executable*
+  Type: |String|
+  Default: `'reorder-python-imports'`
+
+  See |ale-integrations-local-executables|
+
+
+g:ale_python_reorder_python_imports_options
+                                  *g:ale_python_reorder_python_imports_options*
+                                  *b:ale_python_reorder_python_imports_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be set to pass extra options to reorder-python-imports.
+
+
+g:ale_python_reorder_python_imports_use_global
+                               *g:ale_python_reorder_python_imports_use_global*
+                               *b:ale_python_reorder_python_imports_use_global*
+  Type: |Number|
+  Default: `get(g:, 'ale_use_global_executables', 0)`
+
+  See |ale-integrations-local-executables|
+
+
 ===============================================================================
 vulture                                                    *ale-python-vulture*
 
diff --git a/sources_non_forked/ale/doc/ale-reasonml.txt b/sources_non_forked/ale/doc/ale-reasonml.txt
index 426d4c46..b8729a55 100644
--- a/sources_non_forked/ale/doc/ale-reasonml.txt
+++ b/sources_non_forked/ale/doc/ale-reasonml.txt
@@ -5,18 +5,19 @@ ALE ReasonML Integration                                 *ale-reasonml-options*
 ===============================================================================
 merlin                                                    *ale-reasonml-merlin*
 
-  To use merlin linter for ReasonML source code you need to make sure Merlin
-  for Vim is correctly configured. See the corresponding Merlin wiki page for
-  detailed instructions
-  (https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch).
+To use merlin linter for ReasonML source code you need to make sure Merlin for
+Vim is correctly configured. See the corresponding Merlin wiki page for
+detailed instructions:
+https://github.com/the-lambda-church/merlin/wiki/vim-from-scratch
 
 ===============================================================================
 ols                                                          *ale-reasonml-ols*
 
-  The `ocaml-language-server` is the engine that powers OCaml and ReasonML
-  editor support using the Language Server Protocol. See the installation
-  instructions:
-  https://github.com/freebroccolo/ocaml-language-server#installation
+The `ocaml-language-server` is the engine that powers OCaml and ReasonML
+editor support using the Language Server Protocol. See the installation
+instructions:
+https://github.com/freebroccolo/ocaml-language-server#installation
+
 
 g:ale_reason_ols_executable                       *g:ale_reason_ols_executable*
                                                   *b:ale_reason_ols_executable*
@@ -25,6 +26,7 @@ g:ale_reason_ols_executable                       *g:ale_reason_ols_executable*
 
   This variable can be set to change the executable path for `ols`.
 
+
 g:ale_reason_ols_use_global                       *g:ale_reason_ols_use_global*
                                                   *b:ale_reason_ols_use_global*
   Type: |String|
@@ -33,6 +35,24 @@ g:ale_reason_ols_use_global                       *g:ale_reason_ols_use_global*
   This variable can be set to `1` to always use the globally installed
   executable. See also |ale-integrations-local-executables|.
 
+
+===============================================================================
+reason-language-server                           *ale-reasonml-language-server*
+
+Note: You must set an executable - there is no 'default' install location.
+Go to https://github.com/jaredly/reason-language-server and download the
+latest release. You can place it anywhere, but ensure you set the executable
+path.
+
+
+g:ale_reason_ls_executable                         *g:ale_reason_ls_executable*
+                                                   *b:ale_reason_ls_executable*
+  Type: |String|
+
+  This variable defines the standard location of the language server
+  executable. This must be set.
+
+
 ===============================================================================
 refmt                                                      *ale-reasonml-refmt*
 
@@ -43,6 +63,7 @@ g:ale_reasonml_refmt_executable               *g:ale_reasonml_refmt_executable*
 
   This variable can be set to pass the path of the refmt fixer.
 
+
 g:ale_reasonml_refmt_options                     *g:ale_reasonml_refmt_options*
                                                  *b:ale_reasonml_refmt_options*
   Type: |String|
@@ -50,5 +71,6 @@ g:ale_reasonml_refmt_options                     *g:ale_reasonml_refmt_options*
 
   This variable can be set to pass additional options to the refmt fixer.
 
+
 ===============================================================================
   vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale-ruby.txt b/sources_non_forked/ale/doc/ale-ruby.txt
index bf971e7c..e373ab8e 100644
--- a/sources_non_forked/ale/doc/ale-ruby.txt
+++ b/sources_non_forked/ale/doc/ale-ruby.txt
@@ -129,6 +129,26 @@ g:ale_ruby_solargraph_executable             *g:ale_ruby_solargraph_executable*
   from binstubs or a bundle.
 
 
+===============================================================================
+sorbet                                                        *ale-ruby-sorbet*
+
+g:ale_ruby_sorbet_executable                     *g:ale_ruby_sorbet_executable*
+                                                 *b:ale_ruby_sorbet_executable*
+  Type: String
+  Default: `'srb'`
+
+  Override the invoked sorbet binary. Set this to `'bundle'` to invoke
+  `'bundle` `exec` srb'.
+
+
+g:ale_ruby_sorbet_options                           *g:ale_ruby_sorbet_options*
+                                                    *b:ale_ruby_sorbet_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be change to modify flags given to sorbet.
+
+
 ===============================================================================
 standardrb                                                *ale-ruby-standardrb*
 
diff --git a/sources_non_forked/ale/doc/ale-sql.txt b/sources_non_forked/ale/doc/ale-sql.txt
index 75d4b0cf..f9bc6ac2 100644
--- a/sources_non_forked/ale/doc/ale-sql.txt
+++ b/sources_non_forked/ale/doc/ale-sql.txt
@@ -2,6 +2,24 @@
 ALE SQL Integration                                           *ale-sql-options*
 
 
+===============================================================================
+pgformatter                                                 *ale-sql-pgformatter*
+
+g:ale_sql_pgformatter_executable             *g:ale_sql_pgformatter_executable*
+                                             *b:ale_sql_pgformatter_executable*
+  Type: |String|
+  Default: `'pg_format'`
+
+  This variable sets executable used for pgformatter.
+
+g:ale_sql_pgformatter_options                   *g:ale_sql_pgformatter_options*
+                                                *b:ale_sql_pgformatter_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be set to pass additional options to the pgformatter fixer.
+
+
 ===============================================================================
 sqlfmt                                                         *ale-sql-sqlfmt*
 
diff --git a/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt b/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt
index d6fbafa6..37345f7b 100644
--- a/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt
+++ b/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt
@@ -14,6 +14,7 @@ Notes:
 
 * Ada
   * `gcc`
+  * `gnatpp`
 * Ansible
   * `ansible-lint`
 * API Blueprint
@@ -53,6 +54,7 @@ Notes:
   * `gcc`
   * `uncrustify`
 * C#
+  * `csc`!!
   * `mcs`
   * `mcsc`!!
   * `uncrustify`
@@ -181,6 +183,7 @@ Notes:
   * `hdevtools`
   * `hfmt`
   * `hie`
+  * `hindent`
   * `hlint`
   * `stack-build`!!
   * `stack-ghc`
@@ -236,6 +239,7 @@ Notes:
   * `lacheck`
   * `proselint`
   * `redpen`
+  * `texlab`
   * `textlint`
   * `vale`
   * `write-good`
@@ -337,6 +341,8 @@ Notes:
   * `languageserver`
   * `puppet`
   * `puppet-lint`
+* PureScript
+  * `purescript-language-server`
 * Python
   * `autopep8`
   * `bandit`
@@ -352,6 +358,7 @@ Notes:
   * `pylint`!!
   * `pyls`
   * `pyre`
+  * `reorder-python-imports`
   * `vulture`!!
   * `yapf`
 * QML
@@ -365,6 +372,7 @@ Notes:
 * ReasonML
   * `merlin`
   * `ols`
+  * `reason-language-server`
   * `refmt`
 * reStructuredText
   * `alex`!!
@@ -386,6 +394,7 @@ Notes:
   * `ruby`
   * `rufo`
   * `solargraph`
+  * `sorbet`
   * `standardrb`
 * Rust
   * `cargo`!!
@@ -414,6 +423,7 @@ Notes:
   * `solhint`
   * `solium`
 * SQL
+  * `pgformatter`
   * `sqlfmt`
   * `sqlint`
 * Stylus
diff --git a/sources_non_forked/ale/doc/ale-terraform.txt b/sources_non_forked/ale/doc/ale-terraform.txt
index 49a55028..387fd732 100644
--- a/sources_non_forked/ale/doc/ale-terraform.txt
+++ b/sources_non_forked/ale/doc/ale-terraform.txt
@@ -3,7 +3,7 @@ ALE Terraform Integration                               *ale-terraform-options*
 
 
 ===============================================================================
-fmt                                                         *ale-terraform-fmt*
+terraform-fmt-fixer                                   *ale-terraform-fmt-fixer*
 
 g:ale_terraform_fmt_executable                 *g:ale_terraform_fmt_executable*
                                                *b:ale_terraform_fmt_executable*
@@ -20,6 +20,18 @@ g:ale_terraform_fmt_options                       *g:ale_terraform_fmt_options*
   Default: `''`
 
 
+===============================================================================
+terraform                                             *ale-terraform-terraform*
+
+g:ale_terraform_terraform_executable     *g:ale_terraform_terraform_executable*
+                                         *b:ale_terraform_terraform_executable*
+
+  Type: |String|
+  Default: `'terraform'`
+
+  This variable can be changed to use a different executable for terraform.
+
+
 ===============================================================================
 tflint                                                   *ale-terraform-tflint*
 
diff --git a/sources_non_forked/ale/doc/ale-tex.txt b/sources_non_forked/ale/doc/ale-tex.txt
index b1b09117..ceb9fa81 100644
--- a/sources_non_forked/ale/doc/ale-tex.txt
+++ b/sources_non_forked/ale/doc/ale-tex.txt
@@ -53,5 +53,25 @@ g:ale_tex_latexindent_options                   *g:ale_tex_latexindent_options*
 
 
 
+===============================================================================
+texlab                                                          *ale-tex-texlab*
+
+g:ale_tex_texlab_executable                        *g:ale_tex_texlab_executable*
+                                                   *b:ale_tex_texlab_executable*
+  Type: |String|
+  Default: `'texlab'`
+
+  This variable can be changed to change the path to texlab.
+
+
+g:ale_tex_texlab_options                              *g:ale_tex_texlab_options*
+                                                      *b:ale_tex_texlab_options*
+  Type: |String|
+  Default: `''`
+
+  This variable can be changed to modify flags given to texlab.
+
+
+
 ===============================================================================
   vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/sources_non_forked/ale/doc/ale.txt b/sources_non_forked/ale/doc/ale.txt
index 2a086981..beca8546 100644
--- a/sources_non_forked/ale/doc/ale.txt
+++ b/sources_non_forked/ale/doc/ale.txt
@@ -84,7 +84,7 @@ have even saved your changes. ALE will check your code in the following
 circumstances, which can be configured with the associated options.
 
 * When you modify a buffer.                - |g:ale_lint_on_text_changed|
-* On leaving insert mode. (off by default) - |g:ale_lint_on_insert_leave|
+* On leaving insert mode.                  - |g:ale_lint_on_insert_leave|
 * When you open a new or modified buffer.  - |g:ale_lint_on_enter|
 * When you save a buffer.                  - |g:ale_lint_on_save|
 * When the filetype changes for a buffer.  - |g:ale_lint_on_filetype_changed|
@@ -341,6 +341,17 @@ completion source for Deoplete is named `'ale'`, and should enabled
 automatically if Deoplete is enabled and configured correctly. Deoplete
 integration should not be combined with ALE's own implementation.
 
+                                                 *ale-asyncomplete-integration*
+
+ALE additionally integrates with asyncomplete.vim for offering automatic
+completion data. ALE's asyncomplete source requires registration and should
+use the defaults provided by the|asyncomplete#sources#ale#get_source_options| function >
+
+  " Use ALE's function for asyncomplete defaults
+  au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#ale#get_source_options({
+      \ 'priority': 10, " Provide your own overrides here
+      \ }))
+>
 ALE also offers its own completion implementation, which does not require any
 other plugins. Suggestions will be made while you type after completion is
 enabled. ALE's own completion implementation can be enabled by setting
@@ -349,6 +360,12 @@ is loaded. The delay for completion can be configured with
 |g:ale_completion_delay|. This setting should not be enabled if you wish to
 use ALE as a completion source for other plugins.
 
+ALE provides an 'omnifunc' function |ale#completion#OmniFunc| for triggering
+completion manually with CTRL-X CTRL-O. |i_CTRL-X_CTRL-O| >
+
+  " Use ALE's function for omnicompletion.
+  set omnifunc=ale#completion#OmniFunc
+<
 ALE will only suggest so many possible matches for completion. The maximum
 number of items can be controlled with |g:ale_completion_max_suggestions|.
 
@@ -947,7 +964,7 @@ g:ale_lint_on_save                                         *g:ale_lint_on_save*
 g:ale_lint_on_text_changed                         *g:ale_lint_on_text_changed*
 
   Type: |String|
-  Default: `'always'`
+  Default: `'normal'`
 
   This option controls how ALE will check your files as you make changes.
   The following values can be used.
@@ -972,9 +989,10 @@ g:ale_lint_on_text_changed                         *g:ale_lint_on_text_changed*
 
 
 g:ale_lint_on_insert_leave                         *g:ale_lint_on_insert_leave*
+                                                   *b:ale_lint_on_insert_leave*
 
   Type: |Number|
-  Default: `0`
+  Default: `1`
 
   When set to `1` in your vimrc file, this option will cause ALE to run
   linters when you leave insert mode.
@@ -986,6 +1004,10 @@ g:ale_lint_on_insert_leave                         *g:ale_lint_on_insert_leave*
     " Make using Ctrl+C do the same as Escape, to trigger autocmd commands
     inoremap <C-c> <Esc>
 <
+  A buffer-local version of this setting `b:ale_lint_on_insert_leave` can be
+  set to `0` to disable linting when leaving insert mode. The setting must
+  be enabled globally to be enabled locally.
+
   You should set this setting once before ALE is loaded, and restart Vim if
   you want to change your preferences. See |ale-lint-settings-on-startup|.
 
@@ -1006,10 +1028,13 @@ g:ale_linter_aliases                                     *g:ale_linter_aliases*
   \   'Dockerfile': 'dockerfile',
   \   'csh': 'sh',
   \   'plaintex': 'tex',
+  \   'rmarkdown': 'r',
   \   'systemverilog': 'verilog',
   \   'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
   \   'vimwiki': 'markdown',
   \   'vue': ['vue', 'javascript'],
+  \   'xsd': ['xsd', 'xml'],
+  \   'xslt': ['xslt', 'xml'],
   \   'zsh': 'sh',
   \}
 <
@@ -1412,6 +1437,15 @@ g:ale_set_signs                                               *g:ale_set_signs*
   |ALEWarningLine| - All items with `'type': 'W'`
   |ALEInfoLine|    - All items with `'type': 'I'`
 
+  With Neovim 0.3.2 or higher, ALE uses `numhl` option to highlight 'number'
+  column. It uses the following highlight groups.
+
+  |ALEErrorSignLineNr|        - Items with `'type': 'E'`
+  |ALEWarningSignLineNr|      - Items with `'type': 'W'`
+  |ALEInfoSignLineNr|         - Items with `'type': 'I'`
+  |ALEStyleErrorSignLineNr|   - Items with `'type': 'E'` and `'sub_type': 'style'`
+  |ALEStyleWarningSignLineNr| - Items with `'type': 'W'` and `'sub_type': 'style'`
+
   The markers for the highlights can be customized with the following options:
 
   |g:ale_sign_error|
@@ -1696,6 +1730,15 @@ ALEErrorSign                                                     *ALEErrorSign*
   The highlight for error signs. See |g:ale_set_signs|.
 
 
+ALEErrorSignLineNr                                         *ALEErrorSignLineNr*
+
+  Default: `highlight link ALEErrorSignLineNr CursorLineNr`
+
+  The highlight for error signs. See |g:ale_set_signs|.
+
+  NOTE: This highlight is only available on Neovim 0.3.2 or higher.
+
+
 ALEInfo                                                              *ALEInfo.*
                                                             *ALEInfo-highlight*
   Default: `highlight link ALEInfo ALEWarning`
@@ -1720,6 +1763,15 @@ ALEInfoLine                                                       *ALEInfoLine*
   See |g:ale_set_signs| and |g:ale_set_highlights|.
 
 
+ALEInfoSignLineNr                                           *ALEInfoSignLineNr*
+
+  Default: `highlight link ALEInfoSignLineNr CursorLineNr`
+
+  The highlight for error signs. See |g:ale_set_signs|.
+
+  NOTE: This highlight is only available on Neovim 0.3.2 or higher.
+
+
 ALEStyleError                                                   *ALEStyleError*
 
   Default: `highlight link ALEStyleError ALEError`
@@ -1734,6 +1786,15 @@ ALEStyleErrorSign                                           *ALEStyleErrorSign*
   The highlight for style error signs. See |g:ale_set_signs|.
 
 
+ALEStyleErrorSignLineNr                               *ALEStyleErrorSignLineNr*
+
+  Default: `highlight link ALEStyleErrorSignLineNr CursorLineNr`
+
+  The highlight for error signs. See |g:ale_set_signs|.
+
+  NOTE: This highlight is only available on Neovim 0.3.2 or higher.
+
+
 ALEStyleWarning                                               *ALEStyleWarning*
 
   Default: `highlight link ALEStyleWarning ALEError`
@@ -1748,6 +1809,15 @@ ALEStyleWarningSign                                       *ALEStyleWarningSign*
   The highlight for style warning signs. See |g:ale_set_signs|.
 
 
+ALEStyleWarningSignLineNr                           *ALEStyleWarningSignLineNr*
+
+  Default: `highlight link ALEStyleWarningSignLineNr CursorLineNr`
+
+  The highlight for error signs. See |g:ale_set_signs|.
+
+  NOTE: This highlight is only available on Neovim 0.3.2 or higher.
+
+
 ALEVirtualTextError                                       *ALEVirtualTextError*
 
   Default: `highlight link ALEVirtualTextError ALEError`
@@ -1807,6 +1877,15 @@ ALEWarningSign                                                 *ALEWarningSign*
   The highlight for warning signs. See |g:ale_set_signs|.
 
 
+ALEWarningSignLineNr                                     *ALEWarningSignLineNr*
+
+  Default: `highlight link ALEWarningSignLineNr CursorLineNr`
+
+  The highlight for error signs. See |g:ale_set_signs|.
+
+  NOTE: This highlight is only available on Neovim 0.3.2 or higher.
+
+
 ===============================================================================
 7. Linter/Fixer Options                               *ale-integration-options*
 
@@ -1913,6 +1992,7 @@ documented in additional help files.
 
   ada.....................................|ale-ada-options|
     gcc...................................|ale-ada-gcc|
+    gnatpp................................|ale-ada-gnatpp|
   ansible.................................|ale-ansible-options|
     ansible-lint..........................|ale-ansible-ansible-lint|
   asciidoc................................|ale-asciidoc-options|
@@ -1961,6 +2041,7 @@ documented in additional help files.
     uncrustify............................|ale-cpp-uncrustify|
     ccls..................................|ale-cpp-ccls|
   c#......................................|ale-cs-options|
+    csc...................................|ale-cs-csc|
     mcs...................................|ale-cs-mcs|
     mcsc..................................|ale-cs-mcsc|
     uncrustify............................|ale-cs-uncrustify|
@@ -1988,9 +2069,10 @@ documented in additional help files.
     credo.................................|ale-elixir-credo|
   elm.....................................|ale-elm-options|
     elm-format............................|ale-elm-elm-format|
-    elm-lsp...............................|ale-elm-elm-lsp|
+    elm-ls................................|ale-elm-elm-ls|
     elm-make..............................|ale-elm-elm-make|
   erlang..................................|ale-erlang-options|
+    dialyzer..............................|ale-erlang-dialyzer|
     erlc..................................|ale-erlang-erlc|
     syntaxerl.............................|ale-erlang-syntaxerl|
   eruby...................................|ale-eruby-options|
@@ -2027,6 +2109,7 @@ documented in additional help files.
     hackfmt...............................|ale-hack-hackfmt|
     hhast.................................|ale-hack-hhast|
   handlebars..............................|ale-handlebars-options|
+    prettier..............................|ale-handlebars-prettier|
     ember-template-lint...................|ale-handlebars-embertemplatelint|
   haskell.................................|ale-haskell-options|
     brittany..............................|ale-haskell-brittany|
@@ -2036,6 +2119,7 @@ documented in additional help files.
     cabal-ghc.............................|ale-haskell-cabal-ghc|
     hdevtools.............................|ale-haskell-hdevtools|
     hfmt..................................|ale-haskell-hfmt|
+    hindent...............................|ale-haskell-hindent|
     hlint.................................|ale-haskell-hlint|
     stack-build...........................|ale-haskell-stack-build|
     stack-ghc.............................|ale-haskell-stack-ghc|
@@ -2160,6 +2244,8 @@ documented in additional help files.
     puppet................................|ale-puppet-puppet|
     puppetlint............................|ale-puppet-puppetlint|
     puppet-languageserver.................|ale-puppet-languageserver|
+  purescript..............................|ale-purescript-options|
+    purescript-language-server............|ale-purescript-language-server|
   pyrex (cython)..........................|ale-pyrex-options|
     cython................................|ale-pyrex-cython|
   python..................................|ale-python-options|
@@ -2177,6 +2263,7 @@ documented in additional help files.
     pylint................................|ale-python-pylint|
     pyls..................................|ale-python-pyls|
     pyre..................................|ale-python-pyre|
+    reorder-python-imports................|ale-python-reorder_python_imports|
     vulture...............................|ale-python-vulture|
     yapf..................................|ale-python-yapf|
   qml.....................................|ale-qml-options|
@@ -2187,6 +2274,7 @@ documented in additional help files.
   reasonml................................|ale-reasonml-options|
     merlin................................|ale-reasonml-merlin|
     ols...................................|ale-reasonml-ols|
+    reason-language-server................|ale-reasonml-language-server|
     refmt.................................|ale-reasonml-refmt|
   restructuredtext........................|ale-restructuredtext-options|
     textlint..............................|ale-restructuredtext-textlint|
@@ -2199,6 +2287,7 @@ documented in additional help files.
     ruby..................................|ale-ruby-ruby|
     rufo..................................|ale-ruby-rufo|
     solargraph............................|ale-ruby-solargraph|
+    sorbet................................|ale-ruby-sorbet|
     standardrb............................|ale-ruby-standardrb|
   rust....................................|ale-rust-options|
     cargo.................................|ale-rust-cargo|
@@ -2229,6 +2318,7 @@ documented in additional help files.
   spec....................................|ale-spec-options|
     rpmlint...............................|ale-spec-rpmlint|
   sql.....................................|ale-sql-options|
+    pgformatter...........................|ale-sql-pgformatter|
     sqlfmt................................|ale-sql-sqlfmt|
   stylus..................................|ale-stylus-options|
     stylelint.............................|ale-stylus-stylelint|
@@ -2239,12 +2329,14 @@ documented in additional help files.
   tcl.....................................|ale-tcl-options|
     nagelfar..............................|ale-tcl-nagelfar|
   terraform...............................|ale-terraform-options|
-    fmt...................................|ale-terraform-fmt|
+    terraform-fmt-fixer...................|ale-terraform-fmt-fixer|
+    terraform.............................|ale-terraform-terraform|
     tflint................................|ale-terraform-tflint|
   tex.....................................|ale-tex-options|
     chktex................................|ale-tex-chktex|
     lacheck...............................|ale-tex-lacheck|
     latexindent...........................|ale-tex-latexindent|
+    texlab................................|ale-tex-texlab|
   texinfo.................................|ale-texinfo-options|
     write-good............................|ale-texinfo-write-good|
   text....................................|ale-text-options|
@@ -2797,6 +2889,13 @@ ale#command#ManageFile(buffer, filename)             *ale#command#ManageFile()*
   manages directories separately with the |ale#command#ManageDirectory| function.
 
 
+ale#completion#OmniFunc(findstart, base)            *ale#completion#OmniFunc()*
+
+  A completion function to use with 'omnifunc'.
+
+  See |ale-completion|.
+
+
 ale#engine#GetLoclist(buffer)                         *ale#engine#GetLoclist()*
 
   Given a buffer number, this function will return the list of problems
@@ -3174,6 +3273,33 @@ ale#linter#PreventLoading(filetype)               *ale#linter#PreventLoading()*
   |runtimepath| for that filetype. This function can be called from vimrc or
   similar to prevent ALE from loading linters.
 
+
+ale#lsp_linter#SendRequest(buffer, linter_name, message, [Handler])
+                                                 *ale#lsp_linter#SendRequest()*
+
+  Send a custom request to an LSP linter. The arguments are defined as
+  follows:
+
+  `buffer`       A valid buffer number.
+
+  `linter_name`  A |String| identifying an LSP linter that is available and
+                 enabled for the |filetype| of `buffer`.
+
+  `message`      A |List| in the form `[is_notification, method, parameters]`,
+                 containing three elements:
+                 `is_notification` - an |Integer| that has value 1 if the
+                   request is a notification, 0 otherwise;
+                 `method` - a |String|, identifying an LSP method supported
+                   by `linter`;
+                 `parameters` - a |dictionary| of LSP parameters that are
+                   applicable to `method`.
+
+  `Handler`      Optional argument, meaningful only when `message[0]` is 0.
+                 A |Funcref| that is called when a response to the request is
+                 received, and takes as unique argument a dictionary
+                 representing the response obtained from the server.
+
+
 ale#other_source#ShowResults(buffer, linter_name, loclist)
                                                *ale#other_source#ShowResults()*
 
@@ -3312,7 +3438,7 @@ snazzy looking ale glass logo. Cheers, Mark!
 11. Contact                                                       *ale-contact*
 
 If you like this plugin, and wish to get in touch, check out the GitHub
-page for issues and more at https://github.com/w0rp/ale
+page for issues and more at https://github.com/dense-analysis/ale
 
 If you wish to contact the author of this plugin directly, please feel
 free to send an email to devw0rp@gmail.com.
diff --git a/sources_non_forked/ale/plugin/ale.vim b/sources_non_forked/ale/plugin/ale.vim
index cf39d632..6262a7c4 100644
--- a/sources_non_forked/ale/plugin/ale.vim
+++ b/sources_non_forked/ale/plugin/ale.vim
@@ -71,12 +71,12 @@ let g:ale_linter_aliases = get(g:, 'ale_linter_aliases', {})
 let g:ale_lint_delay = get(g:, 'ale_lint_delay', 200)
 
 " This flag can be set to 'never' to disable linting when text is changed.
-" This flag can also be set to 'insert' or 'normal' to lint when text is
-" changed only in insert or normal mode respectively.
-let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 'always')
+" This flag can also be set to 'always' or 'insert' to lint when text is
+" changed in both normal and insert mode, or only in insert mode respectively.
+let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 'normal')
 
 " This flag can be set to 1 to enable linting when leaving insert mode.
-let g:ale_lint_on_insert_leave = get(g:, 'ale_lint_on_insert_leave', 0)
+let g:ale_lint_on_insert_leave = get(g:, 'ale_lint_on_insert_leave', 1)
 
 " This flag can be set to 0 to disable linting when the buffer is entered.
 let g:ale_lint_on_enter = get(g:, 'ale_lint_on_enter', 1)
@@ -142,6 +142,9 @@ let g:ale_completion_enabled = get(g:, 'ale_completion_enabled', 0)
 " Enable automatic detection of pipenv for Python linters.
 let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0)
 
+" This variable can be overridden to set the GO111MODULE environment variable.
+let g:ale_go_go111module = get(g:, 'ale_go_go111module', '')
+
 if g:ale_set_balloons
     call ale#balloon#Enable()
 endif
diff --git a/sources_non_forked/ale/rplugin/python3/deoplete/sources/ale.py b/sources_non_forked/ale/rplugin/python3/deoplete/sources/ale.py
index 7ed2f6c0..3955ed2d 100644
--- a/sources_non_forked/ale/rplugin/python3/deoplete/sources/ale.py
+++ b/sources_non_forked/ale/rplugin/python3/deoplete/sources/ale.py
@@ -21,13 +21,23 @@ class Source(Base):
 
         self.name = 'ale'
         self.mark = '[L]'
-        self.rank = 100
+        self.rank = 1000
         self.is_bytepos = True
         self.min_pattern_length = 1
+        # Do not forget to update s:trigger_character_map in completion.vim in
+        # updating entries in this map.
+        self.input_patterns = {
+            '_': r'\.\w*$',
+            'rust': r'(\.|::)\w*$',
+            'typescript': r'(\.|\'|")\w*$',
+            'cpp': r'(\.|::|->)\w*$',
+        }
 
     # Returns an integer for the start position, as with omnifunc.
-    def get_completion_position(self):
-        return self.vim.call('ale#completion#GetCompletionPosition')
+    def get_complete_position(self, context):
+        return self.vim.call(
+            'ale#completion#GetCompletionPositionForDeoplete', context['input']
+        )
 
     def gather_candidates(self, context):
         # Stop early if ALE can't provide completion data for this buffer.
diff --git a/sources_non_forked/ale/supported-tools.md b/sources_non_forked/ale/supported-tools.md
index 18d69388..c933f510 100644
--- a/sources_non_forked/ale/supported-tools.md
+++ b/sources_non_forked/ale/supported-tools.md
@@ -23,6 +23,7 @@ formatting.
 
 * Ada
   * [gcc](https://gcc.gnu.org)
+  * [gnatpp](https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_utility_programs.html#the-gnat-pretty-printer-gnatpp) :floppy_disk:
 * Ansible
   * [ansible-lint](https://github.com/willthames/ansible-lint)
 * API Blueprint
@@ -62,6 +63,7 @@ formatting.
   * [gcc](https://gcc.gnu.org/)
   * [uncrustify](https://github.com/uncrustify/uncrustify)
 * C#
+  * [csc](http://www.mono-project.com/docs/about-mono/languages/csharp/) :floppy_disk: see:`help ale-cs-csc` for details and configuration
   * [mcs](http://www.mono-project.com/docs/about-mono/languages/csharp/) see:`help ale-cs-mcs` for details
   * [mcsc](http://www.mono-project.com/docs/about-mono/languages/csharp/) :floppy_disk: see:`help ale-cs-mcsc` for details and configuration
   * [uncrustify](https://github.com/uncrustify/uncrustify)
@@ -124,14 +126,14 @@ formatting.
   * [hadolint](https://github.com/hadolint/hadolint)
 * Elixir
   * [credo](https://github.com/rrrene/credo)
-  * [dialyxir](https://github.com/jeremyjh/dialyxir)
-  * [dogma](https://github.com/lpil/dogma)
+  * [dialyxir](https://github.com/jeremyjh/dialyxir) :floppy_disk:
+  * [dogma](https://github.com/lpil/dogma) :floppy_disk:
   * [elixir-ls](https://github.com/JakeBecker/elixir-ls) :warning:
   * [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
 * Elm
   * [elm-format](https://github.com/avh4/elm-format)
   * [elm-lsp](https://github.com/antew/elm-lsp)
-  * [elm-make](https://github.com/elm-lang/elm-make)
+  * [elm-make](https://github.com/elm/compiler)
 * Erb
   * [erb](https://apidock.com/ruby/ERB)
   * [erubi](https://github.com/jeremyevans/erubi)
@@ -190,6 +192,7 @@ formatting.
   * [hdevtools](https://hackage.haskell.org/package/hdevtools)
   * [hfmt](https://github.com/danstiner/hfmt)
   * [hie](https://github.com/haskell/haskell-ide-engine)
+  * [hindent](https://hackage.haskell.org/package/hindent)
   * [hlint](https://hackage.haskell.org/package/hlint)
   * [stack-build](https://haskellstack.org/) :floppy_disk:
   * [stack-ghc](https://haskellstack.org/)
@@ -245,6 +248,7 @@ formatting.
   * [lacheck](https://www.ctan.org/pkg/lacheck)
   * [proselint](http://proselint.com/)
   * [redpen](http://redpen.cc/)
+  * [texlab](https://texlab.netlify.com) ([Rust rewrite](https://github.com/latex-lsp/texlab/tree/rust))
   * [textlint](https://textlint.github.io/)
   * [vale](https://github.com/ValeLint/vale)
   * [write-good](https://github.com/btford/write-good)
@@ -346,6 +350,8 @@ formatting.
   * [languageserver](https://github.com/lingua-pupuli/puppet-editor-services)
   * [puppet](https://puppet.com)
   * [puppet-lint](https://puppet-lint.com)
+* PureScript
+  * [purescript-language-server](https://github.com/nwolverson/purescript-language-server)
 * Python
   * [autopep8](https://github.com/hhatto/autopep8)
   * [bandit](https://github.com/PyCQA/bandit) :warning:
@@ -361,6 +367,7 @@ formatting.
   * [pylint](https://www.pylint.org/) :floppy_disk:
   * [pyls](https://github.com/palantir/python-language-server) :warning:
   * [pyre](https://github.com/facebook/pyre-check) :warning:
+  * [reorder-python-imports](https://github.com/asottile/reorder_python_imports)
   * [vulture](https://github.com/jendrikseipp/vulture) :warning: :floppy_disk:
   * [yapf](https://github.com/google/yapf)
 * QML
@@ -374,6 +381,7 @@ formatting.
 * ReasonML
   * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-reasonml-ols` for configuration instructions
   * [ols](https://github.com/freebroccolo/ocaml-language-server)
+  * [reason-language-server](https://github.com/jaredly/reason-language-server)
   * [refmt](https://github.com/reasonml/reason-cli)
 * reStructuredText
   * [alex](https://github.com/wooorm/alex) :floppy_disk:
@@ -395,6 +403,7 @@ formatting.
   * [ruby](https://www.ruby-lang.org)
   * [rufo](https://github.com/ruby-formatter/rufo)
   * [solargraph](https://solargraph.org)
+  * [sorbet](https://github.com/sorbet/sorbet)
   * [standardrb](https://github.com/testdouble/standard)
 * Rust
   * [cargo](https://github.com/rust-lang/cargo) :floppy_disk: (see `:help ale-integration-rust` for configuration instructions)
@@ -423,6 +432,7 @@ formatting.
   * [solhint](https://github.com/protofire/solhint)
   * [solium](https://github.com/duaraghav8/Solium)
 * SQL
+  * [pgformatter](https://github.com/darold/pgFormatter)
   * [sqlfmt](https://github.com/jackc/sqlfmt)
   * [sqlint](https://github.com/purcell/sqlint)
 * Stylus
diff --git a/sources_non_forked/goyo.vim/autoload/goyo.vim b/sources_non_forked/goyo.vim/autoload/goyo.vim
index 94216d1a..6667620e 100644
--- a/sources_non_forked/goyo.vim/autoload/goyo.vim
+++ b/sources_non_forked/goyo.vim/autoload/goyo.vim
@@ -260,7 +260,7 @@ function! s:goyo_on(dim)
 
   augroup goyo
     autocmd!
-    autocmd TabLeave    *        call s:goyo_off()
+    autocmd TabLeave    * nested call s:goyo_off()
     autocmd VimResized  *        call s:resize_pads()
     autocmd ColorScheme *        call s:tranquilize()
     autocmd BufWinEnter *        call s:hide_linenr() | call s:hide_statusline()
diff --git a/sources_non_forked/lightline.vim/.travis.yml b/sources_non_forked/lightline.vim/.travis.yml
index 179c66dc..9c8184a2 100644
--- a/sources_non_forked/lightline.vim/.travis.yml
+++ b/sources_non_forked/lightline.vim/.travis.yml
@@ -1,7 +1,5 @@
 language: generic
 
-sudo: false
-
 install:
   - git clone --depth=1 https://github.com/thinca/vim-themis /tmp/themis
   - (if ! test -d $HOME/vim-$VIM_VERSION/bin; then
@@ -18,6 +16,8 @@ cache:
     - $HOME/vim-$VIM_VERSION
 
 env:
+  - VIM_VERSION=8.1.1775
+  - VIM_VERSION=8.1.1700
   - VIM_VERSION=8.1.0000
   - VIM_VERSION=8.0.0000
   - VIM_VERSION=7.4
diff --git a/sources_non_forked/lightline.vim/README.md b/sources_non_forked/lightline.vim/README.md
index 1e6eb816..656fe90c 100644
--- a/sources_non_forked/lightline.vim/README.md
+++ b/sources_non_forked/lightline.vim/README.md
@@ -52,11 +52,17 @@ landscape is my colorscheme, which is a high-contrast cterm-supported colorschem
 + Orthogonality. The plugin does not rely on the implementation of other plugins. Such plugin crossing settings should be configured by users.
 
 ## Installation
+### [Vim packages](http://vimhelp.appspot.com/repeat.txt.html#packages) (since Vim 7.4.1528)
+
+        git clone https://github.com/itchyny/lightline.vim ~/.vim/pack/plugins/start/lightline
+
 ### [Pathogen](https://github.com/tpope/vim-pathogen)
 1. Install with the following command.
 
         git clone https://github.com/itchyny/lightline.vim ~/.vim/bundle/lightline.vim
 
+2. Generate help tags with `:Helptags`.
+
 ### [Vundle](https://github.com/VundleVim/Vundle.vim)
 1. Add the following configuration to your `.vimrc`.
 
diff --git a/sources_non_forked/lightline.vim/autoload/lightline.vim b/sources_non_forked/lightline.vim/autoload/lightline.vim
index 2076a114..127622c0 100644
--- a/sources_non_forked/lightline.vim/autoload/lightline.vim
+++ b/sources_non_forked/lightline.vim/autoload/lightline.vim
@@ -2,7 +2,7 @@
 " Filename: autoload/lightline.vim
 " Author: itchyny
 " License: MIT License
-" Last Change: 2018/11/24 12:00:00.
+" Last Change: 2019/08/20 14:00:00.
 " =============================================================================
 
 let s:save_cpo = &cpo
@@ -11,6 +11,7 @@ set cpo&vim
 let s:_ = 1 " 1: uninitialized, 2: disabled
 
 function! lightline#update() abort
+  if &buftype ==# 'popup' | return | endif
   if s:_
     if s:_ == 2 | return | endif
     call lightline#init()
@@ -20,7 +21,7 @@ function! lightline#update() abort
     return
   endif
   let w = winnr()
-  let s = winnr('$') == 1 ? [lightline#statusline(0)] : [lightline#statusline(0), lightline#statusline(1)]
+  let s = winnr('$') == 1 && w > 0 ? [lightline#statusline(0)] : [lightline#statusline(0), lightline#statusline(1)]
   for n in range(1, winnr('$'))
     call setwinvar(n, '&statusline', s[n!=w])
     call setwinvar(n, 'lightline', n!=w)
@@ -45,7 +46,10 @@ function! lightline#enable() abort
   call lightline#update()
   augroup lightline
     autocmd!
-    autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update()
+    autocmd WinEnter,BufEnter,SessionLoadPost * call lightline#update()
+    if !has('patch-8.1.1715')
+      autocmd FileType qf call lightline#update()
+    endif
     autocmd SessionLoadPost * call lightline#highlight()
     autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
           \ | call lightline#update() | call lightline#highlight() | endif
diff --git a/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim
new file mode 100644
index 00000000..85da9025
--- /dev/null
+++ b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/ayu_mirage.vim
@@ -0,0 +1,39 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/ayu_mirage.vim
+" Author: impulse
+" License: MIT License
+" Last Change: 2019/08/11 11:52:20.
+" =============================================================================
+let s:base0 = [ '#d9d7ce', 244 ]
+let s:base1 = [ '#d9d7ce', 247 ]
+let s:base2 = [ '#607080', 248 ]
+let s:base3 = [ '#d9d7ce', 252 ]
+let s:base00 = [ '#272d38', 242  ]
+let s:base01 = [ '#272d38', 240 ]
+let s:base02 = [ '#212733', 238 ]
+let s:base023 = [ '#212733', 236 ]
+let s:base03 = [ '#ffc44c', 235 ]
+let s:yellow = [ '#ffc44c', 180 ]
+let s:orange = [ '#ffae57', 173 ]
+let s:red = [ '#f07178', 203 ]
+let s:magenta = [ '#d4bfff', 216 ]
+let s:blue = [ '#59c2ff', 117 ]
+let s:cyan = s:blue
+let s:green = [ '#bbe67e', 119 ]
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:base02, s:blue ], [ s:base3, s:base01 ] ]
+let s:p.normal.middle = [ [ s:base2, s:base02 ] ]
+let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]
+let s:p.inactive.left =  [ [ s:base1, s:base01 ], [ s:base3, s:base01 ] ]
+let s:p.inactive.middle = [ [ s:base1, s:base023 ] ]
+let s:p.inactive.right = [ [ s:base1, s:base01 ], [ s:base2, s:base02 ] ]
+let s:p.insert.left = [ [ s:base02, s:green ], [ s:base3, s:base01 ] ]
+let s:p.replace.left = [ [ s:base023, s:red ], [ s:base3, s:base01 ] ]
+let s:p.visual.left = [ [ s:base02, s:magenta ], [ s:base3, s:base01 ] ]
+let s:p.tabline.tabsel = [ [ s:base02, s:base03 ] ]
+let s:p.tabline.left = [ [ s:base3, s:base00 ] ]
+let s:p.tabline.middle = [ [ s:base2, s:base02 ] ]
+let s:p.tabline.right = [ [ s:base2, s:base00 ] ]
+let s:p.normal.error = [ [ s:base03, s:red ] ]
+let s:p.normal.warning = [ [ s:base023, s:yellow ] ]
+let g:lightline#colorscheme#ayu_mirage#palette = lightline#colorscheme#flatten(s:p)
diff --git a/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim
new file mode 100644
index 00000000..34058a87
--- /dev/null
+++ b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/powerlineish.vim
@@ -0,0 +1,28 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/powerlineish.vim
+" Author: itchyny
+" License: MIT License
+" Last Change: 2019/06/12 18:47:00.
+" =============================================================================
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ ['darkestgreen', 'brightgreen', 'bold'], ['white', 'gray0'] ]
+let s:p.normal.right = [ ['gray10', 'gray2'], ['white', 'gray1'], ['white', 'gray0'] ]
+let s:p.inactive.right = [ ['gray1', 'gray5'], ['gray4', 'gray1'], ['gray4', 'gray0'] ]
+let s:p.inactive.left = s:p.inactive.right[1:]
+let s:p.insert.left = [ ['darkestcyan', 'white', 'bold'], ['mediumcyan', 'darkestblue'] ]
+let s:p.insert.right = [ [ 'darkestblue', 'mediumcyan' ], [ 'mediumcyan', 'darkblue' ], [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.left = [ ['white', 'brightred', 'bold'], ['white', 'gray0'] ]
+let s:p.visual.left = [ ['black', 'brightestorange', 'bold'], ['white', 'gray0'] ]
+let s:p.normal.middle = [ [ 'white', 'gray0' ] ]
+let s:p.insert.middle = [ [ 'mediumcyan', 'darkestblue' ] ]
+let s:p.replace.middle = s:p.normal.middle
+let s:p.replace.right = s:p.normal.right
+let s:p.tabline.left = [ [ 'gray9', 'gray0' ] ]
+let s:p.tabline.tabsel = [ [ 'gray9', 'gray2' ] ]
+let s:p.tabline.middle = [ [ 'gray2', 'gray0' ] ]
+let s:p.tabline.right = [ [ 'gray9', 'gray1' ] ]
+let s:p.normal.error = [ [ 'gray9', 'brightestred' ] ]
+let s:p.normal.warning = [ [ 'gray1', 'yellow' ] ]
+
+let g:lightline#colorscheme#powerlineish#palette = lightline#colorscheme#fill(s:p)
diff --git a/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim
new file mode 100644
index 00000000..585b948b
--- /dev/null
+++ b/sources_non_forked/lightline.vim/autoload/lightline/colorscheme/selenized_dark.vim
@@ -0,0 +1,50 @@
+" =============================================================================
+" Filename: autoload/lightline/colorscheme/selenized_dark.vim
+" Author: Charles Hall
+" License: MIT License
+" Last Change: 2019/07/22 11:05:34.
+" =============================================================================
+
+" https://github.com/jan-warchol/selenized/blob/master/the-values.md#selenized-dark
+let s:black      = [ "#184956", 0  ]
+let s:red        = [ "#fa5750", 1  ]
+let s:green      = [ "#75b938", 2  ]
+let s:yellow     = [ "#dbb32d", 3  ]
+let s:blue       = [ "#4695f7", 4  ]
+let s:magenta    = [ "#f275be", 5  ]
+let s:cyan       = [ "#41c7b9", 6  ]
+let s:white      = [ "#72898f", 7  ]
+let s:brblack    = [ "#2d5b69", 8  ]
+let s:brred      = [ "#ff665c", 9  ]
+let s:brgreen    = [ "#84c747", 10 ]
+let s:bryellow   = [ "#ebc13d", 11 ]
+let s:brblue     = [ "#58a3ff", 12 ]
+let s:brmagenta  = [ "#ff84cd", 13 ]
+let s:brcyan     = [ "#53d6c7", 14 ]
+let s:brwhite    = [ "#cad8d9", 15 ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+
+let s:p.normal.right    = [[ s:black,  s:blue    ],[ s:cyan, s:brblack ],[ s:white, s:black ]]
+let s:p.normal.left     = [[ s:black,  s:blue    ],[ s:cyan, s:brblack ]]
+let s:p.normal.middle   = [[ s:black,  s:black   ]]
+let s:p.normal.error    = [[ s:black,  s:red     ]]
+let s:p.normal.warning  = [[ s:black,  s:yellow  ]]
+
+let s:p.insert.right    = [[ s:black,  s:green   ],[ s:cyan, s:brblack ],[ s:white, s:black ]]
+let s:p.insert.left     = [[ s:black,  s:green   ],[ s:cyan, s:brblack ]]
+
+let s:p.visual.right    = [[ s:black,  s:magenta ],[ s:cyan, s:brblack ],[ s:white, s:black ]]
+let s:p.visual.left     = [[ s:black,  s:magenta ],[ s:cyan, s:brblack ]]
+
+let s:p.inactive.left   = [[ s:brblue, s:brblack ],[ s:cyan, s:brblack ]]
+let s:p.inactive.right  = [[ s:brblue, s:brblack ],[ s:cyan, s:brblack ]]
+
+let s:p.replace.right   = [[ s:black,  s:red     ],[ s:cyan, s:brblack ],[ s:white, s:black ]]
+let s:p.replace.left    = [[ s:black,  s:red     ],[ s:cyan, s:brblack ]]
+
+let s:p.tabline.right   = [[ s:black,  s:red ]]
+let s:p.tabline.left    = [[ s:cyan,   s:brblack ]]
+let s:p.tabline.tabsel  = [[ s:black,  s:blue ]]
+
+let g:lightline#colorscheme#selenized_dark#palette = lightline#colorscheme#flatten(s:p)
diff --git a/sources_non_forked/lightline.vim/doc/lightline.txt b/sources_non_forked/lightline.vim/doc/lightline.txt
index 7c2a886b..cf64523b 100644
--- a/sources_non_forked/lightline.vim/doc/lightline.txt
+++ b/sources_non_forked/lightline.vim/doc/lightline.txt
@@ -4,7 +4,7 @@ Version: 0.1
 Author: itchyny (https://github.com/itchyny)
 License: MIT License
 Repository: https://github.com/itchyny/lightline.vim
-Last Change: 2018/04/28 00:08:18.
+Last Change: 2019/08/14 10:46:55.
 
 CONTENTS					*lightline-contents*
 
@@ -226,10 +226,12 @@ OPTIONS						*lightline-option*
 <
 	g:lightline.colorscheme			*g:lightline.colorscheme*
 		The colorscheme for lightline.vim.
-		Currently, wombat, solarized, powerline, jellybeans, Tomorrow,
-		Tomorrow_Night, Tomorrow_Night_Blue, Tomorrow_Night_Eighties,
-		PaperColor, seoul256, landscape, one, darcula, molokai, materia,
-		material, OldHope, nord, 16color and deus are available.
+		Currently, wombat, solarized, powerline, powerlineish,
+		jellybeans, molokai, seoul256, darcula, selenized_dark,
+		Tomorrow, Tomorrow_Night, Tomorrow_Night_Blue,
+		Tomorrow_Night_Bright, Tomorrow_Night_Eighties, PaperColor,
+		landscape, one, materia, material, OldHope, nord, deus,
+		srcery_drk, ayu_mirage and 16color are available.
 		The default value is:
 >
 		let g:lightline.colorscheme = 'default'
@@ -986,12 +988,15 @@ Problem 1:					*lightline-problem-1*
 
 			1. Put all the files under $VIM.
 
-		If you are using |vim-pathogen|, install this plugin with the
-		following command.
+		If you are to install this plugin using |vim-pathogen|:
+
+			1. Install this plugin with the following command.
 >
 			git clone https://github.com/itchyny/lightline.vim \
 			    ~/.vim/bundle/lightline.vim
 <
+			2. Generate help tags with |:Helptags|.
+
 		If you are to install this plugin using |Vundle|:
 
 			1. Add the following configuration to your
diff --git a/sources_non_forked/lightline.vim/plugin/lightline.vim b/sources_non_forked/lightline.vim/plugin/lightline.vim
index fc8f5981..d08517d7 100644
--- a/sources_non_forked/lightline.vim/plugin/lightline.vim
+++ b/sources_non_forked/lightline.vim/plugin/lightline.vim
@@ -2,7 +2,7 @@
 " Filename: plugin/lightline.vim
 " Author: itchyny
 " License: MIT License
-" Last Change: 2018/06/22 08:49:00.
+" Last Change: 2019/07/30 12:00:00.
 " =============================================================================
 
 if exists('g:loaded_lightline') || v:version < 700
@@ -15,12 +15,20 @@ set cpo&vim
 
 augroup lightline
   autocmd!
-  autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update()
+  autocmd WinEnter,BufEnter,SessionLoadPost * call lightline#update()
+  if !has('patch-8.1.1715')
+    autocmd FileType qf call lightline#update()
+  endif
   autocmd SessionLoadPost * call lightline#highlight()
   autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
         \ | call lightline#update() | call lightline#highlight() | endif
   autocmd CursorMoved,BufUnload * call lightline#update_once()
 augroup END
 
+" This quickfix option was introduced at Vim 85850f3a5ef9, which is the commit
+" just before 8.1.1715. Before this patch, autocmd FileType is required to
+" overwrite the statusline of the quickfix and location windows.
+let g:qf_disable_statusline = 1
+
 let &cpo = s:save_cpo
 unlet s:save_cpo
diff --git a/sources_non_forked/lightline.vim/test/.themisrc b/sources_non_forked/lightline.vim/test/.themisrc
index c226c089..6e0121ce 100644
--- a/sources_non_forked/lightline.vim/test/.themisrc
+++ b/sources_non_forked/lightline.vim/test/.themisrc
@@ -18,3 +18,5 @@ endfunction
 function! SID(name) abort
   return function(printf("\<SNR>%d_%s", s:sid('autoload/lightline.vim'), a:name))
 endfunction
+
+filetype plugin on
diff --git a/sources_non_forked/lightline.vim/test/popup.vim b/sources_non_forked/lightline.vim/test/popup.vim
new file mode 100644
index 00000000..cc4e882a
--- /dev/null
+++ b/sources_non_forked/lightline.vim/test/popup.vim
@@ -0,0 +1,19 @@
+if !exists('*popup_menu') || !exists('*win_execute')
+  finish
+endif
+
+let s:suite = themis#suite('popup')
+let s:assert = themis#helper('assert')
+
+function! s:suite.before_each()
+  let g:lightline = {}
+  call lightline#init()
+  tabnew
+  tabonly
+endfunction
+
+function! s:suite.win_execute_setfiletype()
+  let id = popup_menu(['aaa', 'bbb'], {})
+  call win_execute(id, 'setfiletype vim')
+  call popup_close(id)
+endfunction
diff --git a/sources_non_forked/lightline.vim/test/quickfix.vim b/sources_non_forked/lightline.vim/test/quickfix.vim
new file mode 100644
index 00000000..df4fce7a
--- /dev/null
+++ b/sources_non_forked/lightline.vim/test/quickfix.vim
@@ -0,0 +1,25 @@
+let s:suite = themis#suite('quickfix')
+let s:assert = themis#helper('assert')
+
+function! s:suite.before_each()
+  let g:lightline = {}
+  call lightline#init()
+  tabnew
+  tabonly
+endfunction
+
+function! s:suite.quickfix_statusline()
+  call setloclist(winnr(), [])
+  lopen
+  wincmd p
+  call setloclist(winnr(), [])
+  for n in range(1, winnr('$'))
+    let statusline = getwinvar(n, '&statusline')
+    call s:assert.match(statusline, 'lightline')
+    if has('patch-8.1.1715')
+      call s:assert.match(statusline, n == 1 ? '_active_' : '_inactive_')
+    else
+      call s:assert.match(statusline, n != 1 ? '_active_' : '_inactive_')
+    endif
+  endfor
+endfunction
diff --git a/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE.md b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index c3ca5eff..00000000
--- a/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--- To assist in resolving your issue, provide as much information as possible. -->
-
-### Environment
-<!--- Describe your Vim/NERDTree setup. -->
-
-* Operating System: 
-* Vim version `:version`: 
-* NERDTree version `git rev-parse --short HEAD`: 
-* NERDTree settings applied in your vimrc, if any:
-    ```vim
-    ```
-
-### Process
-<!--- List the steps that will recreate the issue. -->
-
-1. 
-
-### Current Result
-<!--- Describe what you you currently experience from this process. -->
-
-### Expected Result
-<!--- Describe what you would have expected from this process. -->
-
-### Screenshot(s)
-
-### Possible Fix
-<!--- If you have explored the code, share what you've found. -->
-
diff --git a/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/bug.md b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 00000000..dd351350
--- /dev/null
+++ b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,45 @@
+---
+name: "Bug Report"
+about: "NERDTree is misbehaving? Tell us about it."
+labels: bug
+---
+<!-- Attention! Please Read!
+
+Please fill out ALL the information below so that the issue can be fully
+understood. Omitting information will delay the resolution of your issue. It
+will be labeled "Needs More Info", and may be closed until there is enough
+information.
+
+Keep in mind that others may have the same question in the future. The better
+your information, the more likely they'll be able to help themselves. -->
+
+#### Self-Diagnosis
+<!-- Check the boxes after creating the issue, or use [x]. -->
+- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question.
+- [ ] I have reviewed the NERDTree documentation. `:h NERDTree`
+- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki).
+- [ ] I have searched the web for an answer to my question.
+
+#### Environment (for bug reports)
+- [ ] Operating System: 
+- [ ] Vim/Neovim version `:echo v:version`: 
+- [ ] NERDTree version, found on 1st line in NERDTree quickhelp `?`: 
+- [ ] vimrc settings
+    - [ ] NERDTree variables
+    ```vim
+    ```
+    - Other NERDTree-dependent Plugins
+        - [ ] jistr/vim-nerdtree-tabs
+        - [ ] ryanoasis/vim-devicons
+        - [ ] tiagofumo/vim-nerdtree-syntax-highlight
+        - [ ] Xuyuanp/nerdtree-git-plugin
+        - [ ] Others (specify): 
+    - [ ] I've verified the issue occurs with only NERDTree installed.
+
+#### Steps to Reproduce the Issue
+1. 
+
+#### Current Result (Include screenshots where appropriate.)
+
+#### Expected Result
+
diff --git a/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..35db0f6a
--- /dev/null
+++ b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,8 @@
+---
+name: "Feature Request"
+about: "What new feature are you requesting for NERDTree?"
+labels: "feature request"
+---
+
+#### Description
+
diff --git a/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/question.md b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 00000000..25f15b02
--- /dev/null
+++ b/sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,24 @@
+---
+name: "General Question"
+about: "Having trouble setting up NERDTree? Need clarification on a setting? Ask your question here."
+labels: "general question"
+---
+<!-- Attention! Please Read!
+
+Please fill out ALL the information below so that the issue can be fully
+understood. Omitting information will delay the resolution of your issue. It
+will be labeled "Needs More Info", and may be closed until there is enough
+information.
+
+Keep in mind that others may have the same question in the future. The better
+your information, the more likely they'll be able to help themselves. -->
+
+#### Self-Diagnosis
+<!-- Check the boxes after creating the issue, or use [x]. -->
+- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question.
+- [ ] I have reviewed the NERDTree documentation. `:h NERDTree`
+- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki).
+- [ ] I have searched the web for an answer to my question.
+
+#### State Your Question
+
diff --git a/sources_non_forked/nerdtree/.github/PULL_REQUEST_TEMPLATE.md b/sources_non_forked/nerdtree/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..ccd5bf8d
--- /dev/null
+++ b/sources_non_forked/nerdtree/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,13 @@
+### Description of Changes
+Closes #  <!-- Issue number this PR addresses. If none, remove this line. -->
+
+
+---
+### New Version Info
+
+- [ ] Derive a new version number. Increment the:
+    - [ ] `MAJOR` version when you make incompatible API changes
+    - [ ] `MINOR` version when you add functionality in a backwards-compatible manner
+    - [ ] `PATCH` version when you make backwards-compatible bug fixes
+- [ ] Update [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), following the established pattern.
+- [ ] Tag the merge commit, e.g. `git tag -a 3.1.4 -m "v3.1.4" && git push origin --tags`
diff --git a/sources_non_forked/nerdtree/CHANGELOG b/sources_non_forked/nerdtree/CHANGELOG
deleted file mode 100644
index 6dac46dd..00000000
--- a/sources_non_forked/nerdtree/CHANGELOG
+++ /dev/null
@@ -1,179 +0,0 @@
-Next
-    - Fix broken "t" and "T" mappings, tabs now open at end (lifecrisis) #759
-    - Update doc with already existing mapping variables (asnr) #699
-    - Fix the broken g:NERDTreeBookmarksSort setting (lifecrisis) #696
-    - Correct NERDTreeIgnore pattern in doc (cntoplolicon) #648
-    - Remove empty segments when splitting path (sooth-sayer) #574
-    - Suppress autocmds less agressively (wincent) #578 #691
-    - Add an Issues template to ask for more info initially.
-    - Fix markdown headers in readme (josephfrazier) #676
-    - Don't touch @o and @h registers when rendering
-    - Fix bug with files and directories with dollar signs (alegen) #649
-    - Reuse/reopen existing window trees where possible #244
-    - Remove NERDTree.previousBuf()
-    - Change color of arrow (Leeiio) #630
-    - Improved a tip in README.markdown (ggicci) #628
-    - Shorten delete confimration of empty directory to 'y' (mikeperri) #530
-    - Fix API call to open directory tree in window (devm33) #533
-    - Change default arrows on non-Windows platforms (gwilk) #546
-    - Update to README - combine cd and git clone (zwhitchcox) #584
-    - Update to README - Tip: start NERDTree when vim starts (therealplato) #593 
-    - Escape filename when moving an open buffer (zacharyvoase) #595
-    - Fixed incorrect :helptags command in README (curran) #619
-    - Fixed incomplete escaping of folder arrows (adityanatraj) #548
-    - Added NERDTreeCascadeSingleChildDir option (juanibiapina) #558
-    - Replace strchars() with backward compatible workaround.
-    - Add support for copy command in Windows (SkylerLipthay) #231
-    - Fixed typo in README.markdown - :Helptags -> :helptags
-    - Rename "primary" and "secondary" trees to "tab" and "window" trees.
-    - Move a bunch of buffer level variables into the NERDTree and UI classes.
-    - Display cascading dirs on one line to save vertical/horizontal space (@matt-gardner: brainstorming/testing)
-    - Remove the old style UI - Remove 'NERDTreeDirArrows' option.
-    - On windows default to + and ~ for expand/collapse directory symbols.
-    - Lots more refactoring. Move a bunch of b: level vars into b:NERDTree and friends.
-
-5.0.0
-    - Refactor the code significantly:
-        * Break the classes out into their own files.
-        * Make the majority of the code OO - previously large parts were
-          effectively a tangle of "global" methods.
-    - Add an API to assign flags to nodes. This allows VCS plugins like
-      https://github.com/Xuyuanp/nerdtree-git-plugin to exist. Thanks to
-      Xuyuanp for helping design/test/build said API.
-    - add 'scope' argument to the key map API see :help NERDTreeAddKeyMap()
-    - add magic [[dir]] and [[file]] flags to NERDTreeIgnore
-    - add support for custom path filters. See :help NERDTreeAddPathFilter()
-    - add path listener API. See :help NERDTreePathListenerAPI.
-    - expand the fs menu functionality to list file properties (PhilRunninger,
-      apbarrero, JESii)
-    - make bookmarks work with `~` home shortcuts (hiberabyss)
-    - show OSX specific fsmenu options in regular vim on mac (evindor)
-    - make dir arrow icons configurable (PickRelated)
-    - optimise node sorting performance when opening large dirs (vtsang)
-    - make the root note render prettier by truncating it at a path slash (gcmt)
-    - remove NERDChristmasTree option - its always christmas now
-    - add "cascade" open and closing for dirs containing only another single
-      dir. See :help NERDTreeCascadeOpenSingleChildDir (pendulm)
-
-    Many other fixes, doc updates and contributions from:
-    actionshrimp
-    SchDen
-    egalpin
-    cperl82 - many small fixes
-    toiffel
-    WoLpH
-    handcraftedbits
-    devmanhinton
-    xiaodili
-    zhangoose
-    gastropoda
-    mixvin
-    alvan
-    lucascaton
-    kelaban
-    shanesmith
-    staeff
-    pendulm
-    stephenprater
-    franksort
-    agrussellknives
-    AndrewRadev
-    Twinside
-
-4.2.0
-    - Add NERDTreeDirArrows option to make the UI use pretty arrow chars
-      instead of the old +~| chars to define the tree structure (sickill)
-    - shift the syntax highlighting out into its own syntax file (gnap)
-    - add some mac specific options to the filesystem menu - for macvim
-      only (andersonfreitas)
-    - Add NERDTreeMinimalUI option to remove some non functional parts of the
-      nerdtree ui (camthompson)
-    - tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the
-      new behaviour (benjamingeiger)
-    - if no name is given to :Bookmark, make it default to the name of the
-      target file/dir (minyoung)
-    - use 'file' completion when doing copying, create, and move
-      operations (EvanDotPro)
-    - lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly
-      Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)
-
-4.1.0
-    features:
-    - NERDTreeFind to reveal the node for the current buffer in the tree,
-      see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by
-      Doug McInnes) into the script.
-    - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan
-      Ritter and Rémi Prévost.
-    - truncate the root node if wider than the tree window. Thanks to Victor
-      Gonzalez.
-
-    bugfixes:
-    - really fix window state restoring
-    - fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky,
-      jfilip1024, and Chris Chambers
-
-4.0.0
-    - add a new programmable menu system (see :help NERDTreeMenu).
-    - add new APIs to add menus/menu-items to the menu system as well as
-      custom key mappings to the NERD tree buffer (see :help NERDTreeAPI).
-    - removed the old API functions
-    - added a mapping to maximize/restore the size of nerd tree window, thanks
-      to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
-
-    - fix a bug where secondary nerd trees (netrw hijacked trees) and
-      NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey.
-    - fix a bug where the script ignored directories whose name ended in a dot,
-      thanks to Aggelos Orfanakos for the patch.
-    - fix a bug when using the x mapping on the tree root, thanks to Bryan
-      Venteicher for the patch.
-    - fix a bug where the cursor position/window size of the nerd tree buffer
-      wasnt being stored on closing the window, thanks to Richard Hart.
-    - fix a bug where NERDTreeMirror would mirror the wrong tree
-
-3.1.1
-    - fix a bug where a non-listed no-name buffer was getting created every
-      time the tree windows was created, thanks to Derek Wyatt and owen1
-    - make <CR> behave the same as the 'o' mapping
-    - some helptag fixes in the doc, thanks strull
-    - fix a bug when using :set nohidden and opening a file where the previous
-      buf was modified. Thanks iElectric
-    - other minor fixes
-
-3.1.0
-    New features:
-    - add mappings to open files in a vsplit, see :help NERDTree-s and :help
-      NERDTree-gs
-    - make the statusline for the nerd tree window default to something
-      hopefully more useful. See :help 'NERDTreeStatusline'
-    Bugfixes:
-    - make the hijack netrw functionality work when vim is started with "vim
-      <some dir>" (thanks to Alf Mikula for the patch).
-    - fix a bug where the CWD wasnt being changed for some operations even when
-      NERDTreeChDirMode==2 (thanks to Lucas S. Buchala)
-    - add -bar to all the nerd tree :commands so they can chain with other
-      :commands (thanks to tpope)
-    - fix bugs when ignorecase was set (thanks to nach)
-    - fix a bug with the relative path code (thanks to nach)
-    - fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach)
-
-
-3.0.1
-    Bugfixes:
-    - fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden
-      was not set
-    - fix a bug where :NERDTree <path> would fail if <path> was relative and
-      didnt start with a ./ or ../  Thanks to James Kanze.
-    - make the q mapping work with secondary (:e <dir>  style) trees,
-      thanks to jamessan
-    - fix a bunch of small bugs with secondary trees
-
-    More insane refactoring.
-
-3.0.0
-    - hijack netrw so that doing an :edit <directory>  will put a NERD tree in
-      the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
-    - allow sharing of trees across tabs, see :help :NERDTreeMirror
-    - remove "top" and "bottom" as valid settings for NERDTreeWinPos
-    - change the '<tab>' mapping to 'i'
-    - change the 'H' mapping to 'I'
-    - lots of refactoring
diff --git a/sources_non_forked/nerdtree/CHANGELOG.md b/sources_non_forked/nerdtree/CHANGELOG.md
new file mode 100644
index 00000000..9e494175
--- /dev/null
+++ b/sources_non_forked/nerdtree/CHANGELOG.md
@@ -0,0 +1,222 @@
+# Change Log
+
+#### 5.3...
+- **.0**: Add file extension and size to sorting capabilities [#1029](https://github.com/scrooloose/nerdtree/pull/1029)
+#### 5.2...
+- **.9**: Suppress events for intermediate window/tab/buffer changes [#1026](https://github.com/scrooloose/nerdtree/pull/1026)
+- **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021)
+- **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! [#1019](https://github.com/scrooloose/nerdtree/pull/1019)
+- **.6**: In CHANGELOG.md and PR template, make reference to PR a true HTML link. [#1017](https://github.com/scrooloose/nerdtree/pull/1017)
+- **.5**: Use `:mode` instead of `:redraw!` when updating menu. (PhilRunninger) [#1016](https://github.com/scrooloose/nerdtree/pull/1016)
+- **.4**: When searching for root line num, stop at end of file. (PhilRunninger) [#1015](https://github.com/scrooloose/nerdtree/pull/1015)
+- **.3**: Fix `<CR>` key map on the bookmark (lkebin) [#1014](https://github.com/scrooloose/nerdtree/pull/1014)
+- **.2**: Make Enter work on the `.. ( up a dir )` line (PhilRunninger) [#1013](https://github.com/scrooloose/nerdtree/pull/1013)
+- **.1**: Fix nerdtree#version() on Windows. (PhilRunninger)
+- **.0**: Expand functionality of `<CR>` mapping. (PhilRunninger) [#1011](https://github.com/scrooloose/nerdtree/pull/1011)
+#### 5.1...
+- **.3**: Remove @mentions from PR template and change log. They weren't working. (PhilRunninger) [#1009](https://github.com/scrooloose/nerdtree/pull/1009)
+- **.2**: Fix NERDTree opening with the wrong size. (PhilRunninger) [#1008](https://github.com/scrooloose/nerdtree/pull/1008)
+- **.1**: Update Changelog and create PR Template (PhilRunninger) [#1007](https://github.com/scrooloose/nerdtree/pull/1007)
+- **.0**: Too many changes for one patch...
+    - Refresh a dir_node if the file wasn't found in it, and look once more. (PhilRunninger) [#1005](https://github.com/scrooloose/nerdtree/pull/1005)
+    - Add a "copy path to clipboard" menu option (PhilRunninger) [#1002](https://github.com/scrooloose/nerdtree/pull/1002)
+    - Enable root refresh on "vim ." a different way than [#999](https://github.com/scrooloose/nerdtree/pull/999). (PhilRunninger) [#1001](https://github.com/scrooloose/nerdtree/pull/1001)
+    - Fix refreshroot (PhilRunninger) [#999](https://github.com/scrooloose/nerdtree/pull/999)
+    - Change version check to look for 703 not 730 (vhalis) [#994](https://github.com/scrooloose/nerdtree/pull/994)
+    - Change minimum vim (PhilRunninger) [#991](https://github.com/scrooloose/nerdtree/pull/991)
+    - Allow multi-character DirArrows (PhilRunninger) [#985](https://github.com/scrooloose/nerdtree/pull/985)
+    - Remove redraw! while still clearing last message empty string. (PhilRunninger) [#979](https://github.com/scrooloose/nerdtree/pull/979)
+    - fix `_initChildren` function value set to numChildrenCached error (terryding77) [#969](https://github.com/scrooloose/nerdtree/pull/969)
+    - On Windows, do a case-insensitive comparison of paths. (PhilRunninger) [#967](https://github.com/scrooloose/nerdtree/pull/967)
+    - Remove the **Please wait... DONE** messages. (PhilRunninger) [#966](https://github.com/scrooloose/nerdtree/pull/966)
+    - Smarter delimiter default (PhilRunninger) [#963](https://github.com/scrooloose/nerdtree/pull/963)
+    - Update directory .vimdc readme example (spencerdcarlson) [#961](https://github.com/scrooloose/nerdtree/pull/961)
+    - Preview bookmarks (PhilRunninger) [#956](https://github.com/scrooloose/nerdtree/pull/956)
+    - Add new value to NERDTreeQuitOnOpen to close bookmark table (PhilRunninger) [#955](https://github.com/scrooloose/nerdtree/pull/955)
+    - Add an :EditBookmarks command to edit the bookmarks file (PhilRunninger) [#954](https://github.com/scrooloose/nerdtree/pull/954)
+    - Before copying, turn off &shellslash. Restore after copy is finished. (PhilRunninger) [#952](https://github.com/scrooloose/nerdtree/pull/952)
+    - Set a maximum window size when zooming. (PhilRunninger) [#950](https://github.com/scrooloose/nerdtree/pull/950)
+    - Confirm the wipeout of a unsaved buffer whose file has been renamed. (PhilRunninger) [#949](https://github.com/scrooloose/nerdtree/pull/949)
+    - Escape a backslash so it can be used in a key mapping. (PhilRunninger) [#948](https://github.com/scrooloose/nerdtree/pull/948)
+    - Add a NERDTreeMinimalMenu feature (tuzz) [#938](https://github.com/scrooloose/nerdtree/pull/938)
+    - fixed root path error for windows (zcodes) [#935](https://github.com/scrooloose/nerdtree/pull/935)
+    - Restore getDirChildren for use in nerdtree-project-plugin. (PhilRunninger) [#929](https://github.com/scrooloose/nerdtree/pull/929)
+    - Document NERDTreeNodeDelimiter [#912](https://github.com/scrooloose/nerdtree/pull/912) (PhilRunninger) [#926](https://github.com/scrooloose/nerdtree/pull/926)
+    - Allow modification of menu keybindings (Leandros) [#923](https://github.com/scrooloose/nerdtree/pull/923)
+    - Add two more disqualifications for isCascadable(). (PhilRunninger) [#914](https://github.com/scrooloose/nerdtree/pull/914)
+    - Allow highlighting more than one flag. (kristijanhusak) [#908](https://github.com/scrooloose/nerdtree/pull/908)
+    - Support sorting files and directories by modification time. (PhilRunninger) [#901](https://github.com/scrooloose/nerdtree/pull/901)
+    - Parse . and .. from path string with trailing slash. (PhilRunninger) [#899](https://github.com/scrooloose/nerdtree/pull/899)
+    - Force sort to recalculate the cached sortKey. (PhilRunninger) [#898](https://github.com/scrooloose/nerdtree/pull/898)
+    - Add NERDTreeRefreshRoot command (wgfm) [#897](https://github.com/scrooloose/nerdtree/pull/897)
+    - Call Resolve on the file's path when calling :NERDTreeFind. (PhilRunninger) [#896](https://github.com/scrooloose/nerdtree/pull/896)
+    - Catch all errors, not just NERDTree errors. (PhilRunninger) [#894](https://github.com/scrooloose/nerdtree/pull/894)
+    - Fix typo in help file (lvoisin) [#892](https://github.com/scrooloose/nerdtree/pull/892)
+    - Make NERDTreeCreator set the `'nolist'` option (lifecrisis) [#889](https://github.com/scrooloose/nerdtree/pull/889)
+    - Refresh buffers after `m`, `m` operation on a folder (PhilRunninger) [#888](https://github.com/scrooloose/nerdtree/pull/888)
+    - Use a better arg for FINDSTR when using the m,l command in Windows. (PhilRunninger) [#887](https://github.com/scrooloose/nerdtree/pull/887)
+    - Fix the <C-J>/<C-K> motions, which currently fail with cascades (lifecrisis) [#886](https://github.com/scrooloose/nerdtree/pull/886)
+    - Function "s:UI.getLineNum()" doesn't always work on cascades. (lifecrisis) [#882](https://github.com/scrooloose/nerdtree/pull/882)
+    - NERDTreeCWD: reset CWD if changed by NERDTreeFocus (PhilRunninger) [#878](https://github.com/scrooloose/nerdtree/pull/878)
+    - Use <count>tabnext instead of <count>gt to allow users to remap gt. (PhilRunninger) [#877](https://github.com/scrooloose/nerdtree/pull/877)
+    - Do a case sensitive comparison of new/existing buffers. (PhilRunninger) [#875](https://github.com/scrooloose/nerdtree/pull/875)
+    - Fix opening sub-directories that have commas in their name. (PhilRunninger) [#873](https://github.com/scrooloose/nerdtree/pull/873)
+    - Add new command to open NERDTree in the root of a VCS repository. (PhilRunninger) [#872](https://github.com/scrooloose/nerdtree/pull/872)
+    - Make sure the path to the bookmarks file exists before writing it. (PhilRunninger) [#871](https://github.com/scrooloose/nerdtree/pull/871)
+    - Unzoom NERDTree when opening a file (PhilRunninger) [#870](https://github.com/scrooloose/nerdtree/pull/870)
+    - Support unusual characters in file and directory names (PhilRunninger) [#868](https://github.com/scrooloose/nerdtree/pull/868)
+    - Reword renamed-buffer prompt to be more clear (aflock) [#867](https://github.com/scrooloose/nerdtree/pull/867)
+    - Default to placing cursor on root when closing bookmark table (lifecrisis) [#866](https://github.com/scrooloose/nerdtree/pull/866)
+    - Fix issues with sorting of nodes (PhilRunninger) [#856](https://github.com/scrooloose/nerdtree/pull/856)
+    - Better OSX detection (bubba-h57) [#853](https://github.com/scrooloose/nerdtree/pull/853)
+    - Bugfix - ensure keymaps dictionary exists before using it (mnussbaum) [#852](https://github.com/scrooloose/nerdtree/pull/852)
+    - Decrease startup-time by avoiding linear-time iteration over key mappings (mnussbaum) [#851](https://github.com/scrooloose/nerdtree/pull/851)
+    - Add code to sort mappings in quickhelp (lifecrisis) [#849](https://github.com/scrooloose/nerdtree/pull/849)
+    - Use ":clearjumps" in new NERDTree windows (lifecrisis) [#844](https://github.com/scrooloose/nerdtree/pull/844)
+    - Like m-c did before, create parent directories if needed on m-m. (PhilRunninger) [#840](https://github.com/scrooloose/nerdtree/pull/840)
+    - BUGFIX: Repair a problem with the `'u'` mapping. (lifecrisis) [#838](https://github.com/scrooloose/nerdtree/pull/838)
+    - Make the NERDTree buffer writable when rendering it. (PhilRunninger) [#837](https://github.com/scrooloose/nerdtree/pull/837)
+    - Code cleanup: Remove unsupported bookmark table mappings (lifecrisis) [#835](https://github.com/scrooloose/nerdtree/pull/835)
+    - Replace strcharpart() with substitute() for backward compatibility (bravestarr) [#834](https://github.com/scrooloose/nerdtree/pull/834)
+    - Fixed error `unknown function strcharpart` for older versions of Vim (hav4ik) [#833](https://github.com/scrooloose/nerdtree/pull/833)
+    - Clear output when NERDTree menu is aborted (lifecrisis) [#832](https://github.com/scrooloose/nerdtree/pull/832)
+    - Display a path with multi-byte characters correctly when it is truncated (bravestarr) [#830](https://github.com/scrooloose/nerdtree/pull/830)
+    - Support revealing file and executing file with xdg-open for Linux (ngnmhieu) [#824](https://github.com/scrooloose/nerdtree/pull/824)
+    - If node isn't open, count children on disk before deleting. (PhilRunninger) [#822](https://github.com/scrooloose/nerdtree/pull/822)
+    - Add new variable g:NERDTreeRemoveFileCmd (kutsan) [#816](https://github.com/scrooloose/nerdtree/pull/816)
+    - Use a better check for existence of the NERDTree buffer. (PhilRunninger) [#814](https://github.com/scrooloose/nerdtree/pull/814)
+    - Fix focussing previous buffer when closing NERDTree (mrubli) [#801](https://github.com/scrooloose/nerdtree/pull/801)
+    - Update the docs for "NERDTreeStatusline" (lifecrisis) [#796](https://github.com/scrooloose/nerdtree/pull/796)
+    - BUGFIX: Unstable behavior in the "getPath()" method (lifecrisis) [#795](https://github.com/scrooloose/nerdtree/pull/795)
+    - Revert the bugfix from pull request [#785](https://github.com/scrooloose/nerdtree/pull/785) (lifecrisis) [#794](https://github.com/scrooloose/nerdtree/pull/794)
+    - BUGFIX: Allow ":NERDTreeFind" to discover hidden files (lifecrisis) [#786](https://github.com/scrooloose/nerdtree/pull/786)
+    - BUGFIX: Allow ":NERDTreeFind" to reveal new files (lifecrisis) [#785](https://github.com/scrooloose/nerdtree/pull/785)
+    - Add modelines (lifecrisis) [#782](https://github.com/scrooloose/nerdtree/pull/782)
+    - Change the type of completion used by NERDTreeFind (lifecrisis) [#781](https://github.com/scrooloose/nerdtree/pull/781)
+    - change NERDTreeFind with args (zhenyangze) [#778](https://github.com/scrooloose/nerdtree/pull/778)
+    - Style Choice: Using confirm() when deleting a bookmark (lifecrisis) [#777](https://github.com/scrooloose/nerdtree/pull/777)
+    - remove useless substitute when `file =~# "/$"` (skyblueee) [#773](https://github.com/scrooloose/nerdtree/pull/773)
+    - remove useless removeLeadingSpaces in _stripMarkup (skyblueee) [#772](https://github.com/scrooloose/nerdtree/pull/772)
+    - Make the "o" mapping consistent with "x" (lifecrisis) [#769](https://github.com/scrooloose/nerdtree/pull/769)
+    - Fix a problem with the "x" handler (lifecrisis) [#768](https://github.com/scrooloose/nerdtree/pull/768)
+    - Clean up the handler for the "x" mapping (lifecrisis) [#767](https://github.com/scrooloose/nerdtree/pull/767)
+    - Revert change to tab opening method (lifecrisis) [#766](https://github.com/scrooloose/nerdtree/pull/766)
+    - BUGFIX: Add back support for "b:NERDTreeRoot" (lifecrisis) [#765](https://github.com/scrooloose/nerdtree/pull/765)
+    - Fix broken "t" and "T" mappings, tabs now open at end (lifecrisis) [#759](https://github.com/scrooloose/nerdtree/pull/759)
+    - Update doc with already existing mapping variables (asnr) [#699](https://github.com/scrooloose/nerdtree/pull/699)
+    - Fix the broken g:NERDTreeBookmarksSort setting (lifecrisis) [#696](https://github.com/scrooloose/nerdtree/pull/696)
+    - Correct NERDTreeIgnore pattern in doc (cntoplolicon) [#648](https://github.com/scrooloose/nerdtree/pull/648)
+    - Remove empty segments when splitting path (sooth-sayer) [#574](https://github.com/scrooloose/nerdtree/pull/574)
+    - Suppress autocmds less agressively (wincent) [#578](https://github.com/scrooloose/nerdtree/pull/578) [#691](https://github.com/scrooloose/nerdtree/pull/691)
+    - Add an Issues template to ask for more info initially.
+    - Fix markdown headers in readme (josephfrazier) [#676](https://github.com/scrooloose/nerdtree/pull/676)
+    - Don't touch `@o` and `@h` registers when rendering
+    - Fix bug with files and directories with dollar signs (alegen) [#649](https://github.com/scrooloose/nerdtree/pull/649)
+    - Reuse/reopen existing window trees where possible [#244](https://github.com/scrooloose/nerdtree/pull/244)
+    - Remove NERDTree.previousBuf()
+    - Change color of arrow (Leeiio) [#630](https://github.com/scrooloose/nerdtree/pull/630)
+    - Improved a tip in README.markdown (ggicci) [#628](https://github.com/scrooloose/nerdtree/pull/628)
+    - Shorten delete confimration of empty directory to `y` (mikeperri) [#530](https://github.com/scrooloose/nerdtree/pull/530)
+    - Fix API call to open directory tree in window (devm33) [#533](https://github.com/scrooloose/nerdtree/pull/533)
+    - Change default arrows on non-Windows platforms (gwilk) [#546](https://github.com/scrooloose/nerdtree/pull/546)
+    - Update to README - combine cd and git clone (zwhitchcox) [#584](https://github.com/scrooloose/nerdtree/pull/584)
+    - Update to README - Tip: start NERDTree when vim starts (therealplato) [#593](https://github.com/scrooloose/nerdtree/pull/593)
+    - Escape filename when moving an open buffer (zacharyvoase) [#595](https://github.com/scrooloose/nerdtree/pull/595)
+    - Fixed incorrect :helptags command in README (curran) [#619](https://github.com/scrooloose/nerdtree/pull/619)
+    - Fixed incomplete escaping of folder arrows (adityanatraj) [#548](https://github.com/scrooloose/nerdtree/pull/548)
+    - Added NERDTreeCascadeSingleChildDir option (juanibiapina) [#558](https://github.com/scrooloose/nerdtree/pull/558)
+    - Replace strchars() with backward compatible workaround.
+    - Add support for copy command in Windows (SkylerLipthay) [#231](https://github.com/scrooloose/nerdtree/pull/231)
+    - Fixed typo in README.markdown - :Helptags -> :helptags
+    - Rename "primary" and "secondary" trees to "tab" and "window" trees.
+    - Move a bunch of buffer level variables into the NERDTree and UI classes.
+    - Display cascading dirs on one line to save vertical/horizontal space (matt-gardner: brainstorming/testing)
+    - Remove the old style UI - Remove `NERDTreeDirArrows` option.
+    - On windows default to + and ~ for expand/collapse directory symbols.
+    - Lots more refactoring. Move a bunch of b: level vars into b:NERDTree and friends.
+
+#### 5.0.0
+- Refactor the code significantly:
+    * Break the classes out into their own files.
+    * Make the majority of the code OO - previously large parts were effectively a tangle of "global" methods.
+- Add an API to assign flags to nodes. This allows VCS plugins like https://github.com/Xuyuanp/nerdtree-git-plugin to exist. Thanks to **Xuyuanp** for helping design/test/build said API.
+- add `scope` argument to the key map API see :help NERDTreeAddKeyMap()
+- add magic [[dir]] and [[file]] flags to NERDTreeIgnore
+- add support for custom path filters. See :help NERDTreeAddPathFilter()
+- add path listener API. See :help NERDTreePathListenerAPI.
+- expand the fs menu functionality to list file properties (PhilRunninger, apbarrero, JESii)
+- make bookmarks work with `~` home shortcuts (hiberabyss)
+- show OSX specific fsmenu options in regular vim on mac (evindor)
+- make dir arrow icons configurable (PickRelated)
+- optimise node sorting performance when opening large dirs (vtsang)
+- make the root note render prettier by truncating it at a path slash (gcmt)
+- remove NERDChristmasTree option - its always christmas now
+- add "cascade" open and closing for dirs containing only another single dir. See :help NERDTreeCascadeOpenSingleChildDir (pendulm)
+- Many other fixes, doc updates and contributions from: **actionshrimp**, **agrussellknives**, **alvan**, **AndrewRadev**, **cperl82** (*many small fixes*), **devmanhinton**, **egalpin**, **franksort**, **gastropoda**, **handcraftedbits**, **kelaban**, **lucascaton**, **mixvin**, **pendulm**, **SchDen**, **shanesmith**, **staeff**, **stephenprater**, **toiffel**, **Twinside**, **WoLpH**, **xiaodili**, **zhangoose**
+
+#### 4.2.0
+- Add NERDTreeDirArrows option to make the UI use pretty arrow chars instead of the old +~| chars to define the tree structure (sickill)
+- shift the syntax highlighting out into its own syntax file (gnap)
+- add some mac specific options to the filesystem menu - for macvim only (andersonfreitas)
+- Add NERDTreeMinimalUI option to remove some non functional parts of the nerdtree ui (camthompson)
+- tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the new behaviour (benjamingeiger)
+- if no name is given to :Bookmark, make it default to the name of the target file/dir (minyoung)
+- use `file` completion when doing copying, create, and move operations (EvanDotPro)
+- lots of misc bug fixes from: **AndrewRadev**, **Bogdanov**, **camthompson**, **kml**, **mathias**, **paddyoloughlin**, **scottstvnsn**, **sdewald**, **Vitaly**, **wycats**, me RAWR!
+
+#### 4.1.0
+- features:
+    - NERDTreeFind to reveal the node for the current buffer in the tree, see `|NERDTreeFind|`. This effectively merges the FindInNERDTree plugin (by **Doug McInnes**) into the script.
+    - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to **Stefan Ritter** and **Rémi Prévost**.
+    - truncate the root node if wider than the tree window. Thanks to **Victor Gonzalez**.
+
+- bugfixes:
+    - really fix window state restoring
+    - fix some win32 path escaping issues. Thanks to **Stephan Baumeister**, **Ricky**, **jfilip1024**, and **Chris Chambers**.
+
+#### 4.0.0
+- add a new programmable menu system (see `:help NERDTreeMenu`).
+- add new APIs to add menus/menu-items to the menu system as well as custom key mappings to the NERD tree buffer (see `:help NERDTreeAPI`).
+- removed the old API functions
+- added a mapping to maximize/restore the size of nerd tree window, thanks to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
+- fix a bug where secondary nerd trees (netrw hijacked trees) and NERDTreeQuitOnOpen didnt play nicely, thanks to **Curtis Harvey**.
+- fix a bug where the script ignored directories whose name ended in a dot, thanks to **Aggelos Orfanakos** for the patch.
+- fix a bug when using the x mapping on the tree root, thanks to **Bryan Venteicher** for the patch.
+- fix a bug where the cursor position/window size of the nerd tree buffer wasnt being stored on closing the window, thanks to **Richard Hart**.
+- fix a bug where NERDTreeMirror would mirror the wrong tree
+
+#### 3.1.1
+- fix a bug where a non-listed no-name buffer was getting created every time the tree windows was created, thanks to **Derek Wyatt** and **owen1**
+- make `<CR>` behave the same as the `o` mapping
+- some helptag fixes in the doc, thanks **strull**.
+- fix a bug when using `:set nohidden` and opening a file where the previous buf was modified. Thanks **iElectric**.
+- other minor fixes
+
+#### 3.1.0
+- New features:
+    - add mappings to open files in a vsplit, see `:help NERDTree-s` and `:help NERDTree-gs`
+    - make the statusline for the nerd tree window default to something hopefully more useful. See `:help 'NERDTreeStatusline'`
+- Bugfixes:
+    - make the hijack netrw functionality work when vim is started with `vim <some dir>` (thanks to **Alf Mikula** for the patch).
+    - fix a bug where the CWD wasnt being changed for some operations even when NERDTreeChDirMode==2 (thanks to **Lucas S. Buchala**)
+    - add -bar to all the nerd tree :commands so they can chain with other :commands (thanks to **tpope**)
+    - fix bugs when ignorecase was set (thanks to **nach**)
+    - fix a bug with the relative path code (thanks to **nach**)
+    - fix a bug where doing a `:cd` would cause `:NERDTreeToggle` to fail (thanks **nach**)
+
+
+#### 3.0.1
+- Bugfixes:
+    - fix bugs with :NERDTreeToggle and :NERDTreeMirror when `'hidden'` was not set
+    - fix a bug where `:NERDTree <path>` would fail if `<path>` was relative and didnt start with a `./` or `../`  Thanks to **James Kanze**.
+    - make the `q` mapping work with secondary (`:e <dir>`  style) trees, thanks to **jamessan**
+    - fix a bunch of small bugs with secondary trees
+- More insane refactoring.
+
+#### 3.0.0
+- hijack netrw so that doing an `:edit <directory>`  will put a NERD tree in the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
+- allow sharing of trees across tabs, see `:help :NERDTreeMirror`
+- remove "top" and "bottom" as valid settings for NERDTreeWinPos
+- change the `'<tab>'` mapping to `'i'`
+- change the `'H'` mapping to `'I'`
+- lots of refactoring
diff --git a/sources_non_forked/nerdtree/autoload/nerdtree.vim b/sources_non_forked/nerdtree/autoload/nerdtree.vim
index fd192827..4391565e 100644
--- a/sources_non_forked/nerdtree/autoload/nerdtree.vim
+++ b/sources_non_forked/nerdtree/autoload/nerdtree.vim
@@ -3,13 +3,38 @@ if exists("g:loaded_nerdtree_autoload")
 endif
 let g:loaded_nerdtree_autoload = 1
 
-function! nerdtree#version()
-    return '5.0.0'
+let s:rootNERDTreePath = resolve(expand("<sfile>:p:h:h"))
+function! nerdtree#version(...)
+    let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash()))
+    let l:text = 'Unknown'
+    let l:line = 0
+    while l:line <= len(l:changelog)
+        if l:changelog[l:line] =~ '\d\+\.\d\+'
+            let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '')
+            let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '')
+            break
+        endif
+        let l:line += 1
+    endwhile
+    return l:text
 endfunction
 
 " SECTION: General Functions {{{1
 "============================================================
 
+function! nerdtree#slash()
+
+    if nerdtree#runningWindows()
+        if exists('+shellslash') && &shellslash
+            return '/'
+        endif
+
+        return '\'
+    endif
+
+    return '/'
+endfunction
+
 "FUNCTION: nerdtree#and(x,y) {{{2
 " Implements and() function for Vim <= 7.2
 function! nerdtree#and(x,y)
@@ -129,13 +154,13 @@ function! nerdtree#deprecated(func, ...)
     endif
 endfunction
 
-" FUNCTION: nerdtree#exec(cmd) {{{2
-" Same as :exec cmd but with eventignore set for the duration
-" to disable the autocommands used by NERDTree (BufEnter,
-" BufLeave and VimEnter)
-function! nerdtree#exec(cmd)
+" FUNCTION: nerdtree#exec(cmd, ignoreAll) {{{2
+" Same as :exec cmd but, if ignoreAll is TRUE, set eventignore=all for the duration
+function! nerdtree#exec(cmd, ignoreAll)
     let old_ei = &ei
-    set ei=BufEnter,BufLeave,VimEnter
+    if a:ignoreAll
+        set ei=all
+    endif
     exec a:cmd
     let &ei = old_ei
 endfunction
diff --git a/sources_non_forked/nerdtree/autoload/nerdtree/ui_glue.vim b/sources_non_forked/nerdtree/autoload/nerdtree/ui_glue.vim
index a82ff18e..f0458680 100644
--- a/sources_non_forked/nerdtree/autoload/nerdtree/ui_glue.vim
+++ b/sources_non_forked/nerdtree/autoload/nerdtree/ui_glue.vim
@@ -14,6 +14,10 @@ function! nerdtree#ui_glue#createDefaultBindings()
     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" })
     call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" })
 
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'FileNode', 'callback': s."customOpenFile"})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'DirNode', 'callback': s."customOpenDir"})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'Bookmark', 'callback': s."customOpenBookmark"})
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCustomOpen, 'scope':'all', 'callback': s."activateAll" })
 
     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" })
     call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" })
@@ -76,6 +80,35 @@ endfunction
 "SECTION: Interface bindings {{{1
 "============================================================
 
+"FUNCTION: s:customOpenFile() {{{1
+" Open file node with the "custom" key, initially <CR>.
+function! s:customOpenFile(node)
+    call a:node.activate(s:initCustomOpenArgs().file)
+endfunction
+
+"FUNCTION: s:customOpenDir() {{{1
+" Open directory node with the "custom" key, initially <CR>.
+function! s:customOpenDir(node)
+    call s:activateDirNode(a:node, s:initCustomOpenArgs().dir)
+endfunction
+
+"FUNCTION: s:customOpenBookmark() {{{1
+" Open bookmark node with the "custom" key, initially <CR>.
+function! s:customOpenBookmark(node)
+    if a:node.path.isDirectory
+        call a:node.activate(b:NERDTree, s:initCustomOpenArgs().dir)
+    else
+        call a:node.activate(b:NERDTree, s:initCustomOpenArgs().file)
+    endif
+endfunction
+
+"FUNCTION: s:initCustomOpenArgs() {{{1
+" Make sure NERDTreeCustomOpenArgs has needed keys
+function! s:initCustomOpenArgs()
+    let g:NERDTreeCustomOpenArgs = get(g:, 'NERDTreeCustomOpenArgs', {})
+    return extend(g:NERDTreeCustomOpenArgs, {'file':{'reuse': 'all', 'where': 'p'}, 'dir':{}}, 'keep')
+endfunction
+
 "FUNCTION: s:activateAll() {{{1
 "handle the user activating the updir line
 function! s:activateAll()
@@ -84,15 +117,16 @@ function! s:activateAll()
     endif
 endfunction
 
-" FUNCTION: s:activateDirNode(directoryNode) {{{1
-function! s:activateDirNode(directoryNode)
+" FUNCTION: s:activateDirNode(directoryNode, options) {{{1
+" Open a directory with optional options
+function! s:activateDirNode(directoryNode, ...)
 
     if a:directoryNode.isRoot() && a:directoryNode.isOpen
         call nerdtree#echo('cannot close tree root')
         return
     endif
 
-    call a:directoryNode.activate()
+    call a:directoryNode.activate((a:0 > 0) ? a:1 : {})
 endfunction
 
 "FUNCTION: s:activateFileNode() {{{1
@@ -367,7 +401,7 @@ function! s:jumpToLastChild(node)
     call s:jumpToChild(a:node, 1)
 endfunction
 
-" FUNCTION: s:jumpToChild(node, last) {{{2
+" FUNCTION: s:jumpToChild(node, last) {{{1
 " Jump to the first or last child node at the same file system level.
 "
 " Args:
@@ -425,7 +459,7 @@ function! s:jumpToPrevSibling(node)
     call s:jumpToSibling(a:node, 0)
 endfunction
 
-" FUNCTION: s:jumpToSibling(node, forward) {{{2
+" FUNCTION: s:jumpToSibling(node, forward) {{{1
 " Move the cursor to the next or previous node at the same file system level.
 "
 " Args:
@@ -540,11 +574,11 @@ function! s:refreshRoot()
     call nerdtree#echo("Refreshing the root node. This could take a while...")
 
     let l:curWin = winnr()
-    call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w")
+    call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w", 1)
     call b:NERDTree.root.refresh()
     call b:NERDTree.render()
     redraw
-    call nerdtree#exec(l:curWin . "wincmd w")
+    call nerdtree#exec(l:curWin . "wincmd w", 1)
     call nerdtree#echo("")
 endfunction
 
diff --git a/sources_non_forked/nerdtree/doc/NERDTree.txt b/sources_non_forked/nerdtree/doc/NERDTree.txt
index 93635bd0..14f70782 100644
--- a/sources_non_forked/nerdtree/doc/NERDTree.txt
+++ b/sources_non_forked/nerdtree/doc/NERDTree.txt
@@ -247,12 +247,12 @@ i........Open selected file in a split window.......................|NERDTree-i|
 gi.......Same as i, but leave the cursor on the NERDTree...........|NERDTree-gi|
 s........Open selected file in a new vsplit.........................|NERDTree-s|
 gs.......Same as s, but leave the cursor on the NERDTree...........|NERDTree-gs|
+<CR>.....User-definable custom open action.......................|NERDTree-<CR>|
 O........Recursively open the selected directory....................|NERDTree-O|
 x........Close the current nodes parent.............................|NERDTree-x|
 X........Recursively close all children of the current node.........|NERDTree-X|
 e........Edit the current dir.......................................|NERDTree-e|
 
-<CR>............same as |NERDTree-o|.
 double-click....same as |NERDTree-o|.
 middle-click....same as |NERDTree-i| for files, and |NERDTree-e| for dirs.
 
@@ -319,7 +319,7 @@ The default key combo for this mapping is "g" + NERDTreeMapActivateNode (see
 ------------------------------------------------------------------------------
                                                                     *NERDTree-t*
 Default key: t
-Map setting: NERDTreeMapOpenInTab
+Map setting: *NERDTreeMapOpenInTab*
 Applies to: files and directories.
 
 Opens the selected file in a new tab. If a directory is selected, a fresh
@@ -332,7 +332,7 @@ in a new tab.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-T*
 Default key: T
-Map setting: NERDTreeMapOpenInTabSilent
+Map setting: *NERDTreeMapOpenInTabSilent*
 Applies to: files and directories.
 
 The same as |NERDTree-t| except that the focus is kept in the current tab.
@@ -340,7 +340,7 @@ The same as |NERDTree-t| except that the focus is kept in the current tab.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-i*
 Default key: i
-Map setting: NERDTreeMapOpenSplit
+Map setting: *NERDTreeMapOpenSplit*
 Applies to: files.
 
 Opens the selected file in a new split window and puts the cursor in the new
@@ -349,7 +349,7 @@ window.
 ------------------------------------------------------------------------------
                                                                    *NERDTree-gi*
 Default key: gi
-Map setting: NERDTreeMapPreviewSplit
+Map setting: *NERDTreeMapPreviewSplit*
 Applies to: files.
 
 The same as |NERDTree-i| except that the cursor is not moved.
@@ -360,7 +360,7 @@ The default key combo for this mapping is "g" + NERDTreeMapOpenSplit (see
 ------------------------------------------------------------------------------
                                                                     *NERDTree-s*
 Default key: s
-Map setting: NERDTreeMapOpenVSplit
+Map setting: *NERDTreeMapOpenVSplit*
 Applies to: files.
 
 Opens the selected file in a new vertically split window and puts the cursor
@@ -369,7 +369,7 @@ in the new window.
 ------------------------------------------------------------------------------
                                                                    *NERDTree-gs*
 Default key: gs
-Map setting: NERDTreeMapPreviewVSplit
+Map setting: *NERDTreeMapPreviewVSplit*
 Applies to: files.
 
 The same as |NERDTree-s| except that the cursor is not moved.
@@ -377,10 +377,19 @@ The same as |NERDTree-s| except that the cursor is not moved.
 The default key combo for this mapping is "g" + NERDTreeMapOpenVSplit (see
 |NERDTree-s|).
 
+------------------------------------------------------------------------------
+                                                                 *NERDTree-<CR>*
+Default key: <CR>
+Map setting: *NERDTreeMapCustomOpen*
+Applies to: files, directories, and bookmarks
+
+Performs a customized open action on the selected node. This allows the user
+to define an action that behaves differently from any of the standard
+keys. See |NERDTreeCustomOpenArgs| for more details.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-O*
 Default key: O
-Map setting: NERDTreeMapOpenRecursively
+Map setting: *NERDTreeMapOpenRecursively*
 Applies to: directories.
 
 Recursively opens the selected directory.
@@ -393,7 +402,7 @@ cached. This is handy, especially if you have .svn directories.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-x*
 Default key: x
-Map setting: NERDTreeMapCloseDir
+Map setting: *NERDTreeMapCloseDir*
 Applies to: files and directories.
 
 Closes the parent of the selected node.
@@ -401,7 +410,7 @@ Closes the parent of the selected node.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-X*
 Default key: X
-Map setting: NERDTreeMapCloseChildren
+Map setting: *NERDTreeMapCloseChildren*
 Applies to: directories.
 
 Recursively closes all children of the selected directory.
@@ -411,7 +420,7 @@ Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-e*
 Default key: e
-Map setting: NERDTreeMapOpenExpl
+Map setting: *NERDTreeMapOpenExpl*
 Applies to: files and directories.
 
 |:edit|s the selected directory, or the selected file's directory. This could
@@ -421,7 +430,7 @@ result in a NERDTree or a netrw being opened, depending on
 ------------------------------------------------------------------------------
                                                                     *NERDTree-D*
 Default key: D
-Map setting: NERDTreeMapDeleteBookmark
+Map setting: *NERDTreeMapDeleteBookmark*
 Applies to: lines in the bookmarks table
 
 Deletes the currently selected bookmark.
@@ -429,7 +438,7 @@ Deletes the currently selected bookmark.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-P*
 Default key: P
-Map setting: NERDTreeMapJumpRoot
+Map setting: *NERDTreeMapJumpRoot*
 Applies to: no restrictions.
 
 Jump to the tree root.
@@ -437,7 +446,7 @@ Jump to the tree root.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-p*
 Default key: p
-Map setting: NERDTreeMapJumpParent
+Map setting: *NERDTreeMapJumpParent*
 Applies to: files and directories.
 
 Jump to the parent node of the selected node.
@@ -445,7 +454,7 @@ Jump to the parent node of the selected node.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-K*
 Default key: K
-Map setting: NERDTreeMapJumpFirstChild
+Map setting: *NERDTreeMapJumpFirstChild*
 Applies to: files and directories.
 
 Jump to the first child of the current nodes parent.
@@ -458,7 +467,7 @@ If the cursor is already on the first node then do the following:
 ------------------------------------------------------------------------------
                                                                     *NERDTree-J*
 Default key: J
-Map setting: NERDTreeMapJumpLastChild
+Map setting: *NERDTreeMapJumpLastChild*
 Applies to: files and directories.
 
 Jump to the last child of the current nodes parent.
@@ -471,7 +480,7 @@ If the cursor is already on the last node then do the following:
 ------------------------------------------------------------------------------
                                                                   *NERDTree-C-J*
 Default key: <C-J>
-Map setting: NERDTreeMapJumpNextSibling
+Map setting: *NERDTreeMapJumpNextSibling*
 Applies to: files and directories.
 
 Jump to the next sibling of the selected node.
@@ -479,7 +488,7 @@ Jump to the next sibling of the selected node.
 ------------------------------------------------------------------------------
                                                                   *NERDTree-C-K*
 Default key: <C-K>
-Map setting: NERDTreeMapJumpPrevSibling
+Map setting: *NERDTreeMapJumpPrevSibling*
 Applies to: files and directories.
 
 Jump to the previous sibling of the selected node.
@@ -487,7 +496,7 @@ Jump to the previous sibling of the selected node.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-C*
 Default key: C
-Map setting: NERDTreeMapChangeRoot
+Map setting: *NERDTreeMapChangeRoot*
 Applies to: files and directories.
 
 Make the selected directory node the new tree root. If a file is selected, its
@@ -496,7 +505,7 @@ parent is used.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-u*
 Default key: u
-Map setting: NERDTreeMapUpdir
+Map setting: *NERDTreeMapUpdir*
 Applies to: no restrictions.
 
 Move the tree root up a dir (like doing a "cd ..").
@@ -504,7 +513,7 @@ Move the tree root up a dir (like doing a "cd ..").
 ------------------------------------------------------------------------------
                                                                     *NERDTree-U*
 Default key: U
-Map setting: NERDTreeMapUpdirKeepOpen
+Map setting: *NERDTreeMapUpdirKeepOpen*
 Applies to: no restrictions.
 
 Like |NERDTree-u| except that the old tree root is kept open.
@@ -512,7 +521,7 @@ Like |NERDTree-u| except that the old tree root is kept open.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-r*
 Default key: r
-Map setting: NERDTreeMapRefresh
+Map setting: *NERDTreeMapRefresh*
 Applies to: files and directories.
 
 If a dir is selected, recursively refresh that dir, i.e. scan the filesystem
@@ -523,7 +532,7 @@ If a file node is selected then the above is done on it's parent.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-R*
 Default key: R
-Map setting: NERDTreeMapRefreshRoot
+Map setting: *NERDTreeMapRefreshRoot*
 Applies to: no restrictions.
 
 Recursively refresh the tree root.
@@ -531,7 +540,7 @@ Recursively refresh the tree root.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-m*
 Default key: m
-Map setting: NERDTreeMapMenu
+Map setting: *NERDTreeMapMenu*
 Applies to: files and directories.
 
 Display the NERDTree menu. See |NERDTreeMenu| for details.
@@ -539,7 +548,7 @@ Display the NERDTree menu. See |NERDTreeMenu| for details.
 ------------------------------------------------------------------------------
                                                                    *NERDTree-cd*
 Default key: cd
-Map setting: NERDTreeMapChdir
+Map setting: *NERDTreeMapChdir*
 Applies to: files and directories.
 
 Change Vim's current working directory to that of the selected node.
@@ -547,7 +556,7 @@ Change Vim's current working directory to that of the selected node.
 ------------------------------------------------------------------------------
                                                                    *NERDTree-CD*
 Default key: CD
-Map setting: NERDTreeMapCWD
+Map setting: *NERDTreeMapCWD*
 Applies to: no restrictions.
 
 Change the NERDTree root to Vim's current working directory.
@@ -555,7 +564,7 @@ Change the NERDTree root to Vim's current working directory.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-I*
 Default key: I
-Map setting: NERDTreeMapToggleHidden
+Map setting: *NERDTreeMapToggleHidden*
 Applies to: no restrictions.
 
 Toggles whether hidden files (i.e. "dot files") are displayed.
@@ -563,7 +572,7 @@ Toggles whether hidden files (i.e. "dot files") are displayed.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-f*
 Default key: f
-Map setting: NERDTreeMapToggleFilters
+Map setting: *NERDTreeMapToggleFilters*
 Applies to: no restrictions.
 
 Toggles whether file filters are used. See |NERDTreeIgnore| for details.
@@ -571,7 +580,7 @@ Toggles whether file filters are used. See |NERDTreeIgnore| for details.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-F*
 Default key: F
-Map setting: NERDTreeMapToggleFiles
+Map setting: *NERDTreeMapToggleFiles*
 Applies to: no restrictions.
 
 Toggles whether file nodes are displayed.
@@ -579,7 +588,7 @@ Toggles whether file nodes are displayed.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-B*
 Default key: B
-Map setting: NERDTreeMapToggleBookmarks
+Map setting: *NERDTreeMapToggleBookmarks*
 Applies to: no restrictions.
 
 Toggles whether the bookmarks table is displayed.
@@ -587,7 +596,7 @@ Toggles whether the bookmarks table is displayed.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-q*
 Default key: q
-Map setting: NERDTreeMapQuit
+Map setting: *NERDTreeMapQuit*
 Applies to: no restrictions.
 
 Closes the NERDTree window.
@@ -595,7 +604,7 @@ Closes the NERDTree window.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-A*
 Default key: A
-Map setting: NERDTreeMapToggleZoom
+Map setting: *NERDTreeMapToggleZoom*
 Applies to: no restrictions.
 
 Maximize (zoom) and minimize the NERDTree window.
@@ -603,7 +612,7 @@ Maximize (zoom) and minimize the NERDTree window.
 ------------------------------------------------------------------------------
                                                                     *NERDTree-?*
 Default key: ?
-Map setting: NERDTreeMapHelp
+Map setting: *NERDTreeMapHelp*
 Applies to: no restrictions.
 
 Toggles whether the quickhelp is displayed.
@@ -625,7 +634,7 @@ Related tags: |NERDTree-m| |NERDTreeApi|
 ------------------------------------------------------------------------------
                                                                 *NERDTreeMenu-j*
 Default key: j
-Map option: NERDTreeMenuDown
+Map option: *NERDTreeMenuDown*
 Applies to: The NERDTree menu.
 
 Moves the cursor down.
@@ -633,7 +642,7 @@ Moves the cursor down.
 ------------------------------------------------------------------------------
                                                                 *NERDTreeMenu-k*
 Default key: k
-Map option: NERDTreeMenuUp
+Map option: *NERDTreeMenuUp*
 Applies to: The NERDTree menu.
 
 Moves the cursor up.
@@ -754,6 +763,9 @@ the NERDTree. These settings should be set in your vimrc, using `:let`.
                             file or directory name from the rest of the
                             characters on the line of text.
 
+|NERDTreeCustomOpenArgs|      A dictionary with values that control how a node
+                            is opened with the |NERDTree-<CR>| key.
+
 ------------------------------------------------------------------------------
 3.2. Customisation details                             *NERDTreeSettingsDetails*
 
@@ -1031,28 +1043,31 @@ window.  Use one of the follow lines for this setting: >
 Values: a list of regular expressions.
 Default: ['\/$', '*', '\.swp$',  '\.bak$', '\~$']
 
-This setting is a list of regular expressions which are used to specify the
-order of nodes under their parent.
+This setting is a list of regular expressions which are used to group or sort
+the nodes under their parent.
 
 For example, if the setting is: >
     ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
 <
-then all .vim files will be placed at the top, followed by all .c files then
+then all .vim files will be grouped at the top, followed by all .c files then
 all .h files. All files containing the string 'foobar' will be placed at the
 end.  The star is a special flag: it tells the script that every node that
 doesn't match any of the other regexps should be placed here.
 
-If no star is present in NERDTreeSortOrder then one is automatically
-appended to the array.
+If no star is present in NERDTreeSortOrder, then one is automatically
+appended to the end of the list.
 
 The regex '\/$' should be used to match directory nodes.
 
-A special flag can be used to sort by the modification timestamps of files and
-directories. It is either '[[timestamp]]' for ascending, or '[[-timestamp]]'
-for descending. If placed at the beginning of the list, files and directories
-are sorted by timestamp, and then by the remaining items in the sort order
-list. If this flag is in any other position of the list, timestamp sorting is
-done secondarily. See examples 4, 5, and 6 below.
+Files can also be sorted by 1) the modification timestamp, 2) the size, or 3)
+the extension. Directories are always sorted by name. To accomplish this, the
+following special flags are used:
+  [[timestamp]]   [[-timestamp]]   [[size]]   [[-size]]   [[extension]]
+The hyphen specifies a descending sort; extensions are sorted in ascending
+order only. If placed at the beginning of the list, files are sorted according
+to these flags first, and then grouped by the remaining items in the list. If
+the flags are in any other position of the list, this special sorting is done
+secondarily. See examples 4, 5, and 6 below.
 
 After this sorting is done, the files in each group are sorted alphabetically.
 
@@ -1060,20 +1075,20 @@ Examples: >
     (1) ['*', '\/$']
     (2) []
     (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$',  '\.bak$', '\~$']
-    (4) ['[[timestamp]]']
-    (5) ['\/$', '*', '[[-timestamp]]']
-    (6) ['\.md$', '\.c$', '[[-timestamp]]', '*']
+    (4) ['[[-size]]']
+    (5) ['\/$', '*', '[[timestamp]]']
+    (6) ['foo','\/$','[[extension]]']
 <
 1. Directories will appear last, everything else will appear above.
 2. Everything will simply appear in alphabetical order.
 3. Dirs will appear first, then ruby and php. Swap files, bak files and vim
    backup files will appear last with everything else preceding them.
-4. All files and directories are sorted by timestamp, oldest first. If any
-   files have identical timestamps, they are sorted alphabetically.
-5. Directories are first, newest to oldest, then everything else, newest to
-   oldest.
-6. Markdown files first, followed by C source files, then everything else.
-   Each group is shown newest to oldest.
+4. Everything is sorted by size, largest to smallest, with directories
+   considered to have size 0 bytes.
+5. Directories will appear first alphabetically, followed by files, sorted by
+   timestamp, oldest first.
+6. Files and directories matching 'foo' first, followed by other directories,
+   then all other files. Each section of files is sorted by file extension.
 
 ------------------------------------------------------------------------------
                                                             *NERDTreeStatusline*
@@ -1233,6 +1248,32 @@ when specifying by hex or Unicode. >
     let NERDTreeNodeDelimiter="\u00a0"   "non-breaking space
     let NERDTreeNodeDelimiter="😀"       "smiley face
 <
+------------------------------------------------------------------------------
+                                                        *NERDTreeCustomOpenArgs*
+Values: A nested dictionary, as described below
+Default: {'file': {'reuse': 'all', 'where': 'p'}, 'dir': {}}
+
+This dictionary contains two keys, 'file' and 'dir', whose values each are
+another dictionary. The inner dictionary is a set of parameters used by
+|NERDTree-<CR>| to open a file or directory. Setting these parameters allows you
+to customize the way the node is opened. The default value matches what
+|NERDTree-o| does. To change that behavior, use these keys and
+values in the inner dictionaries:
+
+'where':    specifies whether the node should be opened in a new split ("h" or
+            "v"), in a new tab ("t") or, in the last window ("p").
+'reuse':    if file is already shown in a window, jump there; takes values
+            "all", "currenttab", or empty
+'keepopen': boolean (0 or 1); if true, the tree window will not be closed
+'stay':     boolean (0 or 1); if true, remain in tree window after opening
+
+For example:
+To open files and directories (creating a new NERDTree) in a new tab, >
+    {'file':{'where': 't'}, 'dir':{'where':'t'}}
+<
+To open a file always in the current tab, and expand directories in place, >
+    {'file': {'reuse':'currenttab', 'where':'p', 'keepopen':1, 'stay':1}}
+<
 ==============================================================================
 4. The NERDTree API                                                *NERDTreeAPI*
 
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/bookmark.vim b/sources_non_forked/nerdtree/lib/nerdtree/bookmark.vim
index c633a8f2..b206e7a4 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/bookmark.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/bookmark.vim
@@ -159,8 +159,8 @@ endfunction
 " FUNCTION: s:Edit() {{{1
 " opens the NERDTreeBookmarks file for manual editing
 function! s:Bookmark.Edit()
-    execute "wincmd w"
-    execute "edit ".g:NERDTreeBookmarksFile
+    call nerdtree#exec("wincmd w", 1)
+    call nerdtree#exec("edit ".g:NERDTreeBookmarksFile, 1)
 endfunction
 
 " FUNCTION: Bookmark.getNode(nerdtree, searchFromAbsoluteRoot) {{{1
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/creator.vim b/sources_non_forked/nerdtree/lib/nerdtree/creator.vim
index 980cf805..efd3cc81 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/creator.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/creator.vim
@@ -13,9 +13,6 @@ let g:NERDTreeCreator = s:Creator
 
 " FUNCTION: s:Creator._bindMappings() {{{1
 function! s:Creator._bindMappings()
-    "make <cr> do the same as the activate node mapping
-    nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr>
-
     call g:NERDTreeKeyMap.BindAll()
 
     command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
@@ -189,18 +186,20 @@ function! s:Creator._createTreeWin()
         let t:NERDTreeBufName = self._nextBufferName()
         silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' new'
         silent! execute 'edit ' . t:NERDTreeBufName
+        silent! execute 'vertical resize '. l:splitSize
     else
         silent! execute l:splitLocation . 'vertical ' . l:splitSize . ' split'
         silent! execute 'buffer ' . t:NERDTreeBufName
     endif
 
+    setlocal winfixwidth
+
     call self._setCommonBufOptions()
 
     if has('patch-7.4.1925')
         clearjumps
     endif
 
-    setlocal winfixwidth
 endfunction
 
 " FUNCTION: s:Creator._isBufHidden(nr) {{{1
@@ -218,14 +217,14 @@ function! s:Creator.New()
     return newCreator
 endfunction
 
-" FUNCTION: s:Creator._nextBufferName() {{{2
+" FUNCTION: s:Creator._nextBufferName() {{{1
 " returns the buffer name for the next nerd tree
 function! s:Creator._nextBufferName()
     let name = s:Creator.BufNamePrefix() . self._nextBufferNumber()
     return name
 endfunction
 
-" FUNCTION: s:Creator._nextBufferNumber() {{{2
+" FUNCTION: s:Creator._nextBufferNumber() {{{1
 " the number to add to the nerd tree buffer name to make the buf name unique
 function! s:Creator._nextBufferNumber()
     if !exists("s:Creator._NextBufNum")
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/menu_controller.vim b/sources_non_forked/nerdtree/lib/nerdtree/menu_controller.vim
index 26dbd296..05e82d97 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/menu_controller.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/menu_controller.vim
@@ -31,7 +31,11 @@ function! s:MenuController.showMenu()
         let l:done = 0
 
         while !l:done
-            redraw!
+            if has('nvim')
+                mode
+            else
+                redraw!
+            endif
             call self._echoPrompt()
 
             let l:key = nr2char(getchar())
@@ -64,7 +68,7 @@ function! s:MenuController._echoPrompt()
 
         echo "Menu: [" . join(shortcuts, ",") . "] (" . navHelp . " or shortcut): "
     else
-        echo "NERDTree Menu. " . navHelp . " . or the shortcuts indicated"
+        echo "NERDTree Menu. " . navHelp . ", or the shortcuts indicated"
         echo "========================================================="
 
         for i in range(0, len(self.menuItems)-1)
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/nerdtree.vim b/sources_non_forked/nerdtree/lib/nerdtree/nerdtree.vim
index c1ce5ed0..705d4f9b 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/nerdtree.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/nerdtree.vim
@@ -44,19 +44,19 @@ function! s:NERDTree.Close()
         let l:useWinId = exists('*win_getid') && exists('*win_gotoid')
 
         if winnr() == s:NERDTree.GetWinNum()
-            call nerdtree#exec("wincmd p")
+            call nerdtree#exec("wincmd p", 1)
             let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr("")
-            call nerdtree#exec("wincmd p")
+            call nerdtree#exec("wincmd p", 1)
         else
             let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr("")
         endif
 
-        call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w")
-        close
+        call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w", 1)
+        call nerdtree#exec("close", 1)
         if l:useWinId
-            call nerdtree#exec("call win_gotoid(" . l:activeBufOrWin . ")")
+            call nerdtree#exec("call win_gotoid(" . l:activeBufOrWin . ")", 0)
         else
-            call nerdtree#exec(bufwinnr(l:activeBufOrWin) . " wincmd w")
+            call nerdtree#exec(bufwinnr(l:activeBufOrWin) . " wincmd w", 0)
         endif
     else
         close
@@ -98,7 +98,7 @@ endfunction
 "Places the cursor in the nerd tree window
 function! s:NERDTree.CursorToTreeWin()
     call g:NERDTree.MustBeOpen()
-    call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w")
+    call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w", 1)
 endfunction
 
 " Function: s:NERDTree.ExistsForBuffer()   {{{1
@@ -153,7 +153,7 @@ endfunction
 
 "FUNCTION: s:NERDTree.IsOpen() {{{1
 function! s:NERDTree.IsOpen()
-    return s:NERDTree.GetWinNum() != -1
+    return s:NERDTree.GetWinNum() != -1 || bufname('%') =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$'
 endfunction
 
 "FUNCTION: s:NERDTree.isTabTree() {{{1
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/opener.vim b/sources_non_forked/nerdtree/lib/nerdtree/opener.vim
index f4bd6e06..5953eea2 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/opener.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/opener.vim
@@ -107,10 +107,10 @@ function! s:Opener._isWindowUsable(winnumber)
     endif
 
     let oldwinnr = winnr()
-    call nerdtree#exec(a:winnumber . "wincmd p")
+    call nerdtree#exec(a:winnumber . "wincmd p", 1)
     let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
     let modified = &modified
-    call nerdtree#exec(oldwinnr . "wincmd p")
+    call nerdtree#exec(oldwinnr . "wincmd p", 1)
 
     "if its a special window e.g. quickfix or another explorer plugin then we
     "have to split
@@ -172,7 +172,7 @@ function! s:Opener._newSplit()
     let below=0
 
     " Attempt to go to adjacent window
-    call nerdtree#exec(back)
+    call nerdtree#exec(back, 1)
 
     let onlyOneWin = (winnr("$") ==# 1)
 
@@ -201,9 +201,9 @@ function! s:Opener._newSplit()
     "resize the tree window if no other window was open before
     if onlyOneWin
         let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
-        call nerdtree#exec(there)
+        call nerdtree#exec(there, 1)
         exec("silent ". splitMode ." resize ". size)
-        call nerdtree#exec('wincmd p')
+        call nerdtree#exec('wincmd p', 0)
     endif
 
     " Restore splitmode settings
@@ -219,8 +219,8 @@ function! s:Opener._newVSplit()
         let l:winwidth = g:NERDTreeWinSize
     endif
 
-    call nerdtree#exec('wincmd p')
-    vnew
+    call nerdtree#exec('wincmd p', 1)
+    call nerdtree#exec('vnew', 1)
 
     let l:currentWindowNumber = winnr()
 
@@ -228,7 +228,7 @@ function! s:Opener._newVSplit()
     call g:NERDTree.CursorToTreeWin()
     execute 'silent vertical resize ' . l:winwidth
 
-    call nerdtree#exec(l:currentWindowNumber . 'wincmd w')
+    call nerdtree#exec(l:currentWindowNumber . 'wincmd w', 0)
 endfunction
 
 " FUNCTION: Opener.open(target) {{{1
@@ -290,9 +290,9 @@ function! s:Opener._previousWindow()
     else
         try
             if !self._isWindowUsable(winnr("#"))
-                call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
+                call nerdtree#exec(self._firstUsableWindow() . "wincmd w", 1)
             else
-                call nerdtree#exec('wincmd p')
+                call nerdtree#exec('wincmd p', 1)
             endif
         catch /^Vim\%((\a\+)\)\=:E37/
             call g:NERDTree.CursorToTreeWin()
@@ -305,8 +305,8 @@ endfunction
 
 " FUNCTION: Opener._restoreCursorPos() {{{1
 function! s:Opener._restoreCursorPos()
-    call nerdtree#exec(self._tabnr . 'tabnext')
-    call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w')
+    call nerdtree#exec(self._tabnr . 'tabnext', 1)
+    call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w', 1)
 endfunction
 
 " FUNCTION: Opener._reuseWindow() {{{1
@@ -321,7 +321,7 @@ function! s:Opener._reuseWindow()
     "check the current tab for the window
     let winnr = bufwinnr('^' . self._path.str() . '$')
     if winnr != -1
-        call nerdtree#exec(winnr . "wincmd w")
+        call nerdtree#exec(winnr . "wincmd w", 0)
         call self._checkToCloseTree(0)
         return 1
     endif
@@ -334,9 +334,9 @@ function! s:Opener._reuseWindow()
     let tabnr = self._path.tabnr()
     if tabnr
         call self._checkToCloseTree(1)
-        call nerdtree#exec(tabnr . 'tabnext')
+        call nerdtree#exec(tabnr . 'tabnext', 1)
         let winnr = bufwinnr('^' . self._path.str() . '$')
-        call nerdtree#exec(winnr . "wincmd w")
+        call nerdtree#exec(winnr . "wincmd w", 0)
         return 1
     endif
 
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/path.vim b/sources_non_forked/nerdtree/lib/nerdtree/path.vim
index c3af1952..d00bb898 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/path.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/path.vim
@@ -380,7 +380,8 @@ endfunction
 function! s:Path.getSortOrderIndex()
     let i = 0
     while i < len(g:NERDTreeSortOrder)
-        if  self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
+        if g:NERDTreeSortOrder[i] !~? '\[\[-\?\(timestamp\|size\|extension\)\]\]' &&
+        \ self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
             return i
         endif
         let i = i + 1
@@ -407,15 +408,26 @@ endfunction
 " FUNCTION: Path.getSortKey() {{{1
 " returns a key used in compare function for sorting
 function! s:Path.getSortKey()
-    let l:ascending = index(g:NERDTreeSortOrder,'[[timestamp]]')
-    let l:descending = index(g:NERDTreeSortOrder,'[[-timestamp]]')
-    if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder || l:ascending >= 0 || l:descending >= 0
-        let self._sortKey = [self.getSortOrderIndex()]
+    if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder
+        " Look for file metadata tags: [[timestamp]], [[extension]], [[size]]
+        let metadata = []
+        for tag in g:NERDTreeSortOrder
+            if tag =~? '\[\[-\?timestamp\]\]'
+                let metadata += [self.isDirectory ? 0 : getftime(self.str()) * (tag =~ '-' ? -1 : 1)]
+            elseif tag =~? '\[\[-\?size\]\]'
+                let metadata += [self.isDirectory ? 0 : getfsize(self.str()) * (tag =~ '-' ? -1 : 1)]
+            elseif tag =~? '\[\[extension\]\]'
+                let extension = matchstr(self.getLastPathComponent(0), '[^.]\+\.\zs[^.]\+$')
+                let metadata += [self.isDirectory ? '' : (extension == '' ? nr2char(str2nr('0x10ffff',16)) : extension)]
+            endif
+        endfor
 
-        if l:descending >= 0
-            call insert(self._sortKey, -getftime(self.str()), l:descending == 0 ? 0 : len(self._sortKey))
-        elseif l:ascending >= 0
-            call insert(self._sortKey, getftime(self.str()), l:ascending == 0 ? 0 : len(self._sortKey))
+        if g:NERDTreeSortOrder[0] =~ '\[\[.*\]\]'
+            " Apply tags' sorting first if specified first.
+            let self._sortKey = metadata + [self.getSortOrderIndex()]
+        else
+            " Otherwise, do regex grouping first.
+            let self._sortKey = [self.getSortOrderIndex()] + metadata
         endif
 
         let path = self.getLastPathComponent(1)
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/tree_dir_node.vim b/sources_non_forked/nerdtree/lib/nerdtree/tree_dir_node.vim
index a834e7c1..aa9dea6a 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/tree_dir_node.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/tree_dir_node.vim
@@ -620,6 +620,11 @@ function! s:TreeDirNode.reveal(path, ...)
 
     if self.path.equals(a:path.getParent())
         let n = self.findNode(a:path)
+        " We may be looking for a newly-saved file that isn't in the tree yet.
+        if n == {}
+            call self.refresh()
+            let n = self.findNode(a:path)
+        endif
         if has_key(opts, "open")
             call n.open()
         endif
diff --git a/sources_non_forked/nerdtree/lib/nerdtree/ui.vim b/sources_non_forked/nerdtree/lib/nerdtree/ui.vim
index 6ff9878e..d384071d 100644
--- a/sources_non_forked/nerdtree/lib/nerdtree/ui.vim
+++ b/sources_non_forked/nerdtree/lib/nerdtree/ui.vim
@@ -6,7 +6,7 @@
 let s:UI = {}
 let g:NERDTreeUI = s:UI
 
-" FUNCTION: s:UI.centerView() {{{2
+" FUNCTION: s:UI.centerView() {{{1
 " centers the nerd tree window around the cursor (provided the nerd tree
 " options permit)
 function! s:UI.centerView()
@@ -28,7 +28,6 @@ function! s:UI._dumpHelp()
         let help .= "\" ============================\n"
         let help .= "\" File node mappings~\n"
         let help .= "\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
-        let help .= "\" <CR>,\n"
         if self.nerdtree.isTabTree()
             let help .= "\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
         else
@@ -44,6 +43,7 @@ function! s:UI._dumpHelp()
         let help .= "\" ". g:NERDTreeMapPreviewSplit .": preview split\n"
         let help .= "\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n"
         let help .= "\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
+        let help .= "\" ". g:NERDTreeMapCustomOpen .": custom open\n"
 
         let help .= "\"\n\" ----------------------------\n"
         let help .= "\" Directory node mappings~\n"
@@ -52,6 +52,7 @@ function! s:UI._dumpHelp()
         let help .= "\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n"
         let help .= "\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
         let help .= "\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+        let help .= "\" ". g:NERDTreeMapCustomOpen .": custom open\n"
         let help .= "\" ". g:NERDTreeMapCloseDir .": close parent of node\n"
         let help .= "\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
         let help .= "\"    current node recursively\n"
@@ -66,6 +67,7 @@ function! s:UI._dumpHelp()
         let help .= "\" ". g:NERDTreeMapPreview .": find dir in tree\n"
         let help .= "\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
         let help .= "\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
+        let help .= "\" ". g:NERDTreeMapCustomOpen .": custom open\n"
         let help .= "\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
 
         let help .= "\"\n\" ----------------------------\n"
@@ -252,7 +254,7 @@ endfunction
 " gets the line number of the root node
 function! s:UI.getRootLineNum()
     let rootLine = 1
-    while getline(rootLine) !~# '^\(/\|<\)'
+    while rootLine <= line('$') && getline(rootLine) !~# '^\(/\|<\)'
         let rootLine = rootLine + 1
     endwhile
     return rootLine
@@ -338,7 +340,7 @@ function! s:UI.restoreScreenState()
     if !has_key(self, '_screenState')
         return
     endif
-    exec("silent vertical resize " . self._screenState['oldWindowSize'])
+    call nerdtree#exec("silent vertical resize " . self._screenState['oldWindowSize'], 1)
 
     let old_scrolloff=&scrolloff
     let &scrolloff=0
@@ -358,7 +360,7 @@ function! s:UI.saveScreenState()
     let self._screenState['oldPos'] = getpos(".")
     let self._screenState['oldTopLine'] = line("w0")
     let self._screenState['oldWindowSize']= winwidth("")
-    call nerdtree#exec(win . "wincmd w")
+    call nerdtree#exec(win . "wincmd w", 1)
 endfunction
 
 " FUNCTION: s:UI.setShowHidden(val) {{{1
@@ -504,10 +506,10 @@ endfunction
 function! s:UI.toggleZoom()
     if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed
         let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
-        exec "silent vertical resize ". size
+        call nerdtree#exec("silent vertical resize ". size, 1)
         let b:NERDTreeZoomed = 0
     else
-        exec "vertical resize ". get(g:, 'NERDTreeWinSizeMax', '')
+        call nerdtree#exec("vertical resize ". get(g:, 'NERDTreeWinSizeMax', ''), 1)
         let b:NERDTreeZoomed = 1
     endif
 endfunction
diff --git a/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim b/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim
index 3eef5176..0a5de8a4 100644
--- a/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim
+++ b/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim
@@ -37,6 +37,7 @@ endif
 if g:NERDTreePath.CopyingSupported()
     call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
 endif
+call NERDTreeAddMenuItem({'text': (has("clipboard")?'copy (p)ath to clipboard':'print (p)ath to screen'), 'shortcut': 'p', 'callback': 'NERDTreeCopyPath'})
 
 if has("unix") || has("osx")
     call NERDTreeAddMenuItem({'text': '(l)ist the current node', 'shortcut': 'l', 'callback': 'NERDTreeListNode'})
@@ -113,14 +114,14 @@ function! s:promptToDelBuffer(bufnum, msg)
             let l:listedBufferCount = 0
         endif
         if l:listedBufferCount > 1
-            exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':bnext! ' | endif"
+            call nerdtree#exec("tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':bnext! ' | endif", 1)
         else
-            exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif"
+            call nerdtree#exec("tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif", 1)
         endif
-        exec "tabnext " . s:originalTabNumber
-        exec s:originalWindowNumber . "wincmd w"
+        call nerdtree#exec("tabnext " . s:originalTabNumber, 1)
+        call nerdtree#exec(s:originalWindowNumber . "wincmd w", 1)
         " 3. We don't need a previous buffer anymore
-        exec "bwipeout! " . a:bufnum
+        call nerdtree#exec("bwipeout! " . a:bufnum, 0)
     endif
 endfunction
 
@@ -140,17 +141,17 @@ function! s:renameBuffer(bufNum, newNodeName, isDirectory)
         let editStr = g:NERDTreePath.New(a:newNodeName).str({'format': 'Edit'})
     endif
     " 1. ensure that a new buffer is loaded
-    exec "badd " . quotedFileName
+    call nerdtree#exec("badd " . quotedFileName, 1)
     " 2. ensure that all windows which display the just deleted filename
     " display a buffer for a new filename.
     let s:originalTabNumber = tabpagenr()
     let s:originalWindowNumber = winnr()
-    exec "tabdo windo if winbufnr(0) == " . a:bufNum . " | exec ':e! " . editStr . "' | endif"
-    exec "tabnext " . s:originalTabNumber
-    exec s:originalWindowNumber . "wincmd w"
+    call nerdtree#exec("tabdo windo if winbufnr(0) == " . a:bufNum . " | exec ':e! " . editStr . "' | endif", 1)
+    call nerdtree#exec("tabnext " . s:originalTabNumber, 1)
+    call nerdtree#exec(s:originalWindowNumber . "wincmd w", 1)
     " 3. We don't need a previous buffer anymore
     try
-        exec "confirm bwipeout " . a:bufNum
+        call nerdtree#exec("confirm bwipeout " . a:bufNum, 0)
     catch
         " This happens when answering Cancel if confirmation is needed. Do nothing.
     endtry
@@ -364,6 +365,17 @@ function! NERDTreeCopyNode()
     redraw!
 endfunction
 
+" FUNCTION: NERDTreeCopyPath() {{{1
+function! NERDTreeCopyPath()
+    let l:nodePath = g:NERDTreeFileNode.GetSelected().path.str()
+    if has("clipboard")
+        let @* = l:nodePath
+        call nerdtree#echo("The path [" . l:nodePath . "] was copied to your clipboard.")
+    else
+        call nerdtree#echo("The full path is: " . l:nodePath)
+    endif
+endfunction
+
 " FUNCTION: NERDTreeQuickLook() {{{1
 function! NERDTreeQuickLook()
     let treenode = g:NERDTreeFileNode.GetSelected()
diff --git a/sources_non_forked/nerdtree/plugin/NERD_tree.vim b/sources_non_forked/nerdtree/plugin/NERD_tree.vim
index 595e780b..a8e26d4e 100644
--- a/sources_non_forked/nerdtree/plugin/NERD_tree.vim
+++ b/sources_non_forked/nerdtree/plugin/NERD_tree.vim
@@ -121,6 +121,7 @@ endif
 
 
 "SECTION: Init variable calls for key mappings {{{2
+call s:initVariable("g:NERDTreeMapCustomOpen", "<CR>")
 call s:initVariable("g:NERDTreeMapActivateNode", "o")
 call s:initVariable("g:NERDTreeMapChangeRoot", "C")
 call s:initVariable("g:NERDTreeMapChdir", "cd")
diff --git a/sources_non_forked/nginx.vim/README.md b/sources_non_forked/nginx.vim/README.md
index 856dff23..58eceefa 100644
--- a/sources_non_forked/nginx.vim/README.md
+++ b/sources_non_forked/nginx.vim/README.md
@@ -1,9 +1,12 @@
 # nginx.vim
 
 ## Description
+
 [Vim](http://www.vim.org/) plugin for [Nginx](http://www.nginx.org)
 
+
 ## Features
+
 The plugin is based on the recent vim-plugin distributed with `nginx-1.12.0` and additionally features the following syntax improvements:
 
 - Highlight IPv4 and IPv6 addresses
@@ -24,6 +27,7 @@ Furthermore:
 
 
 ## Screenshots
+
 A `server` block with highlighting of insecure `ssl_protocol` options:
 ![nginx server block with SSL configuration](https://chr4.org/images/nginx_ssl.png)
 
@@ -37,46 +41,18 @@ Embedded LUA syntax highlighting:
 ![Embedded LUA syntax highlighting](https://chr4.org/images/nginx_lua.png)
 
 
-## Snippets
-The plugin comes with useful snippets which can be accessed using e.g. [vim-snipmate](https://github.com/garbas/vim-snipmate).
-
-Select a decent cipher for your requirements (all of them can provide [SSLLabs A+ ratings](https://www.ssllabs.com/ssltest/analyze.html))
-
-- `ciphers-paranoid<tab>`: Even-more-secure ciphers (elliptic curves, no GCM), not compatible with IE < 11, OpenSSL-0.9.8, Safari < 7, Android != 4.4
-- **`ciphers-modern<tab>`: High-security ciphers (elliptic curves), not compatible with IE < 11, OpenSSL-0.9.8, Safari < 7, Android < 4.4 (recommended)**
-- `ciphers-compat<tab>`: Medium-security ciphers with good compatibility (No IE on WinXP) but TLSv1 and SHA required
-- `ciphers-old<tab>`: Low-security ciphers (using weak DES and SHA ciphers, TLSv1), but compatible with everything but IE6 and Java6
-- `ssl-options<tab>`: Bootstrap secure SSL options
-
-Example:
-```nginx
-# High-security ciphers (elliptic curves), less compatibility
-# No IE < 10, OpenSSL-0.9.8, Safari < 7, Android < 4.4
-ssl_protocols TLSv1.1 TLSv1.2;
-ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
-```
-
-Or add a robots.txt file with `robots.txt<tab>`:
-```nginx
-# Tell bots to not index this site
-location /robots.txt {
-    default_type text/plain;
-    return 200 'User-agent: *\nDisallow: /\n';
-}
-```
-
-It also has auto-completion for location and server blocks with `location<tab>` resp. `server<tab>`, and [many more](https://github.com/chr4/nginx.vim/blob/master/snippets/nginx.snippets)!
-
-- Add useful [snippets](https://github.com/chr4/nginx.vim/blob/master/snippets/nginx.snippets)
-
 ## References
+
 - Based on the original `nginx-1.12.0/contrib/vim`
 - IPv4 and IPv6 address highlighting, based on expressions found in [this forum post](http://vim.1045645.n5.nabble.com/IPv6-support-for-quot-dns-quot-zonefile-syntax-highlighting-td1197292.html)
 - [Blog post](https://chr4.org/blog/2017/04/14/better-syntax-highlighting-and-snippets-for-nginx-in-vim/) introducing this plugin including some more examples
 
+For help with secure cipher selection, visit [Mozillas SSL Configuration Generator](https://ssl-config.mozilla.org/)
+
 ## Installation
 
 ### Pathogen
+
 ```bash
 git clone https://github.com/chr4/nginx.vim ~/.vim/bundle/nginx.vim
 ```
diff --git a/sources_non_forked/nginx.vim/snippets/nginx.snippets b/sources_non_forked/nginx.vim/snippets/nginx.snippets
deleted file mode 100644
index 68b1118a..00000000
--- a/sources_non_forked/nginx.vim/snippets/nginx.snippets
+++ /dev/null
@@ -1,166 +0,0 @@
-# vim: ft=nginx
-snippet l80
-	listen [::]:80 ipv6only=off;
-	$0
-
-# Listen statements when using multiple http server blocks
-snippet l80-multi
-	listen [::]:80 default_server;
-	listen 80 default_server;
-	$0
-
-snippet l443
-	listen [::]:443 ipv6only=off ssl http2 default_server;
-	$0
-
-# Listen statements when using multiple ssl server blocks
-snippet l443-multi
-	listen [::]:443 ssl http2 default_server;
-	listen 443 ssl http2 default_server;
-	$0
-
-# Cipher suites are taken and adapted from Mozilla's recommendations
-# https://wiki.mozilla.org/Security/Server_Side_TLS
-#
-# Paranoid mode
-snippet ciphers-paranoid
-	# Paranoid ciphers, 256bit minimum, prefer ChaCha20/ Poly1305, bad compatibility
-	# No Android 5+6 (4.4 works), Chrome < 51, Firefox < 49, IE < 11, Java 6-8, GoogleBot
-	ssl_protocols TLSv1.2;
-	ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
-	$0
-
-# Mozilla modern
-snippet ciphers-modern
-	# High-security ciphers (elliptic curves), less compatibility
-	# No IE < 10, OpenSSL-0.9.8, Safari < 7, Android < 4.4
-	ssl_protocols TLSv1.1 TLSv1.2;
-	ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
-	$0
-
-# Mozilla intermediate (Removed DES for more security)
-snippet ciphers-compat
-	# Medium-security ciphers with good compatibility (Weak: SHA)
-	# No IE on WinXP
-	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
-	ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';
-	$0
-
-# Mozilla old (Removed DSS, HIGH, SEED for more security)
-snippet ciphers-low
-	# Low-security ciphers (Weak: DES, SHA)
-	# No IE6, Java6
-	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
-	ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!KRB5-DES-CBC3-SHA:!SRP:!DSS';
-	$0
-
-snippet ssl-options
-	# SSL certificate
-	ssl_certificate /etc/nginx/certs/${4:www.example.com}.crt;
-	ssl_certificate_key /etc/nginx/certs/${5:www.example.com}.key;
-	# ssl_dhparam /etc/nginx/certs/dhparam.pem;
-
-	ssl_prefer_server_ciphers on;
-	ssl_stapling off;
-	ssl_stapling_verify off;
-	ssl_session_cache 'shared:SSL:10m';
-	ssl_session_tickets off;
-
-	# Enable HSTS (1 year) and some security options
-	add_header Strict-Transport-Security 'max-age=31536000 includeSubDomains; preload;';
-	$0
-
-snippet security-headers
-	add_header X-Frame-Options 'DENY';
-	add_header X-Content-Type-Options 'nosniff';
-	add_header X-Frame-Options 'SAMEORIGIN';
-	add_header X-XSS-Protection '1; mode=block';
-	add_header X-Robots-Tag 'none';
-	add_header X-Download-Options 'noopen';
-	add_header X-Permitted-Cross-Domain-Policies 'none';
-	$0
-
-snippet robots.txt
-	# Tell bots to not index this site
-	location /robots.txt {
-	    default_type text/plain;
-	    return 200 'User-agent: *\nDisallow: /\n';
-	}
-	$0
-
-snippet basic-auth
-	auth_basic 'Restricted';
-	auth_basic_user_file ${1:/etc/nginx/htpasswd};
-	$0
-
-snippet proxy_pass
-	proxy_pass_header Date;
-	proxy_set_header X-Forwarded-Proto $scheme;
-	proxy_set_header Host $host;
-	proxy_set_header X-Real-IP $remote_addr;
-	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-	proxy_pass http://${1:backend};
-	$0
-
-snippet php-fpm
-	location ~ \.php$ {
-	    include fastcgi_params;
-	    fastcgi_split_path_info ^(.+\.php)(/.+)$;
-	    fastcgi_index index.php;
-	    fastcgi_intercept_errors on;
-	    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-	    fastcgi_pass ${1:127.0.0.1:9000};
-	}
-	$0
-
-snippet php-uwsgi
-	location ~ \.php$ {
-	    include uwsgi_params;
-	    uwsgi_max_temp_file_size 4096m;
-	    uwsgi_modifier1 14;
-	    uwsgi_read_timeout 900;
-	    uwsgi_send_timeout 900;
-	    uwsgi_pass ${1:unix:///run/uwsgi/php.sock};
-	}
-	$0
-
-snippet redirect-ssl
-	location / {
-	    return 301 https://$http_host$request_uri;
-	}
-	$0
-
-snippet redirect-other
-	# Redirect other requested hosts
-	if ($host != '${1:DOMAIN}') {
-	    return 301 https://${2:DOMAIN}$request_uri;
-	}
-	$0
-
-snippet letsencrypt
-	listen [::]:80 ipv6only=off;
-
-	# Serve well-known path for letsencrypt
-	location /.well-known/acme-challenge {
-	    root /etc/nginx/certs/acme;
-	    default_type text/plain;
-	}
-
-	location / {
-	    return 301 https://$http_host$request_uri;
-	}
-	$0
-
-snippet cut-trailing-slash
-	rewrite ^/(.*)/$ $scheme://$http_host:$server_port/$1 permanent;
-	$0
-
-snippet location
-	location ${1:/} {
-	    ${0:${VISUAL}}
-	}
-
-snippet server
-	server {
-	    ${0:${VISUAL}}
-	}
diff --git a/sources_non_forked/vim-bundle-mako/indent/mako.vim b/sources_non_forked/vim-bundle-mako/indent/mako.vim
index 4433cc4a..f1f9482a 100644
--- a/sources_non_forked/vim-bundle-mako/indent/mako.vim
+++ b/sources_non_forked/vim-bundle-mako/indent/mako.vim
@@ -170,66 +170,101 @@ endfun
 " [-- <ELEMENT ? - - ...> --]
 call <SID>HtmlIndentPush('a')
 call <SID>HtmlIndentPush('abbr')
-call <SID>HtmlIndentPush('acronym')
 call <SID>HtmlIndentPush('address')
+call <SID>HtmlIndentPush('applet')
+call <SID>HtmlIndentPush('article')
+call <SID>HtmlIndentPush('aside')
+call <SID>HtmlIndentPush('audio')
 call <SID>HtmlIndentPush('b')
+call <SID>HtmlIndentPush('bdi')
 call <SID>HtmlIndentPush('bdo')
-call <SID>HtmlIndentPush('big')
 call <SID>HtmlIndentPush('blockquote')
 call <SID>HtmlIndentPush('button')
+call <SID>HtmlIndentPush('canvas')
 call <SID>HtmlIndentPush('caption')
-call <SID>HtmlIndentPush('center')
 call <SID>HtmlIndentPush('cite')
 call <SID>HtmlIndentPush('code')
 call <SID>HtmlIndentPush('colgroup')
+call <SID>HtmlIndentPush('content')
+call <SID>HtmlIndentPush('data')
+call <SID>HtmlIndentPush('datalist')
 call <SID>HtmlIndentPush('del')
+call <SID>HtmlIndentPush('details')
 call <SID>HtmlIndentPush('dfn')
+call <SID>HtmlIndentPush('dialog')
 call <SID>HtmlIndentPush('dir')
 call <SID>HtmlIndentPush('div')
 call <SID>HtmlIndentPush('dl')
+call <SID>HtmlIndentPush('element')
 call <SID>HtmlIndentPush('em')
 call <SID>HtmlIndentPush('fieldset')
-call <SID>HtmlIndentPush('font')
+call <SID>HtmlIndentPush('figcaption')
+call <SID>HtmlIndentPush('figure')
+call <SID>HtmlIndentPush('footer')
 call <SID>HtmlIndentPush('form')
-call <SID>HtmlIndentPush('frameset')
 call <SID>HtmlIndentPush('h1')
 call <SID>HtmlIndentPush('h2')
 call <SID>HtmlIndentPush('h3')
 call <SID>HtmlIndentPush('h4')
 call <SID>HtmlIndentPush('h5')
 call <SID>HtmlIndentPush('h6')
+call <SID>HtmlIndentPush('header')
+call <SID>HtmlIndentPush('hgroup')
 call <SID>HtmlIndentPush('i')
 call <SID>HtmlIndentPush('iframe')
 call <SID>HtmlIndentPush('ins')
 call <SID>HtmlIndentPush('kbd')
 call <SID>HtmlIndentPush('label')
 call <SID>HtmlIndentPush('legend')
+call <SID>HtmlIndentPush('li')
+call <SID>HtmlIndentPush('main')
 call <SID>HtmlIndentPush('map')
+call <SID>HtmlIndentPush('mark')
+call <SID>HtmlIndentPush('MediaStream')
 call <SID>HtmlIndentPush('menu')
-call <SID>HtmlIndentPush('noframes')
+call <SID>HtmlIndentPush('menuitem')
+call <SID>HtmlIndentPush('meter')
+call <SID>HtmlIndentPush('nav')
+call <SID>HtmlIndentPush('noembed')
 call <SID>HtmlIndentPush('noscript')
 call <SID>HtmlIndentPush('object')
 call <SID>HtmlIndentPush('ol')
 call <SID>HtmlIndentPush('optgroup')
+call <SID>HtmlIndentPush('option')
+call <SID>HtmlIndentPush('output')
+call <SID>HtmlIndentPush('picture')
 call <SID>HtmlIndentPush('pre')
+call <SID>HtmlIndentPush('progress')
 call <SID>HtmlIndentPush('q')
+call <SID>HtmlIndentPush('rb')
+call <SID>HtmlIndentPush('rp')
+call <SID>HtmlIndentPush('rt')
+call <SID>HtmlIndentPush('rtc')
+call <SID>HtmlIndentPush('ruby')
 call <SID>HtmlIndentPush('s')
 call <SID>HtmlIndentPush('samp')
 call <SID>HtmlIndentPush('script')
+call <SID>HtmlIndentPush('section')
 call <SID>HtmlIndentPush('select')
+call <SID>HtmlIndentPush('shadow')
+call <SID>HtmlIndentPush('slot')
 call <SID>HtmlIndentPush('small')
 call <SID>HtmlIndentPush('span')
 call <SID>HtmlIndentPush('strong')
 call <SID>HtmlIndentPush('style')
 call <SID>HtmlIndentPush('sub')
+call <SID>HtmlIndentPush('summary')
 call <SID>HtmlIndentPush('sup')
 call <SID>HtmlIndentPush('table')
+call <SID>HtmlIndentPush('template')
 call <SID>HtmlIndentPush('textarea')
+call <SID>HtmlIndentPush('time')
 call <SID>HtmlIndentPush('title')
 call <SID>HtmlIndentPush('tt')
 call <SID>HtmlIndentPush('u')
 call <SID>HtmlIndentPush('ul')
 call <SID>HtmlIndentPush('var')
+call <SID>HtmlIndentPush('video')
 
 " For some reason the default HTML indentation script doesn't consider these
 " elements to be worthy of indentation.
@@ -256,6 +291,44 @@ if !exists('g:html_indent_strict_table')
     call <SID>HtmlIndentPush('thead')
 endif
 
+" [-- <OBSOLETE ELEMENTS ? - - ...> --]
+call <SID>HtmlIndentPush('abbr')
+call <SID>HtmlIndentPush('acronym')
+call <SID>HtmlIndentPush('applet')
+call <SID>HtmlIndentPush('audio')
+call <SID>HtmlIndentPush('basefont')
+call <SID>HtmlIndentPush('bgsound')
+call <SID>HtmlIndentPush('big')
+call <SID>HtmlIndentPush('blink')
+call <SID>HtmlIndentPush('center')
+call <SID>HtmlIndentPush('command')
+call <SID>HtmlIndentPush('content')
+call <SID>HtmlIndentPush('dir')
+call <SID>HtmlIndentPush('element')
+call <SID>HtmlIndentPush('embed')
+call <SID>HtmlIndentPush('font')
+call <SID>HtmlIndentPush('frame')
+call <SID>HtmlIndentPush('frameset')
+call <SID>HtmlIndentPush('image')
+call <SID>HtmlIndentPush('img')
+call <SID>HtmlIndentPush('isindex')
+call <SID>HtmlIndentPush('keygen')
+call <SID>HtmlIndentPush('listing')
+call <SID>HtmlIndentPush('marquee')
+call <SID>HtmlIndentPush('menuitem')
+call <SID>HtmlIndentPush('multicol')
+call <SID>HtmlIndentPush('nextid')
+call <SID>HtmlIndentPush('nobr')
+call <SID>HtmlIndentPush('noembed')
+call <SID>HtmlIndentPush('noframes')
+call <SID>HtmlIndentPush('object')
+call <SID>HtmlIndentPush('plaintext')
+call <SID>HtmlIndentPush('shadow')
+call <SID>HtmlIndentPush('spacer')
+call <SID>HtmlIndentPush('strike')
+call <SID>HtmlIndentPush('tt')
+call <SID>HtmlIndentPush('xmp')
+
 " [-- <Mako Elements> --]
 call <SID>MakoIndentPush('%def')
 call <SID>MakoIndentPush('%block')
diff --git a/sources_non_forked/vim-fugitive/autoload/fugitive.vim b/sources_non_forked/vim-fugitive/autoload/fugitive.vim
index 8521f551..b012f20d 100644
--- a/sources_non_forked/vim-fugitive/autoload/fugitive.vim
+++ b/sources_non_forked/vim-fugitive/autoload/fugitive.vim
@@ -8,6 +8,8 @@ let g:autoloaded_fugitive = 1
 
 if !exists('g:fugitive_git_executable')
   let g:fugitive_git_executable = 'git'
+elseif g:fugitive_git_executable =~# '^\w\+='
+  let g:fugitive_git_executable = 'env ' . g:fugitive_git_executable
 endif
 
 " Section: Utility
@@ -44,7 +46,9 @@ function! s:winshell() abort
 endfunction
 
 function! s:shellesc(arg) abort
-  if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
+  if type(a:arg) == type([])
+    return join(map(copy(a:arg), 's:shellesc(v:val)'))
+  elseif a:arg =~ '^[A-Za-z0-9_/:.-]\+$'
     return a:arg
   elseif s:winshell()
     return '"'.s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"').'"'
@@ -55,7 +59,9 @@ endfunction
 
 let s:fnameescape = " \t\n*?[{`$\\%#'\"|!<"
 function! s:fnameescape(file) abort
-  if exists('*fnameescape')
+  if type(a:file) == type([])
+    return join(map(copy(a:file), 's:fnameescape(v:val)'))
+  elseif exists('*fnameescape')
     return fnameescape(a:file)
   else
     return escape(a:file, s:fnameescape)
@@ -63,15 +69,23 @@ function! s:fnameescape(file) abort
 endfunction
 
 function! s:throw(string) abort
-  let v:errmsg = 'fugitive: '.a:string
-  throw v:errmsg
+  throw 'fugitive: '.a:string
 endfunction
 
-function! s:warn(str) abort
-  echohl WarningMsg
-  echomsg a:str
-  echohl None
-  let v:warningmsg = a:str
+function! s:DirCheck(...) abort
+  if empty(a:0 ? s:Dir(a:1) : s:Dir())
+    return 'return ' . string('echoerr "fugitive: not a Git repository"')
+  endif
+  return ''
+endfunction
+
+function! s:Mods(mods, ...) abort
+  let mods = substitute(a:mods, '\C<mods>', '', '')
+  let mods = mods =~# '\S$' ? mods . ' ' : mods
+  if a:0 && mods !~# '\<\%(aboveleft\|belowright\|leftabove\|rightbelow\|topleft\|botright\|tab\)\>'
+    let mods = a:1 . ' ' . mods
+  endif
+  return substitute(mods, '\s\+', ' ', 'g')
 endfunction
 
 function! s:Slash(path) abort
@@ -82,27 +96,19 @@ function! s:Slash(path) abort
   endif
 endfunction
 
-function! s:PlatformSlash(path) abort
-  if exists('+shellslash') && !&shellslash
-    return tr(a:path, '/', '\')
-  else
-    return a:path
-  endif
-endfunction
-
 function! s:Resolve(path) abort
   let path = resolve(a:path)
   if has('win32')
-    let path = s:PlatformSlash(fnamemodify(fnamemodify(path, ':h'), ':p') . fnamemodify(path, ':t'))
+    let path = FugitiveVimPath(fnamemodify(fnamemodify(path, ':h'), ':p') . fnamemodify(path, ':t'))
   endif
   return path
 endfunction
 
 function! s:cpath(path, ...) abort
   if exists('+fileignorecase') && &fileignorecase
-    let path = s:PlatformSlash(tolower(a:path))
+    let path = FugitiveVimPath(tolower(a:path))
   else
-    let path = s:PlatformSlash(a:path)
+    let path = FugitiveVimPath(a:path)
   endif
   return a:0 ? path ==# s:cpath(a:1) : path
 endfunction
@@ -129,59 +135,119 @@ function! s:executable(binary) abort
   return s:executables[a:binary]
 endfunction
 
-function! s:map(mode, lhs, rhs, ...) abort
-  let flags = (a:0 ? a:1 : '') . (a:rhs =~# '<Plug>' ? '' : '<script>')
-  let head = a:lhs
-  let tail = ''
-  let keys = get(g:, a:mode.'remap', {})
-  if type(keys) == type([])
-    return
-  endif
-  while !empty(head)
-    if has_key(keys, head)
-      let head = keys[head]
-      if empty(head)
-        return
+let s:nowait = v:version >= 704 ? '<nowait>' : ''
+
+function! s:Map(mode, lhs, rhs, ...) abort
+  for mode in split(a:mode, '\zs')
+    let flags = (a:0 ? a:1 : '') . (a:rhs =~# '<Plug>' ? '' : '<script>')
+    let head = a:lhs
+    let tail = ''
+    let keys = get(g:, mode.'remap', {})
+    if type(keys) == type([])
+      return
+    endif
+    while !empty(head)
+      if has_key(keys, head)
+        let head = keys[head]
+        if empty(head)
+          return
+        endif
+        break
+      endif
+      let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
+      let head = substitute(head, '<[^<>]*>$\|.$', '', '')
+    endwhile
+    if flags !~# '<unique>' || empty(mapcheck(head.tail, mode))
+      exe mode.'map <buffer>' s:nowait flags head.tail a:rhs
+      if a:0 > 1
+        let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') .
+              \ '|sil! exe "' . mode . 'unmap <buffer> ' . head.tail . '"'
       endif
-      break
-    endif
-    let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
-    let head = substitute(head, '<[^<>]*>$\|.$', '', '')
-  endwhile
-  if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
-    exe a:mode.'map <buffer>' flags head.tail a:rhs
-    if a:0 > 1
-      let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') .
-            \ '|sil! exe "' . a:mode . 'unmap <buffer> ' . head.tail . '"'
     endif
+  endfor
+endfunction
+
+" Section: Quickfix
+
+function! s:QuickfixGet(nr, ...) abort
+  if a:nr < 0
+    return call('getqflist', a:000)
+  else
+    return call('getloclist', [a:nr] + a:000)
   endif
 endfunction
 
-function! s:System(cmd) abort
-  try
-    return system(a:cmd)
-  catch /^Vim\%((\a\+)\)\=:E484:/
-    let opts = ['shell', 'shellcmdflag', 'shellredir', 'shellquote', 'shellxquote', 'shellxescape', 'shellslash']
-    call filter(opts, 'exists("+".v:val) && !empty(eval("&".v:val))')
-    call map(opts, 'v:val."=".eval("&".v:val)')
-    call s:throw('failed to run `' . a:cmd . '` with ' . join(opts, ' '))
-  endtry
+function! s:QuickfixSet(nr, ...) abort
+  if a:nr < 0
+    return call('setqflist', a:000)
+  else
+    return call('setloclist', [a:nr] + a:000)
+  endif
+endfunction
+
+function! s:QuickfixCreate(nr, opts) abort
+  if has('patch-7.4.2200')
+    call s:QuickfixSet(a:nr, [], ' ', a:opts)
+  else
+    call s:QuickfixSet(a:nr, [], ' ')
+  endif
+endfunction
+
+function! s:QuickfixStream(nr, title, cmd, first, callback, ...) abort
+  call s:QuickfixCreate(a:nr, {'title': a:title})
+  let winnr = winnr()
+  exe a:nr < 0 ? 'copen' : 'lopen'
+  if winnr != winnr()
+    wincmd p
+  endif
+
+  let buffer = []
+  let lines = split(s:SystemError(s:shellesc(a:cmd))[0], "\n")
+  for line in lines
+    call extend(buffer, call(a:callback, a:000 + [line]))
+    if len(buffer) >= 20
+      call s:QuickfixSet(a:nr, remove(buffer, 0, -1), 'a')
+      redraw
+    endif
+  endfor
+  call s:QuickfixSet(a:nr, extend(buffer, call(a:callback, a:000 + [0])), 'a')
+
+  if a:first && len(s:QuickfixGet(a:nr))
+    call s:BlurStatus()
+    return a:nr < 0 ? 'cfirst' : 'lfirst'
+  else
+    return 'exe'
+  endif
 endfunction
 
 " Section: Git
 
-function! s:UserCommand() abort
-  return get(g:, 'fugitive_git_command', g:fugitive_git_executable)
+function! s:UserCommandList(...) abort
+  let git = split(get(g:, 'fugitive_git_command', g:fugitive_git_executable), '\s\+')
+  let dir = a:0 ? s:Dir(a:1) : ''
+  if len(dir)
+    let tree = s:Tree(dir)
+    if empty(tree)
+      call add(git, '--git-dir=' . FugitiveGitPath(dir))
+    elseif len(tree) && s:cpath(tree) !=# s:cpath(getcwd())
+      if fugitive#GitVersion(1, 8, 5)
+        call extend(git, ['-C', FugitiveGitPath(tree)])
+      else
+        throw 'fugitive: Git 1.8.5 or higher required to change directory'
+      endif
+    endif
+  endif
+  return git
 endfunction
 
-function! s:Prepare(...) abort
-  return call('fugitive#Prepare', a:000)
+function! s:UserCommand(...) abort
+  return s:shellesc(call('s:UserCommandList', a:0 ? [a:1] : []) + (a:0 ? a:2 : []))
 endfunction
 
 let s:git_versions = {}
 function! fugitive#GitVersion(...) abort
   if !has_key(s:git_versions, g:fugitive_git_executable)
-    let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), '\d\S\+')
+    let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), '\d[^[:space:]]\+')
   endif
   if !a:0
     return s:git_versions[g:fugitive_git_executable]
@@ -209,11 +275,11 @@ function! fugitive#CommonDir(dir) abort
     if getfsize(a:dir . '/HEAD') < 10
       let s:commondirs[a:dir] = ''
     elseif filereadable(a:dir . '/commondir')
-      let dir = get(readfile(a:dir . '/commondir', 1), 0, '')
-      if dir =~# '^/\|^\a:/'
-        let s:commondirs[a:dir] = dir
+      let cdir = get(readfile(a:dir . '/commondir', 1), 0, '')
+      if cdir =~# '^/\|^\a:/'
+        let s:commondirs[a:dir] = s:Slash(FugitiveVimPath(cdir))
       else
-        let s:commondirs[a:dir] = simplify(a:dir . '/' . dir)
+        let s:commondirs[a:dir] = simplify(a:dir . '/' . cdir)
       endif
     else
       let s:commondirs[a:dir] = a:dir
@@ -230,12 +296,33 @@ function! s:Tree(...) abort
   return a:0 ? FugitiveWorkTree(a:1) : FugitiveWorkTree()
 endfunction
 
+function! s:HasOpt(args, ...) abort
+  let args = a:args[0 : index(a:args, '--')]
+  let opts = copy(a:000)
+  if type(opts[0]) == type([])
+    if empty(args) || index(opts[0], args[0]) == -1
+      return 0
+    endif
+    call remove(opts, 0)
+  endif
+  for opt in opts
+    if index(args, opt) != -1
+      return 1
+    endif
+  endfor
+endfunction
+
 function! s:PreparePathArgs(cmd, dir, literal) abort
   let literal_supported = fugitive#GitVersion(1, 9)
   if a:literal && literal_supported
     call insert(a:cmd, '--literal-pathspecs')
   endif
   let split = index(a:cmd, '--')
+  for i in range(split < 0 ? len(a:cmd) : split)
+    if type(a:cmd[i]) == type(0)
+      let a:cmd[i] = fugitive#Path(bufname(a:cmd[i]), './', a:dir)
+    endif
+  endfor
   if split < 0
     return a:cmd
   endif
@@ -256,20 +343,19 @@ let s:prepare_env = {
       \ 'core.editor': 'GIT_EDITOR',
       \ 'core.askpass': 'GIT_ASKPASS',
       \ }
-function! fugitive#Prepare(...) abort
-  if !a:0
-    return g:fugitive_git_executable
-  endif
-  if type(a:1) ==# type([])
+function! fugitive#PrepareDirEnvArgv(...) abort
+  if a:0 && type(a:1) ==# type([])
     let cmd = a:000[1:-1] + a:1
   else
     let cmd = copy(a:000)
   endif
-  let pre = ''
+  let env = {}
   let i = 0
   while i < len(cmd)
     if cmd[i] =~# '^$\|[\/.]' && cmd[i] !~# '^-'
       let dir = remove(cmd, 0)
+    elseif cmd[i] =~# '^--git-dir='
+      let dir = remove(cmd, 0)[10:-1]
     elseif type(cmd[i]) ==# type(0)
       let dir = s:Dir(remove(cmd, i))
     elseif cmd[i] ==# '-c' && len(cmd) > i + 1
@@ -277,11 +363,7 @@ function! fugitive#Prepare(...) abort
       if has_key(s:prepare_env, tolower(key)) || key !~# '\.'
         let var = get(s:prepare_env, tolower(key), key)
         let val = matchstr(cmd[i+1], '=\zs.*')
-        if s:winshell()
-          let pre .= 'set ' . var . '=' . s:shellesc(val) . ' & '
-        else
-          let pre = (len(pre) ? pre : 'env ') . var . '=' . s:shellesc(val) . ' '
-        endif
+        let env[var] = val
       endif
       if fugitive#GitVersion(1, 8) && cmd[i+1] =~# '\.'
         let i += 2
@@ -304,32 +386,105 @@ function! fugitive#Prepare(...) abort
   if !exists('dir')
     let dir = s:Dir()
   endif
-  let tree = s:Tree(dir)
   call s:PreparePathArgs(cmd, dir, !exists('explicit_pathspec_option'))
-  let args = join(map(copy(cmd), 's:shellesc(v:val)'))
+  return [dir, env, cmd]
+endfunction
+
+function! s:BuildShell(dir, env, args) abort
+  let cmd = copy(a:args)
+  let tree = s:Tree(a:dir)
+  let pre = ''
+  for [var, val] in items(a:env)
+    if s:winshell()
+      let pre .= 'set ' . var . '=' . s:shellesc(val) . '& '
+    else
+      let pre = (len(pre) ? pre : 'env ') . var . '=' . s:shellesc(val) . ' '
+    endif
+  endfor
   if empty(tree) || index(cmd, '--') == len(cmd) - 1
-    let args = s:shellesc('--git-dir=' . dir) . ' ' . args
-  elseif fugitive#GitVersion(1, 9)
-    let args = '-C ' . s:shellesc(tree) . ' ' . args
+    call insert(cmd, '--git-dir=' . FugitiveGitPath(a:dir))
+  elseif fugitive#GitVersion(1, 8, 5)
+    call extend(cmd, ['-C', FugitiveGitPath(tree)], 'keep')
   else
-    let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? ' & ' : '; ') . pre
+    let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? '& ' : '; ') . pre
   endif
-  return pre . g:fugitive_git_executable . ' ' . args
+  return pre . g:fugitive_git_executable . ' ' . join(map(cmd, 's:shellesc(v:val)'))
+endfunction
+
+function! fugitive#Prepare(...) abort
+  let [dir, env, argv] = call('fugitive#PrepareDirEnvArgv', a:000)
+  return s:BuildShell(dir, env, argv)
+endfunction
+
+function! s:SystemError(cmd, ...) abort
+  try
+    if &shellredir ==# '>' && &shell =~# 'sh\|cmd'
+      let shellredir = &shellredir
+      if &shell =~# 'csh'
+        set shellredir=>&
+      else
+        set shellredir=>%s\ 2>&1
+      endif
+    endif
+    let out = call('system', [type(a:cmd) ==# type([]) ? fugitive#Prepare(a:cmd) : a:cmd] + a:000)
+    return [out, v:shell_error]
+  catch /^Vim\%((\a\+)\)\=:E484:/
+    let opts = ['shell', 'shellcmdflag', 'shellredir', 'shellquote', 'shellxquote', 'shellxescape', 'shellslash']
+    call filter(opts, 'exists("+".v:val) && !empty(eval("&".v:val))')
+    call map(opts, 'v:val."=".eval("&".v:val)')
+    call s:throw('failed to run `' . a:cmd . '` with ' . join(opts, ' '))
+  finally
+    if exists('shellredir')
+      let &shellredir = shellredir
+    endif
+  endtry
+endfunction
+
+function! s:ChompError(...) abort
+  let [out, exec_error] = s:SystemError(call('fugitive#Prepare', a:000))
+  return [s:sub(out, '\n$', ''), exec_error]
+endfunction
+
+function! s:ChompDefault(default, ...) abort
+  let [out, exec_error] = call('s:ChompError', a:000)
+  return exec_error ? a:default : out
+endfunction
+
+function! s:LinesError(...) abort
+  let [out, exec_error] = call('s:ChompError', a:000)
+  return [len(out) && !exec_error ? split(out, "\n", 1) : [], exec_error]
+endfunction
+
+function! s:NullError(...) abort
+  let [out, exec_error] = s:SystemError(call('fugitive#Prepare', a:000))
+  return [exec_error ? [] : split(out, "\1"), exec_error ? substitute(out, "\n$", "", "") : '', exec_error]
 endfunction
 
 function! s:TreeChomp(...) abort
-  return s:sub(s:System(call('fugitive#Prepare', a:000)), '\n$', '')
+  let cmd = call('fugitive#Prepare', a:000)
+  let [out, exec_error] = s:SystemError(cmd)
+  let out = s:sub(out, '\n$', '')
+  if !exec_error
+    return out
+  endif
+  throw 'fugitive: error running `' . cmd . '`: ' . out
+endfunction
+
+function! s:EchoExec(...) abort
+  echo call('s:ChompError', a:000)[0]
+  call fugitive#ReloadStatus(-1, 1)
+  return 'checktime'
 endfunction
 
 function! fugitive#Head(...) abort
   let dir = a:0 > 1 ? a:2 : s:Dir()
-  if empty(dir) || !filereadable(dir . '/HEAD')
+  if empty(dir) || !filereadable(fugitive#Find('.git/HEAD', dir))
     return ''
   endif
-  let head = readfile(dir . '/HEAD')[0]
+  let head = readfile(fugitive#Find('.git/HEAD', dir))[0]
   if head =~# '^ref: '
     return substitute(head, '\C^ref: \%(refs/\%(heads/\|remotes/\|tags/\)\=\)\=', '', '')
-  elseif head =~# '^\x\{40\}$'
+  elseif head =~# '^\x\{40,\}$'
     let len = a:0 ? a:1 : 0
     return len < 0 ? head : len ? head[0:len-1] : ''
   else
@@ -338,11 +493,11 @@ function! fugitive#Head(...) abort
 endfunction
 
 function! fugitive#RevParse(rev, ...) abort
-  let hash = system(s:Prepare(a:0 ? a:1 : s:Dir(), 'rev-parse', '--verify', a:rev, '--'))[0:-2]
-  if !v:shell_error && hash =~# '^\x\{40\}$'
+  let [hash, exec_error] = s:ChompError([a:0 ? a:1 : s:Dir(), 'rev-parse', '--verify', a:rev, '--'])
+  if !exec_error && hash =~# '^\x\{40,\}$'
     return hash
   endif
-  call s:throw('rev-parse '.a:rev.': '.hash)
+  throw 'fugitive: rev-parse '.a:rev.': '.hash
 endfunction
 
 function! s:ConfigTimestamps(dir, dict) abort
@@ -378,8 +533,8 @@ function! fugitive#Config(...) abort
     let dict = s:config[key][1]
   else
     let dict = {}
-    let lines = split(system(FugitivePrepare(['config', '--list', '-z'], dir)), "\1")
-    if v:shell_error
+    let [lines, message, exec_error] = s:NullError([dir, 'config', '--list', '-z'])
+    if exec_error
       return {}
     endif
     for line in lines
@@ -413,9 +568,7 @@ function! fugitive#RemoteUrl(...) abort
   if !fugitive#GitVersion(2, 7)
     return fugitive#Config('remote.' . remote . '.url')
   endif
-  let cmd = s:Prepare(dir, 'remote', 'get-url', remote, '--')
-  let out = substitute(system(cmd), "\n$", '', '')
-  return v:shell_error ? '' : out
+  return s:ChompDefault('', [dir, 'remote', 'get-url', remote, '--'])
 endfunction
 
 " Section: Repository Object
@@ -426,12 +579,30 @@ function! s:add_methods(namespace, method_names) abort
   endfor
 endfunction
 
+function! s:Command(command, line1, line2, range, bang, mods, arg, args) abort
+  try
+    if a:command =~# '^\l[[:alnum:]-]\+$'
+      return s:GitCommand(a:line1, a:line2, a:range, a:line2, a:bang, s:Mods(a:mods), '', a:command . ' ' . a:arg, [a:command] + a:args)
+    endif
+    return s:{a:command}Command(a:line1, a:line2, a:range, a:line2, a:bang, s:Mods(a:mods), '', a:arg, a:args)
+  catch /^fugitive:/
+    return 'echoerr ' . string(v:exception)
+  endtry
+endfunction
+
 let s:commands = []
 function! s:command(definition, ...) abort
+  let def = a:definition
+  if !has('patch-7.4.542')
+    let def = substitute(def, '-addr=\S\+ ', '', '')
+  endif
+  if !has('patch-8.1.560')
+    let def = substitute(def, '-addr=other ', '', '')
+  endif
   if a:0
-    call add(s:commands, a:definition . ' execute s:' . a:1 . "Command(<line1>, <line2>, +'<range>', <count>, <bang>0, '<mods>', <q-reg>, <q-args>, [<f-args>])")
+    call add(s:commands, def . ' execute s:Command(' . string(a:1) . ", <line1>, <count>, +'<range>', <bang>0, '<mods>', <q-args>, [<f-args>])")
   else
-    call add(s:commands, a:definition)
+    call add(s:commands, def)
   endif
 endfunction
 
@@ -445,7 +616,7 @@ let s:repo_prototype = {}
 let s:repos = {}
 
 function! fugitive#repo(...) abort
-  let dir = a:0 ? a:1 : (len(s:Dir()) ? s:Dir() : FugitiveExtractGitDir(expand('%:p')))
+  let dir = a:0 ? s:Dir(a:1) : (len(s:Dir()) ? s:Dir() : FugitiveExtractGitDir(expand('%:p')))
   if dir !=# ''
     if has_key(s:repos, dir)
       let repo = get(s:repos, dir)
@@ -455,7 +626,7 @@ function! fugitive#repo(...) abort
     endif
     return extend(repo, s:repo_prototype, 'keep')
   endif
-  call s:throw('not a Git repository: ' . string(dir))
+  call s:throw('not a Git repository')
 endfunction
 
 function! s:repo_dir(...) dict abort
@@ -505,7 +676,7 @@ endfunction
 function! s:repo_git_chomp(...) dict abort
   let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
   let output = git . join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
-  return s:sub(s:System(output),'\n$','')
+  return s:sub(system(output), '\n$', '')
 endfunction
 
 function! s:repo_git_chomp_in_tree(...) dict abort
@@ -544,7 +715,7 @@ call s:add_methods('repo',['config', 'user'])
 " Section: File API
 
 function! s:DirCommitFile(path) abort
-  let vals = matchlist(s:Slash(a:path), '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\x\{40\}\|[0-3]\)\(/.*\)\=$')
+  let vals = matchlist(s:Slash(a:path), '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\x\{40,\}\|[0-3]\)\(/.*\)\=$')
   if empty(vals)
     return ['', '', '']
   endif
@@ -561,16 +732,17 @@ function! s:Owner(path, ...) abort
   if empty(dir)
     return ''
   endif
+  let actualdir = fugitive#Find('.git/', dir)
   let [pdir, commit, file] = s:DirCommitFile(a:path)
   if s:cpath(dir, pdir)
-    if commit =~# '^\x\{40\}$'
+    if commit =~# '^\x\{40,\}$'
       return commit
     elseif commit ==# '2'
       return 'HEAD^{}'
     endif
-    if filereadable(dir . '/MERGE_HEAD')
+    if filereadable(actualdir . 'MERGE_HEAD')
       let merge_head = 'MERGE_HEAD'
-    elseif filereadable(dir . '/REBASE_HEAD')
+    elseif filereadable(actualdir . 'REBASE_HEAD')
       let merge_head = 'REBASE_HEAD'
     else
       return ''
@@ -582,10 +754,10 @@ function! s:Owner(path, ...) abort
     endif
   endif
   let path = fnamemodify(a:path, ':p')
-  if s:cpath(dir . '/', path[0 : len(dir)]) && a:path =~# 'HEAD$'
-    return strpart(path, len(dir) + 1)
+  if s:cpath(actualdir, strpart(path, 0, len(actualdir))) && a:path =~# 'HEAD$'
+    return strpart(path, len(actualdir))
   endif
-  let refs = fugitive#CommonDir(dir) . '/refs'
+  let refs = fugitive#Find('.git/refs', dir)
   if s:cpath(refs . '/', path[0 : len(refs)]) && path !~# '[\/]$'
     return strpart(path, len(refs) - 4)
   endif
@@ -599,7 +771,7 @@ function! fugitive#Real(url) abort
   let [dir, commit, file] = s:DirCommitFile(a:url)
   if len(dir)
     let tree = s:Tree(dir)
-    return s:PlatformSlash((len(tree) ? tree : dir) . file)
+    return FugitiveVimPath((len(tree) ? tree : dir) . file)
   endif
   let pre = substitute(matchstr(a:url, '^\a\a\+\ze:'), '^.', '\u&', '')
   if len(pre) && pre !=? 'fugitive' && exists('*' . pre . 'Real')
@@ -607,7 +779,7 @@ function! fugitive#Real(url) abort
   else
     let url = fnamemodify(a:url, ':p' . (a:url =~# '[\/]$' ? '' : ':s?[\/]$??'))
   endif
-  return s:PlatformSlash(empty(url) ? a:url : url)
+  return FugitiveVimPath(empty(url) ? a:url : url)
 endfunction
 
 function! fugitive#Path(url, ...) abort
@@ -635,8 +807,9 @@ function! fugitive#Path(url, ...) abort
     return a:1[0:-2] . path
   endif
   let url = a:url
-  if has_key(get(s:temp_files, s:cpath(url), {}), 'bufnr')
-    let url = bufname(s:temp_files[s:cpath(url)].bufnr)
+  let temp_state = s:TempState(url)
+  if has_key(temp_state, 'bufnr')
+    let url = bufname(temp_state.bufnr)
   endif
   let url = s:Slash(fnamemodify(url, ':p'))
   if url =~# '/$' && s:Slash(a:url) !~# '/$'
@@ -653,34 +826,34 @@ function! fugitive#Path(url, ...) abort
     let file = '/'
   endif
   if empty(file) && a:1 =~# '^$\|^[.:]/$'
-    return s:Slash(fugitive#Real(a:url))
+    return FugitiveGitPath(fugitive#Real(a:url))
   endif
   return substitute(file, '^/', a:1, '')
 endfunction
 
 function! s:Relative(...) abort
-  return fugitive#Path(@%, a:0 ? a:1 : ':(top)')
+  return fugitive#Path(@%, a:0 ? a:1 : ':(top)', a:0 > 1 ? a:2 : s:Dir())
 endfunction
 
 function! fugitive#Find(object, ...) abort
   if type(a:object) == type(0)
     let name = bufname(a:object)
-    return s:PlatformSlash(name =~# '^$\|^/\|^\a\+:' ? name : getcwd() . '/' . name)
+    return FugitiveVimPath(name =~# '^$\|^/\|^\a\+:' ? name : getcwd() . '/' . name)
   elseif a:object =~# '^[~$]'
     let prefix = matchstr(a:object, '^[~$]\i*')
     let owner = expand(prefix)
-    return s:PlatformSlash((len(owner) ? owner : prefix) . strpart(a:object, len(prefix)))
+    return FugitiveVimPath((len(owner) ? owner : prefix) . strpart(a:object, len(prefix)))
   elseif s:Slash(a:object) =~# '^$\|^/\|^\%(\a\a\+:\).*\%(//\|::\)' . (has('win32') ? '\|^\a:/' : '')
-    return s:PlatformSlash(a:object)
+    return FugitiveVimPath(a:object)
   elseif s:Slash(a:object) =~# '^\.\.\=\%(/\|$\)'
-    return s:PlatformSlash(simplify(getcwd() . '/' . a:object))
+    return FugitiveVimPath(simplify(getcwd() . '/' . a:object))
   endif
   let dir = a:0 ? a:1 : s:Dir()
   if empty(dir)
     let file = matchstr(a:object, '^\%(:\d:\|[^:]*:\)\zs.*', '', '')
     let dir = FugitiveExtractGitDir(file)
     if empty(dir)
-      return fnamemodify(len(file) ? file : a:object, ':p')
+      return fnamemodify(FugitiveVimPath(len(file) ? file : a:object), ':p')
     endif
   endif
   let rev = s:Slash(a:object)
@@ -697,7 +870,8 @@ function! fugitive#Find(object, ...) abort
       let f = base . f[3:-1]
     elseif cdir !=# dir && (
           \ f =~# '^/\%(config\|hooks\|info\|logs/refs\|objects\|refs\|worktrees\)\%(/\|$\)' ||
-          \ f !~# '^/logs$\|/\w*HEAD$' && getftime(dir . f) < 0 && getftime(cdir . f) >= 0)
+          \ f !~# '^/\%(index$\|index\.lock$\|\w*MSG$\|\w*HEAD$\|logs/\w*HEAD$\|logs$\|rebase-\w\+\)\%(/\|$\)' &&
+          \ getftime(FugitiveVimPath(dir . f)) < 0 && getftime(FugitiveVimPath(cdir . f)) >= 0)
       let f = simplify(cdir . f)
     else
       let f = simplify(dir . f)
@@ -728,22 +902,21 @@ function! fugitive#Find(object, ...) abort
     if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && s:cpath(fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(dir)]) ==# s:cpath(dir . '/') && filereadable($GIT_INDEX_FILE)
       let f = fnamemodify($GIT_INDEX_FILE, ':p')
     else
-      let f = dir . '/index'
+      let f = fugitive#Find('.git/index', dir)
     endif
   elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))'
-    let f = base . '/' . matchstr(rev, ')\zs.*')
+    let f = matchstr(rev, ')\zs.*')
+    if f=~# '^\.\.\=\%(/\|$\)'
+      let f = simplify(getcwd() . '/' . f)
+    elseif f !~# '^/\|^\%(\a\a\+:\).*\%(//\|::\)' . (has('win32') ? '\|^\a:/' : '')
+      let f = base . '/' . f
+    endif
   elseif rev =~# '^:/\@!'
     let f = 'fugitive://' . dir . '//0/' . rev[1:-1]
   else
-    if rev =~# 'HEAD$\|^refs/' && rev !~# ':'
-      let cdir = rev =~# '^refs/' ? fugitive#CommonDir(dir) : dir
-      if filereadable(cdir . '/' . rev)
-        let f = simplify(cdir . '/' . rev)
-      endif
-    endif
     if !exists('f')
-      let commit = substitute(matchstr(rev, '^[^:]\+\|^:.*'), '^@\%($\|[~^]\|@{\)\@=', 'HEAD', '')
-      let file = substitute(matchstr(rev, '^[^:]\+\zs:.*'), '^:', '/', '')
+      let commit = substitute(matchstr(rev, '^[^:.-][^:]*\|^:.*'), '^@\%($\|[~^]\|@{\)\@=', 'HEAD', '')
+      let file = substitute(matchstr(rev, '^[^:.-][^:]*\zs:.*'), '^:', '/', '')
       if file =~# '^/\.\.\=\%(/\|$\)\|^//\|^/\a\+:'
         let file = file =~# '^/\.' ? simplify(getcwd() . file) : file[1:-1]
         if s:cpath(base . '/', (file . '/')[0 : len(base)])
@@ -756,9 +929,13 @@ function! fugitive#Find(object, ...) abort
           return file
         endif
       endif
-      if commit !~# '^[0-9a-f]\{40\}$'
-        let commit = system(s:Prepare(dir, 'rev-parse', '--verify', commit, '--'))[0:-2]
-        let commit = v:shell_error ? '' : commit
+      let commits = split(commit, '\.\.\.-\@!', 1)
+      if len(commits) == 2
+        call map(commits, 'empty(v:val) || v:val ==# "@" ? "HEAD" : v:val')
+        let commit = matchstr(s:ChompDefault('', [dir, 'merge-base'] + commits + ['--']), '\<[0-9a-f]\{40,\}\>')
+      endif
+      if commit !~# '^[0-9a-f]\{40,\}$'
+        let commit = matchstr(s:ChompDefault('', [dir, 'rev-parse', '--verify', commit, '--']), '\<[0-9a-f]\{40,\}\>')
       endif
       if len(commit)
         let f = 'fugitive://' . dir . '//' . commit . file
@@ -767,25 +944,17 @@ function! fugitive#Find(object, ...) abort
       endif
     endif
   endif
-  return s:PlatformSlash(f)
+  return FugitiveVimPath(f)
 endfunction
 
 function! s:Generate(rev, ...) abort
-  let dir = a:0 ? a:1 : s:Dir()
-  let tree = s:Tree(dir)
-  let object = a:rev
-  if a:rev =~# '^/\.git\%(/\|$\)'
-    let object = a:rev[1:-1]
-  elseif a:rev =~# '^/' && len(tree) && getftime(tree . a:rev) >= 0 && getftime(a:rev) < 0
-    let object = ':(top)' . a:rev[1:-1]
-  endif
-  return fugitive#Find(object, dir)
+  return fugitive#Find(a:rev, a:0 ? a:1 : s:Dir())
 endfunction
 
-function! s:DotRelative(path) abort
-  let cwd = getcwd()
+function! s:DotRelative(path, ...) abort
+  let cwd = a:0 ? a:1 : getcwd()
   let path = substitute(a:path, '^[~$]\i*', '\=expand(submatch(0))', '')
-  if s:cpath(cwd . '/', (path . '/')[0 : len(cwd)])
+  if len(cwd) && s:cpath(cwd . '/', (path . '/')[0 : len(cwd)])
     return '.' . strpart(path, len(cwd))
   endif
   return a:path
@@ -801,13 +970,8 @@ function! fugitive#Object(...) abort
   if empty(rev) && empty(tree)
   elseif empty(rev)
     let rev = fugitive#Path(a:0 ? a:1 : @%, './', dir)
-    let cdir = fugitive#CommonDir(dir)
-    if rev =~# '^\./\.git/refs/\%(tags\|heads\|remotes\)/.\|^\./\.git/\w*HEAD$'
-      let rev = rev[7:-1]
-    elseif s:cpath(cdir . '/refs/', rev[0 : len(cdir)])
-      let rev = strpart(rev, len(cdir)+1)
-    elseif rev =~# '^\./.git\%(/\|$\)'
-      return fnamemodify(a:0 ? a:1 : @%, ':p')
+    if rev =~# '^\./.git\%(/\|$\)'
+      return fnamemodify(a:0 ? a:1 : @%, ':p' . (rev =~# '/$' ? '' : ':s?/$??'))
     endif
   endif
   if rev !~# '^\.\%(/\|$\)' || s:cpath(getcwd(), tree)
@@ -823,30 +987,43 @@ let s:expand = '\%(\(' . s:var . '\)\(' . s:flag . '*\)\(:S\)\=\)'
 
 function! s:BufName(var) abort
   if a:var ==# '%'
-    return bufname(get(b:, 'fugitive_blamed_bufnr', ''))
+    return bufname(get(s:TempState(), 'bufnr', ''))
   elseif a:var =~# '^#\d*$'
-    let nr = getbufvar(+a:var[1:-1], 'fugitive_blamed_bufnr', '')
+    let nr = get(s:TempState(bufname(+a:var[1:-1])), 'bufnr', '')
     return bufname(nr ? nr : +a:var[1:-1])
   else
     return expand(a:var)
   endif
 endfunction
 
-function! s:ExpandVar(other, var, flags, esc) abort
+function! s:ExpandVarLegacy(str) abort
+  if get(g:, 'fugitive_legacy_quoting', 1)
+    return substitute(a:str, '\\\ze[%#!]', '', 'g')
+  else
+    return a:str
+  endif
+endfunction
+
+function! s:ExpandVar(other, var, flags, esc, ...) abort
+  let cwd = a:0 ? a:1 : getcwd()
   if a:other =~# '^\'
     return a:other[1:-1]
+  elseif a:other =~# '^'''
+    return s:ExpandVarLegacy(substitute(a:other[1:-2], "''", "'", "g"))
+  elseif a:other =~# '^"'
+    return s:ExpandVarLegacy(substitute(a:other[1:-2], '""', '"', "g"))
   elseif a:other =~# '^!'
     let buffer = s:BufName(len(a:other) > 1 ? '#'. a:other[1:-1] : '%')
     let owner = s:Owner(buffer)
     return len(owner) ? owner : '@'
   endif
   let flags = a:flags
-  let file = s:DotRelative(fugitive#Real(s:BufName(a:var)))
+  let file = s:DotRelative(fugitive#Real(s:BufName(a:var)), cwd)
   while len(flags)
     let flag = matchstr(flags, s:flag)
     let flags = strpart(flags, len(flag))
     if flag ==# ':.'
-      let file = s:DotRelative(file)
+      let file = s:DotRelative(file, cwd)
     else
       let file = fnamemodify(file, flag)
     endif
@@ -855,22 +1032,19 @@ function! s:ExpandVar(other, var, flags, esc) abort
   return (len(a:esc) ? shellescape(file) : file)
 endfunction
 
-function! s:Expand(rev) abort
+function! s:Expand(rev, ...) abort
   if a:rev =~# '^:[0-3]$'
-    let file = a:rev . s:Relative(':')
-  elseif a:rev =~# '^-'
-    let file = 'HEAD^{}' . a:rev[1:-1] . s:Relative(':')
-  elseif a:rev =~# '^@{'
-    let file = 'HEAD' . a:rev. s:Relative(':')
-  elseif a:rev =~# '^\^[0-9~^{]\|^\~[0-9~^]'
-    let commit = substitute(s:DirCommitFile(@%)[1], '^\d\=$', 'HEAD', '')
-    let file = commit . a:rev . s:Relative(':')
+    let file = a:rev . ':%'
+  elseif a:rev =~# '^>[~^]\|^>@{\|^>$'
+    let file = 'HEAD' . a:rev[1:-1] . ':%'
+  elseif a:rev =~# '^>[> ]\@!'
+    let file = a:rev[1:-1] . ':%'
   else
     let file = a:rev
   endif
   return substitute(file,
         \ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
-        \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),"")', 'g')
+        \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),"", a:0 ? a:1 : getcwd())', 'g')
 endfunction
 
 function! fugitive#Expand(object) abort
@@ -879,9 +1053,40 @@ function! fugitive#Expand(object) abort
         \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5))', 'g')
 endfunction
 
-function! s:ShellExpand(cmd) abort
-  return substitute(a:cmd, '\(\\[!#%]\|!\d*\)\|' . s:expand,
-        \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5))', 'g')
+function! s:ExpandSplit(string, ...) abort
+  let list = []
+  let string = a:string
+  let handle_bar = a:0 && a:1
+  let dquote = handle_bar ? '"\%([^"]\|""\|\\"\)*"\|' : ''
+  let cwd = a:0 > 1 ? a:2 : getcwd()
+  while string =~# '\S'
+    if handle_bar && string =~# '^\s*|'
+      return [list, substitute(string, '^\s*', '', '')]
+    endif
+    let arg = matchstr(string, '^\s*\%(' . dquote . '''[^'']*''\|\\.\|[^[:space:] ' . (handle_bar ? '|' : '') . ']\)\+')
+    let string = strpart(string, len(arg))
+    let arg = substitute(arg, '^\s\+', '', '')
+    if !exists('seen_separator')
+      let arg = substitute(arg, '^\%([^:.][^:]*:\|^:\|^:[0-3]:\)\=\zs\.\.\=\%(/.*\)\=$',
+            \ '\=s:DotRelative(s:Slash(simplify(getcwd() . "/" . submatch(0))), cwd)', '')
+    endif
+    let arg = substitute(arg,
+          \ '\(' . dquote . '''\%(''''\|[^'']\)*''\|\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
+          \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5), cwd)', 'g')
+    call add(list, arg)
+    if arg ==# '--'
+      let seen_separator = 1
+    endif
+  endwhile
+  return handle_bar ? [list, ''] : list
+endfunction
+
+function! s:SplitExpand(string, ...) abort
+  return s:ExpandSplit(a:string, 0, a:0 ? a:1 : getcwd())
+endfunction
+
+function! s:SplitExpandChain(string, ...) abort
+  return s:ExpandSplit(a:string, 1, a:0 ? a:1 : getcwd())
 endfunction
 
 let s:trees = {}
@@ -889,14 +1094,14 @@ let s:indexes = {}
 function! s:TreeInfo(dir, commit) abort
   if a:commit =~# '^:\=[0-3]$'
     let index = get(s:indexes, a:dir, [])
-    let newftime = getftime(a:dir . '/index')
+    let newftime = getftime(fugitive#Find('.git/index', a:dir))
     if get(index, 0, -1) < newftime
-      let out = system(fugitive#Prepare(a:dir, 'ls-files', '--stage', '--'))
+      let [lines, exec_error] = s:LinesError([a:dir, 'ls-files', '--stage', '--'])
       let s:indexes[a:dir] = [newftime, {'0': {}, '1': {}, '2': {}, '3': {}}]
-      if v:shell_error
+      if exec_error
         return [{}, -1]
       endif
-      for line in split(out, "\n")
+      for line in lines
         let [info, filename] = split(line, "\t")
         let [mode, sha, stage] = split(info, '\s\+')
         let s:indexes[a:dir][1][stage][filename] = [newftime, mode, 'blob', sha, -2]
@@ -907,25 +1112,25 @@ function! s:TreeInfo(dir, commit) abort
       endfor
     endif
     return [get(s:indexes[a:dir][1], a:commit[-1:-1], {}), newftime]
-  elseif a:commit =~# '^\x\{40\}$'
+  elseif a:commit =~# '^\x\{40,\}$'
     if !has_key(s:trees, a:dir)
       let s:trees[a:dir] = {}
     endif
     if !has_key(s:trees[a:dir], a:commit)
-      let ftime = +system(fugitive#Prepare(a:dir, 'log', '-1', '--pretty=format:%ct', a:commit, '--'))
-      if v:shell_error
+      let [ftime, exec_error] = s:ChompError([a:dir, 'log', '-1', '--pretty=format:%ct', a:commit, '--'])
+      if exec_error
         let s:trees[a:dir][a:commit] = [{}, -1]
         return s:trees[a:dir][a:commit]
       endif
       let s:trees[a:dir][a:commit] = [{}, +ftime]
-      let out = system(fugitive#Prepare(a:dir, 'ls-tree', '-rtl', '--full-name', a:commit, '--'))
-      if v:shell_error
+      let [lines, exec_error] = s:LinesError([a:dir, 'ls-tree', '-rtl', '--full-name', a:commit, '--'])
+      if exec_error
         return s:trees[a:dir][a:commit]
       endif
-      for line in split(out, "\n")
+      for line in lines
         let [info, filename] = split(line, "\t")
         let [mode, type, sha, size] = split(info, '\s\+')
-        let s:trees[a:dir][a:commit][0][filename] = [ftime, mode, type, sha, +size, filename]
+        let s:trees[a:dir][a:commit][0][filename] = [+ftime, mode, type, sha, +size, filename]
       endfor
     endif
     return s:trees[a:dir][a:commit]
@@ -941,7 +1146,7 @@ function! s:PathInfo(url) abort
   let path = substitute(file[1:-1], '/*$', '', '')
   let [tree, ftime] = s:TreeInfo(dir, commit)
   let entry = empty(path) ? [ftime, '040000', 'tree', '', -1] : get(tree, path, [])
-  if empty(entry) || file =~# '/$' && entry[1] !=# 'tree'
+  if empty(entry) || file =~# '/$' && entry[2] !=# 'tree'
     return [-1, '000000', '', '', -1]
   else
     return entry
@@ -958,11 +1163,11 @@ function! fugitive#simplify(url) abort
     if len(tree)
       let path = simplify(tree . file)
       if strpart(path . '/', 0, len(tree) + 1) !=# tree . '/'
-        return s:PlatformSlash(path)
+        return FugitiveVimPath(path)
       endif
     endif
   endif
-  return s:PlatformSlash('fugitive://' . simplify(dir) . '//' . commit . simplify(file))
+  return FugitiveVimPath('fugitive://' . simplify(dir) . '//' . commit . simplify(file))
 endfunction
 
 function! fugitive#resolve(url) abort
@@ -982,8 +1187,7 @@ function! fugitive#getfsize(url) abort
   let entry = s:PathInfo(a:url)
   if entry[4] == -2 && entry[2] ==# 'blob' && len(entry[3])
     let dir = s:DirCommitFile(a:url)[0]
-    let size = +system(s:Prepare(dir, 'cat-file', '-s', entry[3]))
-    let entry[4] = v:shell_error ? -1 : size
+    let entry[4] = +s:ChompDefault(-1, [dir, 'cat-file', '-s', entry[3]])
   endif
   return entry[4]
 endfunction
@@ -998,7 +1202,7 @@ endfunction
 
 function! fugitive#filewritable(url) abort
   let [dir, commit, file] = s:DirCommitFile(a:url)
-  if commit !~# '^\d$' || !filewritable(dir . '/index')
+  if commit !~# '^\d$' || !filewritable(fugitive#Find('.git/index', dir))
     return 0
   endif
   return s:PathInfo(a:url)[2] ==# 'blob' ? 1 : 2
@@ -1035,23 +1239,23 @@ function! fugitive#setfperm(url, perm) abort
       \ substitute(perm, 'x', '-', 'g') !=# substitute(a:perm, 'x', '-', 'g')
     return -2
   endif
-  call system(s:Prepare(dir, 'update-index', '--index-info'),
-        \ (a:perm =~# 'x' ? '000755 ' : '000644 ') . entry[3] . ' ' . commit . "\t" . file[1:-1])
-  return v:shell_error ? -1 : 0
+  let exec_error = s:SystemError([dir, 'update-index', '--index-info'],
+        \ (a:perm =~# 'x' ? '000755 ' : '000644 ') . entry[3] . ' ' . commit . "\t" . file[1:-1])[1]
+  return exec_error ? -1 : 0
 endfunction
 
 function! s:TempCmd(out, cmd) abort
   let prefix = ''
   try
-    let cmd = (type(a:cmd) == type([]) ? call('s:Prepare', a:cmd) : a:cmd)
+    let cmd = (type(a:cmd) == type([]) ? fugitive#Prepare(a:cmd) : a:cmd)
     let redir = ' > ' . a:out
     if s:winshell()
       let cmd_escape_char = &shellxquote == '(' ?  '^' : '^^^'
-      return s:System('cmd /c "' . prefix . s:gsub(cmd, '[<>]', cmd_escape_char . '&') . redir . '"')
+      return s:SystemError('cmd /c "' . prefix . s:gsub(cmd, '[<>]', cmd_escape_char . '&') . redir . '"')
     elseif &shell =~# 'fish'
-      return s:System(' begin;' . prefix . cmd . redir . ';end ')
+      return s:SystemError(' begin;' . prefix . cmd . redir . ';end ')
     else
-      return s:System(' (' . prefix . cmd . redir . ') ')
+      return s:SystemError(' (' . prefix . cmd . redir . ') ')
     endif
   endtry
 endfunction
@@ -1074,9 +1278,8 @@ function! s:BlobTemp(url) abort
   endif
   if commit =~# '^\d$' || !filereadable(tempfile)
     let rev = s:DirRev(a:url)[1]
-    let command = s:Prepare(dir, 'cat-file', 'blob', rev)
-    call s:TempCmd(tempfile, command)
-    if v:shell_error
+    let exec_error = s:TempCmd(tempfile, [dir, 'cat-file', 'blob', rev])[1]
+    if exec_error
       call delete(tempfile)
       return ''
     endif
@@ -1106,12 +1309,12 @@ function! fugitive#writefile(lines, url, ...) abort
       call writefile(fugitive#readfile(url, 'b'), temp, 'b')
     endif
     call call('writefile', [a:lines, temp] + a:000)
-    let hash = system(s:Prepare(dir, 'hash-object', '-w', temp))[0:-2]
+    let [hash, exec_error] = s:ChompError([dir, 'hash-object', '-w', temp])
     let mode = len(entry[1]) ? entry[1] : '100644'
-    if !v:shell_error && hash =~# '^\x\{40\}$'
-      call system(s:Prepare(dir, 'update-index', '--index-info'),
-            \ mode . ' ' . hash . ' ' . commit . "\t" . file[1:-1])
-      if !v:shell_error
+    if !exec_error && hash =~# '^\x\{40,\}$'
+      let exec_error = s:SystemError([dir, 'update-index', '--index-info'],
+            \ mode . ' ' . hash . ' ' . commit . "\t" . file[1:-1])[1]
+      if !exec_error
         return 0
       endif
     endif
@@ -1134,7 +1337,7 @@ function! fugitive#glob(url, ...) abort
   let pattern = '^' . substitute(glob, '/\=\*\*/\=\|/\=\*\|[.?\$]\|^^', '\=get(s:globsubs, submatch(0), "\\" . submatch(0))', 'g')[1:-1] . '$'
   let results = []
   for dir in dirglob =~# '[*?]' ? split(glob(dirglob), "\n") : [dirglob]
-    if empty(dir) || !get(g:, 'fugitive_file_api', 1) || !filereadable(dir . '/HEAD')
+    if empty(dir) || !get(g:, 'fugitive_file_api', 1) || !filereadable(fugitive#Find('.git/HEAD', dir))
       continue
     endif
     let files = items(s:TreeInfo(dir, commit)[0])
@@ -1145,7 +1348,7 @@ function! fugitive#glob(url, ...) abort
     call filter(files, 'v:val =~# pattern')
     let prepend = 'fugitive://' . dir . '//' . substitute(commit, '^:', '', '') . '/'
     call sort(files)
-    call map(files, 's:PlatformSlash(prepend . v:val . append)')
+    call map(files, 'FugitiveVimPath(prepend . v:val . append)')
     call extend(results, files)
   endfor
   if a:0 > 1 && a:2
@@ -1164,9 +1367,9 @@ function! fugitive#delete(url, ...) abort
   if entry[2] !=# 'blob'
     return -1
   endif
-  call system(s:Prepare(dir, 'update-index', '--index-info'),
-        \ '000000 0000000000000000000000000000000000000000 ' . commit . "\t" . file[1:-1])
-  return v:shell_error ? -1 : 0
+  let exec_error = s:SystemError([dir, 'update-index', '--index-info'],
+        \ '000000 0000000000000000000000000000000000000000 ' . commit . "\t" . file[1:-1])[1]
+  return exec_error ? -1 : 0
 endfunction
 
 " Section: Buffer Object
@@ -1188,11 +1391,11 @@ function! s:buffer_getline(lnum) dict abort
 endfunction
 
 function! s:buffer_repo() dict abort
-  throw "fugitive: A third-party plugin or vimrc is calling fugitive#buffer().repo() which has been removed. Replace it with fugitive#repo()"
+  return fugitive#repo(self['#'])
 endfunction
 
 function! s:buffer_type(...) dict abort
-  throw "fugitive: A third-party plugin or vimrc is calling fugitive#buffer().type() which has been removed. Replace it with get(b:, 'fugitive_type', '')"
+  return getbufvar(self['#'], 'fugitive_type')
 endfunction
 
 function! s:buffer_spec() dict abort
@@ -1219,8 +1422,18 @@ call s:add_methods('buffer',['getvar','getline','repo','type','spec','name','com
 
 " Section: Completion
 
+function! s:FilterEscape(items, ...) abort
+  let items = copy(a:items)
+  if a:0 && type(a:1) == type('')
+    call filter(items, 'strpart(v:val, 0, strlen(a:1)) ==# a:1')
+  endif
+  return map(items, 's:fnameescape(v:val)')
+endfunction
+
 function! s:GlobComplete(lead, pattern) abort
-  if v:version >= 704
+  if a:lead ==# '/'
+    return []
+  elseif v:version >= 704
     let results = glob(a:lead . a:pattern, 0, 1)
   else
     let results = split(glob(a:lead . a:pattern), "\n")
@@ -1263,7 +1476,7 @@ endfunction
 
 function! fugitive#CompleteObject(base, ...) abort
   let dir = a:0 == 1 ? a:1 : a:0 == 3 ? a:3 : s:Dir()
-  let cwd = a:0 == 1 ? s:Tree(dir) : getcwd()
+  let cwd = getcwd()
   let tree = s:Tree(dir) . '/'
   let subdir = ''
   if len(tree) > 1 && s:cpath(tree, cwd[0 : len(tree) - 1])
@@ -1276,10 +1489,10 @@ function! fugitive#CompleteObject(base, ...) abort
       let results += map(s:GlobComplete(fugitive#CommonDir(dir) . '/', a:base . '*'), 's:Slash(v:val)')
     elseif a:base !~# '^\.\=/\|^:('
       let heads = ['HEAD', 'ORIG_HEAD', 'FETCH_HEAD', 'MERGE_HEAD', 'refs/']
-      let heads += sort(split(s:TreeChomp(["rev-parse","--symbolic","--branches","--tags","--remotes"], dir),"\n"))
-      if filereadable(fugitive#CommonDir(dir) . '/refs/stash')
+      let heads += sort(s:LinesError(["rev-parse","--symbolic","--branches","--tags","--remotes"], dir)[0])
+      if filereadable(fugitive#Find('.git/refs/stash', dir))
         let heads += ["stash"]
-        let heads += sort(split(s:TreeChomp(["stash","list","--pretty=format:%gd"], dir),"\n"))
+        let heads += sort(s:LinesError(["stash","list","--pretty=format:%gd"], dir)[0])
       endif
       call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
       let results += heads
@@ -1291,7 +1504,7 @@ function! fugitive#CompleteObject(base, ...) abort
     return results
 
   elseif a:base =~# '^:'
-    let entries = split(s:TreeChomp(['ls-files','--stage'], dir),"\n")
+    let entries = s:LinesError(['ls-files','--stage'], dir)[0]
     if a:base =~# ':\./'
       call map(entries, 'substitute(v:val, "\\M\t\\zs" . subdir, "./", "")')
     endif
@@ -1303,25 +1516,52 @@ function! fugitive#CompleteObject(base, ...) abort
 
   else
     let tree = matchstr(a:base, '.*[:/]')
-    let entries = split(s:TreeChomp(['ls-tree', substitute(tree,  ':\zs\./', '\=subdir', '')], dir),"\n")
+    let entries = s:LinesError(['ls-tree', substitute(tree,  ':\zs\./', '\=subdir', '')], dir)[0]
     call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
     call map(entries,'tree.s:sub(v:val,".*\t","")')
 
   endif
-  call filter(entries, 'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
-  return map(entries, 's:fnameescape(v:val)')
+  return s:FilterEscape(entries, a:base)
 endfunction
 
-function! fugitive#Complete(...) abort
-  return call('fugitive#CompleteObject', a:000)
+function! s:CompleteSub(subcommand, A, L, P, ...) abort
+  let pre = strpart(a:L, 0, a:P)
+  if pre =~# ' -- '
+    return fugitive#CompletePath(a:A)
+  elseif a:A =~# '^-' || a:A is# 0
+    return s:FilterEscape(split(s:ChompDefault('', a:subcommand, '--git-completion-helper'), ' '), a:A)
+  elseif !a:0
+    return fugitive#CompleteObject(a:A, s:Dir())
+  elseif type(a:1) == type(function('tr'))
+    return call(a:1, [a:A, a:L, a:P])
+  else
+    return s:FilterEscape(a:1, a:A)
+  endif
+endfunction
+
+function! s:CompleteRevision(A, L, P) abort
+  return s:FilterEscape(['HEAD', 'FETCH_HEAD', 'MERGE_HEAD', 'ORIG_HEAD'] +
+        \ s:LinesError('rev-parse', '--symbolic', '--branches', '--tags', '--remotes')[0], a:A)
+endfunction
+
+function! s:CompleteRemote(A, L, P) abort
+  let remote = matchstr(a:L, '\u\w*[! ] *\zs\S\+\ze ')
+  if !empty(remote)
+    let matches = s:LinesError('ls-remote', remote)[0]
+    call filter(matches, 'v:val =~# "\t" && v:val !~# "{"')
+    call map(matches, 's:sub(v:val, "^.*\t%(refs/%(heads/|tags/)=)=", "")')
+  else
+    let matches = s:LinesError('remote')[0]
+  endif
+  return s:FilterEscape(matches, a:A)
 endfunction
 
 " Section: Buffer auto-commands
 
 function! s:ReplaceCmd(cmd) abort
   let temp = tempname()
-  let err = s:TempCmd(temp, a:cmd)
-  if v:shell_error
+  let [err, exec_error] = s:TempCmd(temp, a:cmd)
+  if exec_error
     call s:throw((len(err) ? err : filereadable(temp) ? join(readfile(temp), ' ') : 'unknown error running ' . a:cmd))
   endif
   let temp = s:Resolve(temp)
@@ -1345,10 +1585,7 @@ function! s:ReplaceCmd(cmd) abort
 endfunction
 
 function! s:QueryLog(refspec) abort
-  let lines = split(system(FugitivePrepare('log', '-n', '256', '--format=%h%x09%s', a:refspec, '--')), "\n")
-  if v:shell_error
-    return []
-  endif
+  let lines = s:LinesError(['log', '-n', '256', '--format=%h%x09%s', a:refspec, '--'])[0]
   call map(lines, 'split(v:val, "\t")')
   call map(lines, '{"type": "Log", "commit": v:val[0], "subject": v:val[-1]}')
   return lines
@@ -1401,17 +1638,18 @@ endfunction
 function! fugitive#BufReadStatus() abort
   let amatch = s:Slash(expand('%:p'))
   let b:fugitive_type = 'index'
+  unlet! b:fugitive_reltime
   try
     silent doautocmd BufReadPre
     let cmd = [fnamemodify(amatch, ':h')]
     setlocal noro ma nomodeline buftype=nowrite
-    if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : s:Dir() . '/index', ':p')) !=# s:cpath(amatch)
+    if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch)
       let cmd += ['-c', 'GIT_INDEX_FILE=' . amatch]
     endif
     let cmd += ['status', '--porcelain', '-bz']
-    let output = split(system(fugitive#Prepare(cmd)), "\1")
-    if v:shell_error
-      throw 'fugitive: ' . join(output, ' ')
+    let [output, message, exec_error] = s:NullError(cmd)
+    if exec_error
+      throw 'fugitive: ' . message
     endif
 
     let head = matchstr(output[0], '^## \zs\S\+\ze\%($\| \[\)')
@@ -1443,17 +1681,13 @@ function! fugitive#BufReadStatus() abort
       endif
       if line[0] !~# '[ ?!#]'
         call add(staged, {'type': 'File', 'status': line[0], 'filename': files})
-        let b:fugitive_status['Staged'][files] = line[0]
       endif
-      if line[1] =~# '?'
+      if line[0:1] ==# '??'
         call add(untracked, {'type': 'File', 'status': line[1], 'filename': files})
-        let b:fugitive_status['Unstaged'][files] = line[1]
       elseif line[1] !~# '[ !#]'
         call add(unstaged, {'type': 'File', 'status': line[1], 'filename': files})
-        let b:fugitive_status['Unstaged'][files] = line[1]
       endif
     endwhile
-    let unstaged = extend(untracked, unstaged)
 
     for dict in staged
       let b:fugitive_status['Staged'][dict.filename] = dict.status
@@ -1531,9 +1765,16 @@ function! fugitive#BufReadStatus() abort
       endfor
     endif
 
-    let b:fugitive_diff = {
-          \ 'Staged': split(system(fugitive#Prepare('diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached')), "\n"),
-          \ 'Unstaged': split(system(fugitive#Prepare('diff', '--color=never', '--no-ext-diff', '--no-prefix')), "\n")}
+    let diff = {'Staged': [], 'Unstaged': []}
+    if len(staged)
+      let diff['Staged'] =
+          \ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached'])[0]
+    endif
+    if len(unstaged)
+      let diff['Unstaged'] =
+          \ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix'])[0]
+    endif
+    let b:fugitive_diff = diff
     let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}})
     let b:fugitive_expanded = {'Staged': {}, 'Unstaged': {}}
 
@@ -1545,6 +1786,7 @@ function! fugitive#BufReadStatus() abort
       call s:AddHeader('Push', push)
     endif
     call s:AddSection('Rebasing ' . rebasing_head, rebasing)
+    call s:AddSection('Untracked', untracked)
     call s:AddSection('Unstaged', unstaged)
     let unstaged_end = len(unstaged) ? line('$') : 0
     call s:AddSection('Staged', staged)
@@ -1560,47 +1802,54 @@ function! fugitive#BufReadStatus() abort
     endif
     let b:dispatch = ':Gfetch --all'
     call fugitive#MapJumps()
-    let nowait = v:version >= 704 ? '<nowait>' : ''
-    nunmap   <buffer>          P
-    nunmap   <buffer>          ~
-    nnoremap <buffer> <silent> <C-N> :<C-U>execute <SID>StageNext(v:count1)<CR>
-    nnoremap <buffer> <silent> <C-P> :<C-U>execute <SID>StagePrevious(v:count1)<CR>
-    exe "nnoremap <buffer> <silent>" nowait "- :<C-U>execute <SID>Do('Toggle',0)<CR>"
-    exe "xnoremap <buffer> <silent>" nowait "- :<C-U>execute <SID>Do('Toggle',1)<CR>"
-    exe "nnoremap <buffer> <silent>" nowait "s :<C-U>execute <SID>Do('Stage',0)<CR>"
-    exe "xnoremap <buffer> <silent>" nowait "s :<C-U>execute <SID>Do('Stage',1)<CR>"
-    exe "nnoremap <buffer> <silent>" nowait "u :<C-U>execute <SID>Do('Unstage',0)<CR>"
-    exe "xnoremap <buffer> <silent>" nowait "u :<C-U>execute <SID>Do('Unstage',1)<CR>"
-    nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>
-    nnoremap <buffer> <silent> a :<C-U>execute <SID>Do('Toggle',0)<CR>
-    nnoremap <buffer> <silent> i :<C-U>execute <SID>StageIntend(v:count1)<CR>
-    exe 'nnoremap <buffer> <silent>' nowait "= :<C-U>execute <SID>StageInline('toggle',line('.'),v:count)<CR>"
-    exe 'nnoremap <buffer> <silent>' nowait "< :<C-U>execute <SID>StageInline('show',  line('.'),v:count)<CR>"
-    exe 'nnoremap <buffer> <silent>' nowait "> :<C-U>execute <SID>StageInline('hide',  line('.'),v:count)<CR>"
-    exe 'xnoremap <buffer> <silent>' nowait "= :<C-U>execute <SID>StageInline('toggle',line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>"
-    exe 'xnoremap <buffer> <silent>' nowait "< :<C-U>execute <SID>StageInline('show',  line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>"
-    exe 'xnoremap <buffer> <silent>' nowait "> :<C-U>execute <SID>StageInline('hide',  line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>"
-    nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff('Gdiff')<CR>
-    nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff('Gdiff')<CR>
-    nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
-    nnoremap <buffer> <silent> ds :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
-    nnoremap <buffer> <silent> dp :<C-U>execute <SID>StageDiffEdit()<CR>
-    nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR>
-    nnoremap <buffer> <silent> J :<C-U>execute <SID>StageNext(v:count1)<CR>
-    nnoremap <buffer> <silent> K :<C-U>execute <SID>StagePrevious(v:count1)<CR>
-    nnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
-    xnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
-    nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>
-    exe 'nnoremap <buffer> <silent>' nowait "gq :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>"
-    nnoremap <buffer> <silent> R :<C-U>exe <SID>ReloadStatus()<CR>
-    nnoremap <buffer> <silent> U :<C-U>echoerr 'Changed to X'<CR>
-    nnoremap <buffer> <silent> g<Bar> :<C-U>execute <SID>StageDelete(line('.'),v:count)<CR>
-    xnoremap <buffer> <silent> g<Bar> :<C-U>execute <SID>StageDelete(line("'<"),line("'>")-line("'<")+1)<CR>
-    nnoremap <buffer> <silent> X :<C-U>execute <SID>StageDelete(line('.'),v:count)<CR>
-    xnoremap <buffer> <silent> X :<C-U>execute <SID>StageDelete(line("'<"),line("'>")-line("'<")+1)<CR>
-    nnoremap <buffer>          . :<C-U> <C-R>=<SID>StageArgs(0)<CR><Home>
-    xnoremap <buffer>          . :<C-U> <C-R>=<SID>StageArgs(1)<CR><Home>
-    nnoremap <buffer> <silent> <F1> :help fugitive-mappings<CR>
+    call s:Map('n', '-', ":<C-U>execute <SID>Do('Toggle',0)<CR>", '<silent>')
+    call s:Map('x', '-', ":<C-U>execute <SID>Do('Toggle',1)<CR>", '<silent>')
+    call s:Map('n', 's', ":<C-U>execute <SID>Do('Stage',0)<CR>", '<silent>')
+    call s:Map('x', 's', ":<C-U>execute <SID>Do('Stage',1)<CR>", '<silent>')
+    call s:Map('n', 'u', ":<C-U>execute <SID>Do('Unstage',0)<CR>", '<silent>')
+    call s:Map('x', 'u', ":<C-U>execute <SID>Do('Unstage',1)<CR>", '<silent>')
+    call s:Map('n', 'U', ":exe <SID>EchoExec('reset', '-q')<CR>", '<silent>')
+    call s:MapMotion('gu', "exe <SID>StageJump(v:count, 'Untracked', 'Unstaged')")
+    call s:MapMotion('gU', "exe <SID>StageJump(v:count, 'Unstaged', 'Untracked')")
+    call s:MapMotion('gs', "exe <SID>StageJump(v:count, 'Staged')")
+    call s:MapMotion('gp', "exe <SID>StageJump(v:count, 'Unpushed')")
+    call s:MapMotion('gP', "exe <SID>StageJump(v:count, 'Unpulled')")
+    call s:MapMotion('gr', "exe <SID>StageJump(v:count, 'Rebasing')")
+    call s:Map('n', 'C', ":<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>", '<silent>')
+    call s:Map('n', 'a', ":<C-U>execute <SID>Do('Toggle',0)<CR>", '<silent>')
+    call s:Map('n', 'i', ":<C-U>execute <SID>NextExpandedHunk(v:count1)<CR>", '<silent>')
+    call s:Map('n', "=", ":<C-U>execute <SID>StageInline('toggle',line('.'),v:count)<CR>", '<silent>')
+    call s:Map('n', "<", ":<C-U>execute <SID>StageInline('hide',  line('.'),v:count)<CR>", '<silent>')
+    call s:Map('n', ">", ":<C-U>execute <SID>StageInline('show',  line('.'),v:count)<CR>", '<silent>')
+    call s:Map('x', "=", ":<C-U>execute <SID>StageInline('toggle',line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>", '<silent>')
+    call s:Map('x', "<", ":<C-U>execute <SID>StageInline('hide',  line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>", '<silent>')
+    call s:Map('x', ">", ":<C-U>execute <SID>StageInline('show',  line(\"'<\"),line(\"'>\")-line(\"'<\")+1)<CR>", '<silent>')
+    call s:Map('n', 'D', ":<C-U>execute <SID>StageDiff('Gdiffsplit')<Bar>redraw<Bar>echohl WarningMsg<Bar> echo ':Gstatus D is deprecated in favor of dd'<Bar>echohl NONE<CR>", '<silent>')
+    call s:Map('n', 'dd', ":<C-U>execute <SID>StageDiff('Gdiffsplit')<CR>", '<silent>')
+    call s:Map('n', 'dh', ":<C-U>execute <SID>StageDiff('Ghdiffsplit')<CR>", '<silent>')
+    call s:Map('n', 'ds', ":<C-U>execute <SID>StageDiff('Ghdiffsplit')<CR>", '<silent>')
+    call s:Map('n', 'dp', ":<C-U>execute <SID>StageDiffEdit()<CR>", '<silent>')
+    call s:Map('n', 'dv', ":<C-U>execute <SID>StageDiff('Gvdiffsplit')<CR>", '<silent>')
+    call s:Map('n', 'd?', ":<C-U>help fugitive_d<CR>", '<silent>')
+    call s:Map('n', 'P', ":<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>", '<silent>')
+    call s:Map('x', 'P', ":<C-U>execute <SID>StagePatch(line(\"'<\"),line(\"'>\"))<CR>", '<silent>')
+    call s:Map('n', 'p', ":<C-U>if v:count<Bar>silent exe <SID>GF('pedit')<Bar>else<Bar>echoerr 'Use = for inline diff, P for :Git add/reset --patch, 1p for :pedit'<Bar>endif<CR>", '<silent>')
+    call s:Map('x', 'p', ":<C-U>execute <SID>StagePatch(line(\"'<\"),line(\"'>\"))<CR>", '<silent>')
+    call s:Map('n', 'I', ":<C-U>execute <SID>StagePatch(line('.'),line('.'))<CR>", '<silent>')
+    call s:Map('x', 'I', ":<C-U>execute <SID>StagePatch(line(\"'<\"),line(\"'>\"))<CR>", '<silent>')
+    if empty(mapcheck('q', 'n'))
+      nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<Bar>echohl WarningMsg<Bar>echo ':Gstatus q is deprecated in favor of gq or the built-in <Lt>C-W>q'<Bar>echohl NONE<CR>
+    endif
+    call s:Map('n', 'gq', ":<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>", '<silent>')
+    call s:Map('n', 'R', ":echohl WarningMsg<Bar>echo 'Reloading is automatic.  Use :e to force'<Bar>echohl NONE<CR>", '<silent>')
+    call s:Map('n', 'g<Bar>', ":<C-U>echoerr 'Changed to X'<CR>", '<silent>')
+    call s:Map('x', 'g<Bar>', ":<C-U>echoerr 'Changed to X'<CR>", '<silent>')
+    call s:Map('n', 'X', ":<C-U>execute <SID>StageDelete(line('.'), 0, v:count)<CR>", '<silent>')
+    call s:Map('x', 'X', ":<C-U>execute <SID>StageDelete(line(\"'<\"), line(\"'>\"), v:count)<CR>", '<silent>')
+    call s:Map('n', 'gI', ":<C-U>execute <SID>StageIgnore(line('.'), line('.'), v:count)<CR>", '<silent>')
+    call s:Map('x', 'gI', ":<C-U>execute <SID>StageIgnore(line(\"'<\"), line(\"'>\"), v:count)<CR>", '<silent>')
+    call s:Map('n', '.', ':<C-U> <C-R>=<SID>StageArgs(0)<CR><Home>')
+    call s:Map('x', '.', ':<C-U> <C-R>=<SID>StageArgs(1)<CR><Home>')
     setlocal filetype=fugitive
 
     for [lnum, section] in [[staged_end, 'Staged'], [unstaged_end, 'Unstaged']]
@@ -1613,9 +1862,10 @@ function! fugitive#BufReadStatus() abort
       endwhile
     endfor
 
+    let b:fugitive_reltime = reltime()
     return ''
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
 endfunction
 
@@ -1626,10 +1876,10 @@ function! fugitive#FileReadCmd(...) abort
   if empty(dir)
     return 'noautocmd ' . line . 'read ' . s:fnameescape(amatch)
   endif
-  if rev !~# ':'
-    let cmd = s:Prepare(dir, 'log', '--pretty=format:%B', '-1', rev, '--')
+  if rev !~# ':' && s:ChompDefault('', [dir, 'cat-file', '-t', rev]) =~# '^\%(commit\|tag\)$'
+    let cmd = fugitive#Prepare(dir, 'log', '--pretty=format:%B', '-1', rev, '--')
   else
-    let cmd = s:Prepare(dir, 'cat-file', '-p', rev)
+    let cmd = fugitive#Prepare(dir, 'cat-file', '-p', rev)
   endif
   return line . 'read !' . escape(cmd, '!#%')
 endfunction
@@ -1646,20 +1896,19 @@ function! fugitive#FileWriteCmd(...) abort
     if commit !~# '^[0-3]$' || !v:cmdbang && (line("'[") != 1 || line("']") != line('$'))
       return "noautocmd '[,']write" . (v:cmdbang ? '!' : '') . ' ' . s:fnameescape(amatch)
     endif
-    silent execute "'[,']write !".s:Prepare(dir, 'hash-object', '-w', '--stdin', '--').' > '.tmp
+    silent execute "'[,']write !".fugitive#Prepare(dir, 'hash-object', '-w', '--stdin', '--').' > '.tmp
     let sha1 = readfile(tmp)[0]
-    let old_mode = matchstr(system(s:Prepare(dir, 'ls-files', '--stage', '.' . file)), '^\d\+')
+    let old_mode = matchstr(s:SystemError([dir, 'ls-files', '--stage', '.' . file])[0], '^\d\+')
     if empty(old_mode)
       let old_mode = executable(s:Tree(dir) . file) ? '100755' : '100644'
     endif
     let info = old_mode.' '.sha1.' '.commit."\t".file[1:-1]
-    let error = system(s:Prepare(dir, 'update-index', '--index-info'), info . "\n")
-    if v:shell_error == 0
+    let [error, exec_error] = s:SystemError([dir, 'update-index', '--index-info'], info . "\n")
+    if !exec_error
       setlocal nomodified
       if exists('#' . autype . 'WritePost')
         execute 'doautocmd ' . autype . 'WritePost ' . s:fnameescape(amatch)
       endif
-      call fugitive#ReloadStatus()
       return ''
     else
       return 'echoerr '.string('fugitive: '.error)
@@ -1669,6 +1918,8 @@ function! fugitive#FileWriteCmd(...) abort
   endtry
 endfunction
 
+let s:nomodeline = (v:version >= 704 ? '<nomodeline>' : '')
+
 function! fugitive#BufReadCmd(...) abort
   let amatch = a:0 ? a:1 : expand('<amatch>')
   try
@@ -1679,20 +1930,25 @@ function! fugitive#BufReadCmd(...) abort
     if rev =~# '^:\d$'
       let b:fugitive_type = 'stage'
     else
-      let b:fugitive_type = system(s:Prepare(dir, 'cat-file', '-t', rev))[0:-2]
-      if v:shell_error && rev =~# '^:0'
-        let sha = system(s:Prepare(dir, 'write-tree', '--prefix=' . rev[3:-1]))[0:-2]
-        let b:fugitive_type = 'tree'
+      let [b:fugitive_type, exec_error] = s:ChompError([dir, 'cat-file', '-t', rev])
+      if exec_error && rev =~# '^:0'
+        let sha = s:ChompDefault('', dir, 'write-tree', '--prefix=' . rev[3:-1])
+        let exec_error = empty(sha)
+        let b:fugitive_type = exec_error ? '' : 'tree'
       endif
-      if v:shell_error
+      if exec_error
         let error = b:fugitive_type
         unlet b:fugitive_type
+        setlocal noswapfile
+        if empty(&bufhidden)
+          setlocal bufhidden=delete
+        endif
         if rev =~# '^:\d:'
-          let &l:readonly = !filewritable(dir . '/index')
+          let &l:readonly = !filewritable(fugitive#Find('.git/index', dir))
           return 'silent doautocmd BufNewFile'
         else
           setlocal readonly nomodifiable
-          return 'echo ' . string(error)
+          return 'silent doautocmd BufNewFile|echo ' . string(error)
         endif
       elseif b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
         return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'")
@@ -1719,7 +1975,7 @@ function! fugitive#BufReadCmd(...) abort
           call s:ReplaceCmd([dir, 'ls-tree', exists('sha') ? sha : rev])
         else
           if !exists('sha')
-            let sha = system(s:Prepare(dir, 'rev-parse', '--verify', rev, '--'))[0:-2]
+            let sha = s:TreeChomp(dir, 'rev-parse', '--verify', rev, '--')
           endif
           call s:ReplaceCmd([dir, 'show', '--no-color', sha])
         endif
@@ -1758,24 +2014,24 @@ function! fugitive#BufReadCmd(...) abort
       keepjumps call setpos('.',pos)
       setlocal nomodified noswapfile
       let modifiable = rev =~# '^:.:' && b:fugitive_type !=# 'tree'
-      let &l:readonly = !modifiable || !filewritable(dir . '/index')
-      if &bufhidden ==# ''
+      let &l:readonly = !modifiable || !filewritable(fugitive#Find('.git/index', dir))
+      if empty(&bufhidden)
         setlocal bufhidden=delete
       endif
       let &l:modifiable = modifiable
       if b:fugitive_type !=# 'blob'
         setlocal filetype=git foldmethod=syntax
-        nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe fugitive#BufReadCmd(@%)<CR>
-        nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe fugitive#BufReadCmd(@%)<CR>
+        call s:Map('n', 'a', ":<C-U>let b:fugitive_display_format += v:count1<Bar>exe fugitive#BufReadCmd(@%)<CR>", '<silent>')
+        call s:Map('n', 'i', ":<C-U>let b:fugitive_display_format -= v:count1<Bar>exe fugitive#BufReadCmd(@%)<CR>", '<silent>')
       endif
       call fugitive#MapJumps()
     endtry
 
     setlocal modifiable
-    return 'silent doautocmd' . (v:version >= 704 ? ' <nomodeline>' : '') .
+    return 'silent doautocmd' . s:nomodeline .
           \ ' BufReadPost' . (modifiable ? '' : '|setl nomodifiable')
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
 endfunction
 
@@ -1802,24 +2058,38 @@ if !exists('s:temp_files')
   let s:temp_files = {}
 endif
 
-function! s:SetupTemp(file) abort
+function! s:TempState(...) abort
+  return get(s:temp_files, s:cpath(fnamemodify(a:0 ? a:1 : @%, ':p')), {})
+endfunction
+
+function! s:TempReadPre(file) abort
+  if has_key(s:temp_files, s:cpath(a:file))
+    let dict = s:temp_files[s:cpath(a:file)]
+    setlocal nomodeline
+    setlocal bufhidden=delete nobuflisted
+    setlocal buftype=nowrite
+    if has_key(dict, 'modifiable')
+      let &l:modifiable = dict.modifiable
+    endif
+    if len(dict.dir)
+      let b:git_dir = dict.dir
+      call extend(b:, {'fugitive_type': 'temp'}, 'keep')
+    endif
+  endif
+endfunction
+
+function! s:TempReadPost(file) abort
   if has_key(s:temp_files, s:cpath(a:file))
     let dict = s:temp_files[s:cpath(a:file)]
-    let b:git_dir = dict.dir
-    call extend(b:, {'fugitive_type': 'temp'}, 'keep')
     if has_key(dict, 'filetype') && dict.filetype !=# &l:filetype
       let &l:filetype = dict.filetype
     endif
     setlocal foldmarker=<<<<<<<,>>>>>>>
-    setlocal bufhidden=delete nobuflisted
-    setlocal buftype=nowrite
-    nnoremap <buffer> <silent> q    :<C-U>bdelete<CR>
-    if getline(1) !~# '^diff '
-      setlocal nomodifiable
+    if empty(mapcheck('q', 'n'))
+      nnoremap <buffer> <silent> q    :<C-U>bdelete<Bar>echohl WarningMsg<Bar>echo "Temp file q is deprecated in favor of the built-in <Lt>C-W>q"<Bar>echohl NONE<CR>
     endif
-    call FugitiveDetect(a:file)
-    if &filetype ==# 'git'
-      call fugitive#MapJumps()
+    if !&modifiable
+      call s:Map('n', 'gq', ":<C-U>bdelete<CR>", '<silent> <unique>')
     endif
   endif
   return ''
@@ -1827,52 +2097,71 @@ endfunction
 
 augroup fugitive_temp
   autocmd!
-  autocmd BufNewFile,BufReadPost * exe s:SetupTemp(expand('<amatch>:p'))
+  autocmd BufReadPre  * exe s:TempReadPre( expand('<amatch>:p'))
+  autocmd BufReadPost * exe s:TempReadPost(expand('<amatch>:p'))
 augroup END
 
 " Section: :Git
 
-call s:command("-bang -nargs=? -complete=customlist,fugitive#CompleteGit Git", "Git")
-
 function! s:GitCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
-  if a:bang
-    return s:Open('edit', 1, a:mods, a:arg, a:args)
+  let dir = s:Dir()
+  let [args, after] = s:SplitExpandChain(a:arg, s:Tree(dir))
+  if empty(args)
+    let cmd = s:StatusCommand(a:line1, a:line2, a:range, a:count, a:bang, a:mods, a:reg, '', [])
+    return (empty(cmd) ? 'exe' : cmd) . after
+  endif
+  let alias = get(s:Aliases(dir), args[0], '!')
+  if get(args, 1, '') !=# '--help' && alias !~# '^!\|[\"'']' && !filereadable(s:ExecPath() . '/git-' . args[0])
+        \ && !(has('win32') && filereadable(s:ExecPath() . '/git-' . args[0] . '.exe'))
+    call remove(args, 0)
+    call extend(args, split(alias, '\s\+'), 'keep')
+  endif
+  let name = substitute(args[0], '\%(^\|-\)\(\l\)', '\u\1', 'g')
+  if exists('*s:' . name . 'Subcommand') && get(args, 1, '') !=# '--help'
+    try
+      exe s:DirCheck(dir)
+      return 'exe ' . string(s:{name}Subcommand(a:line1, a:count, a:range, a:bang, a:mods, args[1:-1])) . after
+    catch /^fugitive:/
+      return 'echoerr ' . string(v:exception)
+    endtry
+  endif
+  if a:bang || args[0] =~# '^-P$\|^--no-pager$\|diff\%(tool\)\@!\|log\|^show$' ||
+        \ (args[0] ==# 'stash' && get(args, 1, '') ==# 'show') ||
+        \ (args[0] ==# 'help' || get(args, 1, '') ==# '--help') && !s:HasOpt(args, '--web')
+    return s:OpenExec((a:count > 0 ? a:count : '') . (a:count ? 'split' : 'edit'), a:mods, args, dir) . after
+  endif
+  if s:HasOpt(args, ['add', 'checkout', 'commit', 'stage', 'stash', 'reset'], '-p', '--patch') ||
+        \ s:HasOpt(args, ['add', 'clean', 'stage'], '-i', '--interactive') ||
+        \ index(['--paginate', '-p'], args[0]) >= 0
+    let mods = substitute(s:Mods(a:mods), '\<tab\>', '-tab', 'g')
+    if has('nvim')
+      if &autowrite || &autowriteall | silent! wall | endif
+      return mods . (a:count ? 'split' : 'edit') . ' term://' . s:fnameescape(s:UserCommand(dir, args)) . '|startinsert' . after
+    elseif has('terminal')
+      if &autowrite || &autowriteall | silent! wall | endif
+      return 'exe ' . string(mods . 'terminal ' . (a:count ? '' : '++curwin ') . join(map(s:UserCommandList(dir) + args, 's:fnameescape(v:val)'))) . after
+    endif
   endif
-  let git = s:UserCommand()
   if has('gui_running') && !has('win32')
-    let git .= ' --no-pager'
+    call insert(args, '--no-pager')
   endif
-  let args = matchstr(a:arg,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
-  let after = matchstr(a:arg, '\v\C\\@<!%(\\\\)*\zs\|.*')
-  let tree = s:Tree()
-  if !s:CanAutoReloadStatus()
-    let after = '|call fugitive#ReloadStatus()' . after
-  endif
-  if exists(':terminal') && has('nvim') && !get(g:, 'fugitive_force_bang_command')
-    if len(@%)
-      -tabedit %
-    else
-      -tabnew
-    endif
-    execute 'lcd' fnameescape(tree)
-    let exec = escape(git . ' ' . s:ShellExpand(args), '#%')
-    return 'exe ' . string('terminal ' . exec) . after
-  else
-    let cmd = "exe '!'.escape(" . string(git) . " . ' ' . s:ShellExpand(" . string(args) . "),'!#%')"
-    if s:cpath(tree) !=# s:cpath(getcwd())
-      let cd = s:Cd()
-      let cmd = 'try|' . cd . ' ' . tree . '|' . cmd . '|finally|' . cd . ' ' . s:fnameescape(getcwd()) . '|endtry'
-    endif
-    return cmd . after
+  let pre = ''
+  if has('nvim') && executable('env')
+    let pre .= 'env GIT_TERMINAL_PROMPT=0 '
   endif
+  return 'exe ' . string('!' . escape(pre . s:UserCommand(dir, args), '!#%')) . after
 endfunction
 
 let s:exec_paths = {}
-function! s:Subcommands() abort
+function! s:ExecPath() abort
   if !has_key(s:exec_paths, g:fugitive_git_executable)
     let s:exec_paths[g:fugitive_git_executable] = s:sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
   endif
-  let exec_path = s:exec_paths[g:fugitive_git_executable]
+  return s:exec_paths[g:fugitive_git_executable]
+endfunction
+
+function! s:Subcommands() abort
+  let exec_path = s:ExecPath()
   return map(split(glob(exec_path.'/git-*'),"\n"),'s:sub(v:val[strlen(exec_path)+5 : -1],"\\.exe$","")')
 endfunction
 
@@ -1880,8 +2169,8 @@ let s:aliases = {}
 function! s:Aliases(dir) abort
   if !has_key(s:aliases, a:dir)
     let s:aliases[a:dir] = {}
-    let lines = split(s:TreeChomp('config','-z','--get-regexp','^alias[.]'),"\1")
-    for line in v:shell_error ? [] : lines
+    let lines = s:NullError([a:dir, 'config', '-z', '--get-regexp', '^alias[.]'])[0]
+    for line in lines
       let s:aliases[a:dir][matchstr(line, '\.\zs.\{-}\ze\n')] = matchstr(line, '\n\zs.*')
     endfor
   endif
@@ -1891,16 +2180,26 @@ endfunction
 function! fugitive#CompleteGit(lead, ...) abort
   let dir = a:0 == 1 ? a:1 : a:0 == 3 ? a:3 : s:Dir()
   let pre = a:0 > 1 ? strpart(a:1, 0, a:2) : ''
-  if pre !~# ' [[:alnum:]-]\+ '
-    let cmds = s:Subcommands()
-    return filter(sort(cmds+keys(s:Aliases(dir))), 'strpart(v:val, 0, strlen(a:lead)) ==# a:lead')
+  let subcmd = matchstr(pre, '\u\w*[! ] *\zs[[:alnum:]-]\+\ze ')
+  if empty(subcmd)
+    let results = sort(s:Subcommands() + keys(s:Aliases(dir)))
   elseif pre =~# ' -- '
     return fugitive#CompletePath(a:lead, dir)
+  elseif a:lead =~# '^-'
+    let results = split(s:ChompDefault('', dir, subcmd, '--git-completion-helper'), ' ')
   else
     return fugitive#CompleteObject(a:lead, dir)
   endif
+  return filter(results, 'strpart(v:val, 0, strlen(a:lead)) ==# a:lead')
 endfunction
 
+function! fugitive#Complete(...) abort
+  return call('fugitive#CompleteGit', a:000)
+endfunction
+
+call s:command("-bang -nargs=? -range=-1 -addr=other -complete=customlist,fugitive#CompleteGit Git", "Git")
+call s:command("-bang -nargs=? -range=-1 -addr=other -complete=customlist,fugitive#CompleteGit G", "Git")
+
 " Section: :Gcd, :Glcd
 
 function! s:DirComplete(A, L, P) abort
@@ -1912,32 +2211,36 @@ function! s:DirArg(path) abort
   if path =~# '^/\|^\a\+:\|^\.\.\=\%(/\|$\)'
     return path
   else
-    return (empty(s:Tree()) ? s:Dir() : s:Tree()) . '/' . path
+    return FugitiveVimPath((empty(s:Tree()) ? s:Dir() : s:Tree()) . '/' . path)
   endif
 endfunction
 
-call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd  :exe 'cd<bang>'  s:fnameescape(s:DirArg(<q-args>))")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :exe 'lcd<bang>' s:fnameescape(s:DirArg(<q-args>))")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd  :exe s:DirCheck()|exe 'cd<bang>'  s:fnameescape(s:DirArg(<q-args>))")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :exe s:DirCheck()|exe 'lcd<bang>' s:fnameescape(s:DirArg(<q-args>))")
 
 " Section: :Gstatus
 
-call s:command("-bar -bang -range=-1 Gstatus", "Status")
-call s:command("-bar -bang -range=-1 G", "Status")
+call s:command("-bar -bang -range=-1 -addr=other Gstatus", "Status")
 
-function! s:StatusCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
+function! s:StatusCommand(line1, line2, range, count, bang, mods, reg, arg, args, ...) abort
+  let dir = a:0 ? a:1 : s:Dir()
+  exe s:DirCheck(dir)
   try
-    let mods = a:mods ==# '<mods>' || empty(a:mods) ? '' : a:mods . ' '
-    if mods !~# 'aboveleft\|belowright\|leftabove\|rightbelow\|topleft\|botright'
-      let mods = (&splitbelow ? 'botright ' : 'topleft ') . mods
-    endif
-    let file = fugitive#Find(':')
+    let mods = s:Mods(a:mods, &splitbelow ? 'botright' : 'topleft')
+    let file = fugitive#Find(':', dir)
     let arg = ' +setl\ foldmethod=syntax\ foldlevel=1\|let\ w:fugitive_status=FugitiveGitDir() ' .
           \ s:fnameescape(file)
     for winnr in range(1, winnr('$'))
       if s:cpath(file, fnamemodify(bufname(winbufnr(winnr)), ':p'))
-        exe winnr . 'wincmd w'
-        let w:fugitive_status = FugitiveGitDir()
-        return s:ReloadStatus()
+        if winnr == winnr()
+          call s:ReloadStatus()
+        else
+          call s:ExpireStatus(dir)
+          exe winnr . 'wincmd w'
+        endif
+        let w:fugitive_status = dir
+        1
+        return ''
       endif
     endfor
     if a:count ==# 0
@@ -1948,11 +2251,37 @@ function! s:StatusCommand(line1, line2, range, count, bang, mods, reg, arg, args
       return mods . (a:count > 0 ? a:count : '') . 'split' . arg
     endif
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
   return ''
 endfunction
 
+function! s:StageJump(offset, section, ...) abort
+  let line = search('^\%(' . a:section . '\)', 'nw')
+  if !line && a:0
+    let line = search('^\%(' . a:1 . '\)', 'nw')
+  endif
+  if line
+    exe line
+    if a:offset
+      for i in range(a:offset)
+        call search(s:file_commit_pattern . '\|^$', 'W')
+        if empty(getline('.')) && a:0 && getline(line('.') + 1) =~# '^\%(' . a:1 . '\)'
+          call search(s:file_commit_pattern . '\|^$', 'W')
+        endif
+        if empty(getline('.'))
+          return ''
+        endif
+      endfor
+      call s:StageReveal()
+    else
+      call s:StageReveal()
+      +
+    endif
+  endif
+  return ''
+endfunction
+
 function! s:StageSeek(info, fallback) abort
   let info = a:info
   if empty(info.section)
@@ -1960,7 +2289,7 @@ function! s:StageSeek(info, fallback) abort
   endif
   let line = search('^' . info.section, 'wn')
   if !line
-    for section in get({'Staged': ['Unstaged'], 'Unstaged': ['Staged']}, info.section, [])
+    for section in get({'Staged': ['Unstaged', 'Untracked'], 'Unstaged': ['Untracked', 'Staged'], 'Untracked': ['Unstaged', 'Staged']}, info.section, [])
       let line = search('^' . section, 'wn')
       if line
         return line + (info.index > 0 ? 1 : 0)
@@ -2013,6 +2342,7 @@ function! s:StageSeek(info, fallback) abort
 endfunction
 
 function! s:ReloadStatus(...) abort
+  call s:ExpireStatus(-1)
   if get(b:, 'fugitive_type', '') !=# 'index'
     return ''
   endif
@@ -2024,57 +2354,100 @@ function! s:ReloadStatus(...) abort
   return ''
 endfunction
 
-function! fugitive#ReloadStatus(...) abort
-  if exists('s:reloading_status')
+let s:last_time = reltime()
+if !exists('s:last_times')
+  let s:last_times = {}
+endif
+
+function! s:ExpireStatus(bufnr) abort
+  if a:bufnr == -2
+    let s:last_time = reltime()
+    return ''
+  endif
+  let dir = s:Dir(a:bufnr)
+  if len(dir)
+    let s:last_times[s:cpath(dir)] = reltime()
+  endif
+  return ''
+endfunction
+
+function! FugitiveReloadCheck() abort
+  let t = b:fugitive_reltime
+  return [t, reltimestr(reltime(s:last_time, t)),
+        \ reltimestr(reltime(get(s:last_times, s:cpath(s:Dir()), t), t))]
+endfunction
+
+function! s:ReloadWinStatus(...) abort
+  if get(b:, 'fugitive_type', '') !=# 'index' || &modified
     return
   endif
-  try
-    let s:reloading_status = 1
-    let mytab = tabpagenr()
-    for tab in [mytab] + range(1,tabpagenr('$'))
-      for winnr in range(1,tabpagewinnr(tab,'$'))
-        if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index'
-          execute 'tabnext '.tab
-          if winnr != winnr()
-            execute winnr.'wincmd w'
-            let restorewinnr = 1
-          endif
-          try
-            if !&modified
-              exe s:ReloadStatus()
-            endif
-          finally
-            if exists('restorewinnr')
-              unlet restorewinnr
-              wincmd p
-            endif
-            execute 'tabnext '.mytab
-          endtry
+  if !exists('b:fugitive_reltime')
+    exe s:ReloadStatus()
+    return
+  endif
+  let t = b:fugitive_reltime
+  if reltimestr(reltime(s:last_time, t)) =~# '-\|\d\{10\}\.' ||
+        \ reltimestr(reltime(get(s:last_times, s:cpath(s:Dir()), t), t)) =~# '-\|\d\{10\}\.'
+    exe s:ReloadStatus()
+  endif
+endfunction
+
+function! s:ReloadTabStatus(...) abort
+  let mytab = tabpagenr()
+  let tab = a:0 ? a:1 : mytab
+  for winnr in range(1, tabpagewinnr(tab, '$'))
+    if getbufvar(tabpagebuflist(tab)[winnr-1], 'fugitive_type') ==# 'index'
+      execute 'tabnext '.tab
+      if winnr != winnr()
+        execute winnr.'wincmd w'
+        let restorewinnr = 1
+      endif
+      try
+        call s:ReloadWinStatus()
+      finally
+        if exists('restorewinnr')
+          unlet restorewinnr
+          wincmd p
         endif
-      endfor
+        execute 'tabnext '.mytab
+      endtry
+    endif
+  endfor
+  unlet! t:fugitive_reload_status
+endfunction
+
+function! fugitive#ReloadStatus(...) abort
+  call s:ExpireStatus(a:0 ? a:1 : -2)
+  if a:0 > 1 ? a:2 : s:CanAutoReloadStatus()
+    let t = reltime()
+    let t:fugitive_reload_status = t
+    for tabnr in exists('*settabvar') ? range(1, tabpagenr('$')) : []
+      call settabvar(tabnr, 'fugitive_reload_status', t)
     endfor
-  finally
-    unlet! s:reloading_status
-  endtry
+    call s:ReloadTabStatus()
+  else
+    call s:ReloadWinStatus()
+  endif
 endfunction
 
 function! s:CanAutoReloadStatus() abort
   return get(g:, 'fugitive_autoreload_status', !has('win32'))
 endfunction
 
-function! s:AutoReloadStatus(...) abort
-  if s:CanAutoReloadStatus()
-    return call('fugitive#ReloadStatus', a:000)
-  endif
-endfunction
-
 augroup fugitive_status
   autocmd!
-  autocmd ShellCmdPost         * call s:AutoReloadStatus()
-  autocmd BufDelete     term://* call s:AutoReloadStatus()
+  autocmd BufWritePost         * call fugitive#ReloadStatus(-1, 0)
+  autocmd ShellCmdPost     * nested call fugitive#ReloadStatus()
+  autocmd BufDelete term://* nested call fugitive#ReloadStatus()
   if !has('win32')
-    autocmd FocusGained        * call s:AutoReloadStatus()
+    autocmd FocusGained        * call fugitive#ReloadStatus(-2, 0)
   endif
+  autocmd BufEnter index,index.lock
+        \ call s:ReloadWinStatus()
+  autocmd TabEnter *
+        \ if exists('t:fugitive_reload_status') |
+        \    call s:ReloadTabStatus() |
+        \ endif
 augroup END
 
 function! s:StageInfo(...) abort
@@ -2104,11 +2477,14 @@ function! s:StageInfo(...) abort
       let index += 1
     endif
   endwhile
+  let text = matchstr(getline(lnum), '^[A-Z?] \zs.*')
   return {'section': section,
         \ 'heading': getline(slnum),
         \ 'sigil': sigil,
         \ 'offset': offset,
-        \ 'filename': matchstr(getline(lnum), '^[A-Z?] \zs.*'),
+        \ 'filename': text,
+        \ 'relative': reverse(split(text, ' -> ')),
+        \ 'paths': map(reverse(split(text, ' -> ')), 's:Tree() . "/" . v:val'),
         \ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '),
         \ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'),
         \ 'index': index}
@@ -2117,7 +2493,7 @@ endfunction
 function! s:Selection(arg1, ...) abort
   if a:arg1 ==# 'n'
     let arg1 = line('.')
-    let arg2 = v:count
+    let arg2 = -v:count
   elseif a:arg1 ==# 'v'
     let arg1 = line("'<")
     let arg2 = line("'>")
@@ -2158,6 +2534,7 @@ function! s:Selection(arg1, ...) abort
         \ 'heading': heading,
         \ 'section': matchstr(heading, '^\u\l\+\ze.* (\d\+)$'),
         \ 'filename': '',
+        \ 'relative': [],
         \ 'paths': [],
         \ 'commit': '',
         \ 'status': '',
@@ -2182,6 +2559,7 @@ function! s:Selection(arg1, ...) abort
       call add(results, extend(deepcopy(template), {
             \ 'lnum': lnum,
             \ 'filename': filename,
+            \ 'relative': reverse(split(filename, ' -> ')),
             \ 'paths': map(reverse(split(filename, ' -> ')), 'root . v:val'),
             \ 'status': matchstr(line, '^[A-Z?]'),
             \ }))
@@ -2229,23 +2607,24 @@ endfunction
 
 function! s:Do(action, visual) abort
   let line = getline('.')
+  let reload = 0
   if !a:0 && !v:count && line =~# '^[A-Z][a-z]'
     let header = matchstr(line, '^\S\+\ze:')
     if len(header) && exists('*s:Do' . a:action . header . 'Header')
-      call s:Do{a:action}{header}Header(matchstr(line, ': \zs.*'))
-    endif
-    let section = matchstr(line, '^\S\+')
-    if exists('*s:Do' . a:action . section . 'Heading')
-      call s:Do{a:action}{section}Heading(line)
-      return s:ReloadStatus()
+      let reload = s:Do{a:action}{header}Header(matchstr(line, ': \zs.*')) > 0
+    else
+      let section = matchstr(line, '^\S\+')
+      if exists('*s:Do' . a:action . section . 'Heading')
+        let reload = s:Do{a:action}{section}Heading(line) > 0
+      endif
     endif
+    return reload ? s:ReloadStatus() : ''
   endif
   let selection = s:Selection(a:visual ? 'v' : 'n')
   if empty(selection)
     return ''
   endif
   call filter(selection, 'v:val.section ==# selection[0].section')
-  let reload = 0
   let status = 0
   let err = ''
   try
@@ -2263,13 +2642,16 @@ function! s:Do(action, visual) abort
     if status < 0
       execute record.lnum + 1
     endif
-    call s:StageReveal()
+    let success = 1
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   finally
     if reload
       execute s:ReloadStatus()
     endif
+    if exists('success')
+      call s:StageReveal()
+    endif
   endtry
   return ''
 endfunction
@@ -2281,38 +2663,199 @@ function! s:StageReveal(...) abort
     while getline(end) =~# '^[ \+-]'
       let end += 1
     endwhile
-    while end > line('w$') && line('.') > line('w0') + &scrolloff
+  elseif getline(begin) =~# '^commit '
+    let end = begin
+    while end < line('$') && getline(end + 1) !~# '^commit '
+      let end += 1
+    endwhile
+  elseif getline(begin) =~# s:section_pattern
+    let end = begin
+    while len(getline(end + 1))
+      let end += 1
+    endwhile
+  endif
+  if exists('end')
+    while line('.') > line('w0') + &scrolloff && end > line('w$')
       execute "normal! \<C-E>"
     endwhile
   endif
 endfunction
 
-function! s:StageNext(count) abort
+let s:file_pattern = '^[A-Z?] .\|^diff --'
+let s:file_commit_pattern = s:file_pattern . '\|^\%(\l\{3,\} \)\=[0-9a-f]\{4,\} '
+let s:item_pattern = s:file_commit_pattern . '\|^@@'
+
+function! s:NextHunk(count) abort
+  if &filetype ==# 'fugitive' && getline('.') =~# s:file_pattern
+    exe s:StageInline('show')
+  endif
   for i in range(a:count)
-    call search('^[A-Z?] .\|^[0-9a-f]\{4,\} \|^@','W')
+    if &filetype ==# 'fugitive'
+      call search(s:file_pattern . '\|^@', 'W')
+      if getline('.') =~# s:file_pattern
+        exe s:StageInline('show')
+        if getline(line('.') + 1) =~# '^@'
+          +
+        endif
+      endif
+    else
+      call search('^@@', 'W')
+    endif
   endfor
   call s:StageReveal()
   return '.'
 endfunction
 
-function! s:StagePrevious(count) abort
-  if line('.') == 1 && exists(':CtrlP') && get(g:, 'ctrl_p_map') =~? '^<c-p>$'
-    return 'CtrlP '.fnameescape(s:Tree())
-  else
-    for i in range(a:count)
-      call search('^[A-Z?] .\|^[0-9a-f]\{4,\} \|^@','Wbe')
-    endfor
+function! s:PreviousHunk(count) abort
+  for i in range(a:count)
+    if &filetype ==# 'fugitive'
+      let lnum = search(s:file_pattern . '\|^@','Wbn')
+      call s:StageInline('show', lnum)
+      call search('^? .\|^@','Wb')
+    else
+      call search('^@@', 'Wb')
+    endif
+  endfor
+  call s:StageReveal()
+  return '.'
+endfunction
+
+function! s:NextFile(count) abort
+  for i in range(a:count)
+    exe s:StageInline('hide')
+    if !search(s:file_pattern, 'W')
+      break
+    endif
+  endfor
+  exe s:StageInline('hide')
+  return '.'
+endfunction
+
+function! s:PreviousFile(count) abort
+  exe s:StageInline('hide')
+  for i in range(a:count)
+    if !search(s:file_pattern, 'Wb')
+      break
+    endif
+    exe s:StageInline('hide')
+  endfor
+  return '.'
+endfunction
+
+function! s:NextItem(count) abort
+  for i in range(a:count)
+    if !search(s:item_pattern, 'W') && getline('.') !~# s:item_pattern
+      call search('^commit ', 'W')
+    endif
+  endfor
+  call s:StageReveal()
+  return '.'
+endfunction
+
+function! s:PreviousItem(count) abort
+  for i in range(a:count)
+    if !search(s:item_pattern, 'Wbe') && getline('.') !~# s:item_pattern
+      call search('^commit ', 'Wbe')
+    endif
+  endfor
+  call s:StageReveal()
+  return '.'
+endfunction
+
+let s:section_pattern = '^[A-Z][a-z][^:]*$'
+let s:section_commit_pattern = s:section_pattern . '\|^commit '
+
+function! s:NextSection(count) abort
+  let orig = line('.')
+  if getline('.') !~# '^commit '
+    -
+  endif
+  for i in range(a:count)
+    if !search(s:section_commit_pattern, 'W')
+      break
+    endif
+  endfor
+  if getline('.') =~# s:section_commit_pattern
     call s:StageReveal()
-    return '.'
+    return getline('.') =~# s:section_pattern ? '+' : ':'
+  else
+    return orig
   endif
 endfunction
 
+function! s:PreviousSection(count) abort
+  let orig = line('.')
+  if getline('.') !~# '^commit '
+    -
+  endif
+  for i in range(a:count)
+    if !search(s:section_commit_pattern . '\|\%^', 'bW')
+      break
+    endif
+  endfor
+  if getline('.') =~# s:section_commit_pattern || line('.') == 1
+    call s:StageReveal()
+    return getline('.') =~# s:section_pattern ? '+' : ':'
+  else
+    return orig
+  endif
+endfunction
+
+function! s:NextSectionEnd(count) abort
+  +
+  if empty(getline('.'))
+    +
+  endif
+  for i in range(a:count)
+    if !search(s:section_commit_pattern, 'W')
+      return '$'
+    endif
+  endfor
+  return search('^.', 'Wb')
+endfunction
+
+function! s:PreviousSectionEnd(count) abort
+  let old = line('.')
+  for i in range(a:count)
+    if search(s:section_commit_pattern, 'Wb') <= 1
+      exe old
+      if i
+        break
+      else
+        return ''
+      endif
+    endif
+    let old = line('.')
+  endfor
+  return search('^.', 'Wb')
+endfunction
+
+function! s:PatchSearchExpr(reverse) abort
+  let line = getline('.')
+  if col('.') ==# 1 && line =~# '^[+-]'
+    if line =~# '^[+-]\{3\} '
+      let pattern = '^[+-]\{3\} ' . substitute(escape(strpart(line, 4), '^$.*[]~\'), '^\w/', '\\w/', '') . '$'
+    else
+      let pattern = '^[+-]\s*' . escape(substitute(strpart(line, 1), '^\s*\|\s*$', '', ''), '^$.*[]~\') . '\s*$'
+    endif
+    if a:reverse
+      return '?' . escape(pattern, '/') . "\<CR>"
+    else
+      return '/' . escape(pattern, '/?') . "\<CR>"
+    endif
+  endif
+  return a:reverse ? '#' : '*'
+endfunction
+
 function! s:StageInline(mode, ...) abort
+  if &filetype !=# 'fugitive'
+    return ''
+  endif
   let lnum1 = a:0 ? a:1 : line('.')
   let lnum = lnum1 + 1
   if a:0 > 1 && a:2 == 0
     let info = s:StageInfo(lnum - 1)
-    if empty(info.filename) && len(info.section)
+    if empty(info.paths) && len(info.section)
       while len(getline(lnum))
         let lnum += 1
       endwhile
@@ -2342,7 +2885,7 @@ function! s:StageInline(mode, ...) abort
       endif
       continue
     endif
-    if !has_key(b:fugitive_diff, info.section) || info.status !~# '^[ADM]$' || a:mode ==# 'hide'
+    if !has_key(b:fugitive_diff, info.section) || info.status !~# '^[ADMRU]$' || a:mode ==# 'hide'
       continue
     endif
     let mode = ''
@@ -2359,9 +2902,9 @@ function! s:StageInline(mode, ...) abort
         endif
         let start = index
         let mode = 'head'
-      elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '--- ' . info.filename
+      elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '--- ' . info.relative[-1]
         let mode = 'await'
-      elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '+++ ' . info.filename
+      elseif mode ==# 'head' && substitute(line, "\t$", '', '') ==# '+++ ' . info.relative[0]
         let mode = 'await'
       elseif mode ==# 'capture'
         call add(diff, line)
@@ -2380,19 +2923,10 @@ function! s:StageInline(mode, ...) abort
   return lnum
 endfunction
 
-function! s:StageIntend(count) abort
+function! s:NextExpandedHunk(count) abort
   for i in range(a:count)
-    if getline('.')[0:1] ==# '? '
-      call s:TreeChomp('add', '--intent-to-add', '--', s:Tree() . '/' . getline('.')[2:-1])
-      -
-      exe s:ReloadStatus()
-    elseif getline('.') =~# '^Unstaged'
-      call s:TreeChomp('add', '--intent-to-add', '--', s:Tree())
-      exe s:ReloadStatus()
-    else
-      call s:StageInline('show', line('.'), 1)
-    endif
-    call s:StageNext(1)
+    call s:StageInline('show', line('.'), 1)
+    call search(s:file_pattern . '\|^@','W')
   endfor
   return '.'
 endfunction
@@ -2401,43 +2935,45 @@ function! s:StageDiff(diff) abort
   let lnum = line('.')
   let info = s:StageInfo(lnum)
   let prefix = info.offset > 0 ? '+' . info.offset : ''
-  if empty(info.filename) && info.section ==# 'Staged'
+  if empty(info.paths) && info.section ==# 'Staged'
     return 'Git! diff --no-ext-diff --cached'
-  elseif empty(info.filename)
+  elseif empty(info.paths)
     return 'Git! diff --no-ext-diff'
-  elseif info.filename =~# ' -> '
-    let [old, new] = split(info.filename,' -> ')
-    execute 'Gedit' . prefix s:fnameescape(':0:'.new)
-    return a:diff.' HEAD:'.s:fnameescape(old)
+  elseif len(info.paths) > 1
+    execute 'Gedit' . prefix s:fnameescape(':0:' . info.paths[0])
+    return a:diff . '! HEAD:'.s:fnameescape(info.paths[1])
   elseif info.section ==# 'Staged' && info.sigil ==# '-'
-    execute 'Gedit' prefix s:fnameescape('@:'.info.filename)
-    return a:diff.'! :0'
+    execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0])
+    return a:diff . '! :0:%'
   elseif info.section ==# 'Staged'
-    execute 'Gedit' prefix s:fnameescape(':0:'.info.filename)
-    return a:diff . (info.sigil ==# '+' ? '!' : '') . ' -'
+    execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0])
+    return a:diff . '! @:%'
   elseif info.sigil ==# '-'
-    execute 'Gedit' prefix s:fnameescape(':0:'.info.filename)
-    return a:diff . '!'
+    execute 'Gedit' prefix s:fnameescape(':0:'.info.paths[0])
+    return a:diff . '! :(top)%'
   else
-    execute 'Gedit' prefix s:fnameescape(':(top)'.info.filename)
-    return a:diff . (info.sigil ==# '+' ? '!' : '')
+    execute 'Gedit' prefix s:fnameescape(':(top)'.info.paths[0])
+    return a:diff . '!'
   endif
 endfunction
 
 function! s:StageDiffEdit() abort
   let info = s:StageInfo(line('.'))
-  let arg = (empty(info.filename) ? '.' : info.filename)
+  let arg = (empty(info.paths) ? s:Tree() : info.paths[0])
   if info.section ==# 'Staged'
-    return 'Git! diff --no-ext-diff --cached '.s:shellesc(arg)
+    return 'Git! diff --no-ext-diff --cached '.s:fnameescape(arg)
   elseif info.status ==# '?'
-    call s:TreeChomp('add', '--intent-to-add', './' . arg)
+    call s:TreeChomp('add', '--intent-to-add', '--', arg)
     return s:ReloadStatus()
   else
-    return 'Git! diff --no-ext-diff '.s:shellesc(arg)
+    return 'Git! diff --no-ext-diff '.s:fnameescape(arg)
   endif
 endfunction
 
 function! s:StageApply(info, reverse, extra) abort
+  if a:info.status ==# 'R'
+    call s:throw('fugitive: patching renamed file not yet supported')
+  endif
   let cmd = ['apply', '-p0', '--recount'] + a:extra
   let info = a:info
   let start = info.patch
@@ -2460,8 +2996,10 @@ function! s:StageApply(info, reverse, extra) abort
       call insert(lines, getline(start))
     endif
   endwhile
-  if start == 0 || getline(start) !~# '^@@ '
-    call s:throw("could not find hunk")
+  if start == 0
+    throw 'fugitive: cold not find hunk'
+  elseif getline(start) !~# '^@@ '
+    throw 'fugitive: cannot apply conflict hunk'
   endif
   let i = b:fugitive_expanded[info.section][info.filename][0]
   let head = []
@@ -2476,49 +3014,73 @@ function! s:StageApply(info, reverse, extra) abort
     call add(cmd, '--reverse')
   endif
   call extend(cmd, ['--', temp])
-  let output = call('s:TreeChomp', cmd)
-  if !v:shell_error
+  let [output, exec_error] = s:ChompError(cmd)
+  if !exec_error
     return 1
   endif
   call s:throw(output)
 endfunction
 
-function! s:StageDelete(lnum, count) abort
-  let info = get(s:Selection(a:lnum, -a:count), 0, {'filename': ''})
-  if empty(info.filename)
-    return ''
-  endif
-  let hash = s:TreeChomp('hash-object', '-w', '--', info.paths[0])
-  if empty(hash)
-    return ''
-  elseif info.patch
-    try
-      call s:StageApply(info, 1, info.section ==# 'Staged' ? ['--index'] : [])
-    catch /^fugitive:/
-      return 'echoerr v:errmsg'
-    endtry
-  elseif a:count == 2
-    call s:TreeChomp('checkout', '--ours', '--', info.paths[0])
-  elseif a:count == 3
-    call s:TreeChomp('checkout', '--theirs', '--', info.paths[0])
-  elseif info.status =~# '[ADU]' &&
-        \ get(b:fugitive_status[info.section ==# 'Staged' ? 'Unstaged' : 'Staged'], info.filename, '') =~# '[AU]'
-    call s:TreeChomp('checkout', info.section ==# 'Staged' ? '--ours' : '--theirs', '--', info.paths[0])
-  elseif info.status ==# 'U'
-    call s:TreeChomp('rm', '--', info.paths[0])
-  elseif info.status ==# 'A'
-    call s:TreeChomp('rm', '-f', '--', info.paths[0])
-  elseif info.status ==# '?'
-    call s:TreeChomp('clean', '-f', '--', info.paths[0])
-  elseif info.section ==# 'Unstaged'
-    call s:TreeChomp('checkout', '--', info.paths[0])
-  else
-    call s:TreeChomp('checkout', 'HEAD^{}', '--', info.paths[0])
+function! s:StageDelete(lnum1, lnum2, count) abort
+  let restore = []
+  let err = ''
+  try
+    for info in s:Selection(a:lnum1, a:lnum2)
+      if empty(info.paths)
+        continue
+      endif
+      let hash = s:TreeChomp('hash-object', '-w', '--', info.paths[0])
+      if empty(hash)
+        continue
+      endif
+      if info.patch
+        call s:StageApply(info, 1, info.section ==# 'Staged' ? ['--index'] : [])
+      elseif info.status ==# '?'
+        call s:TreeChomp('clean', '-f', '--', info.paths[0])
+      elseif a:count == 2
+        call s:TreeChomp('checkout', '--ours', '--', info.paths[0])
+      elseif a:count == 3
+        call s:TreeChomp('checkout', '--theirs', '--', info.paths[0])
+      elseif info.status =~# '[ADU]' &&
+            \ get(b:fugitive_status[info.section ==# 'Staged' ? 'Unstaged' : 'Staged'], info.filename, '') =~# '[AU]'
+        call s:TreeChomp('checkout', info.section ==# 'Staged' ? '--ours' : '--theirs', '--', info.paths[0])
+      elseif info.status ==# 'U'
+        call s:TreeChomp('rm', '--', info.paths[0])
+      elseif info.status ==# 'A'
+        call s:TreeChomp('rm', '-f', '--', info.paths[0])
+      elseif info.section ==# 'Unstaged'
+        call s:TreeChomp('checkout', '--', info.paths[0])
+      else
+        call s:TreeChomp('checkout', 'HEAD^{}', '--', info.paths[0])
+      endif
+      call add(restore, ':Gsplit ' . s:fnameescape(info.relative[0]) . '|Gread ' . hash[0:6])
+    endfor
+  catch /^fugitive:/
+    let err = '|echoerr ' . string(v:exception)
+  endtry
+  if empty(restore)
+    return err[1:-1]
   endif
   exe s:ReloadStatus()
-  let @@ = hash
-  return 'checktime|redraw|echomsg ' .
-        \ string('To restore, :Git cat-file blob '.hash[0:6].' > '.info.filename)
+  call s:StageReveal()
+  return 'checktime|redraw|echomsg ' . string('To restore, ' . join(restore, '|')) . err
+endfunction
+
+function! s:StageIgnore(lnum1, lnum2, count) abort
+  let paths = []
+  for info in s:Selection(a:lnum1, a:lnum2)
+    call extend(paths, info.relative)
+  endfor
+  call map(paths, '"/" . v:val')
+  exe 'Gsplit' (a:count ? '.gitignore' : '.git/info/exclude')
+  let last = line('$')
+  if last == 1 && empty(getline(1))
+    call setline(last, paths)
+  else
+    call append(last, paths)
+    exe last + 1
+  endif
+  return ''
 endfunction
 
 function! s:DoToggleHeadHeader(value) abort
@@ -2526,7 +3088,7 @@ function! s:DoToggleHeadHeader(value) abort
   call search('\C^index$', 'wc')
 endfunction
 
-function! s:DoToggleUnpushedHeading(heading) abort
+function! s:DoStageUnpushedHeading(heading) abort
   let remote = matchstr(a:heading, 'to \zs[^/]\+\ze/')
   if empty(remote)
     let remote = '.'
@@ -2535,7 +3097,11 @@ function! s:DoToggleUnpushedHeading(heading) abort
   call feedkeys(':Gpush ' . remote . ' ' . 'HEAD:' . branch)
 endfunction
 
-function! s:DoToggleUnpushed(record) abort
+function! s:DoToggleUnpushedHeading(heading) abort
+  return s:DoStageUnpushedHeading(a:heading)
+endfunction
+
+function! s:DoStageUnpushed(record) abort
   let remote = matchstr(a:record.heading, 'to \zs[^/]\+\ze/')
   if empty(remote)
     let remote = '.'
@@ -2544,14 +3110,30 @@ function! s:DoToggleUnpushed(record) abort
   call feedkeys(':Gpush ' . remote . ' ' . a:record.commit . ':' . branch)
 endfunction
 
-function! s:DoToggleUnpulledHeading(heading) abort
+function! s:DoToggleUnpushed(record) abort
+  return s:DoStageUnpushed(a:record)
+endfunction
+
+function! s:DoUnstageUnpulledHeading(heading) abort
   call feedkeys(':Grebase')
 endfunction
 
-function! s:DoToggleUnpulled(record) abort
+function! s:DoToggleUnpulledHeading(heading) abort
+  call s:DoUnstageUnpulledHeading(a:heading)
+endfunction
+
+function! s:DoUnstageUnpulled(record) abort
   call feedkeys(':Grebase ' . a:record.commit)
 endfunction
 
+function! s:DoToggleUnpulled(record) abort
+  call s:DoUnstageUnpulled(a:record)
+endfunction
+
+function! s:DoUnstageUnpushed(record) abort
+  call feedkeys(':Grebase --autosquash ' . a:record.commit . '^')
+endfunction
+
 function! s:DoToggleStagedHeading(...) abort
   call s:TreeChomp('reset', '-q')
   return 1
@@ -2570,6 +3152,15 @@ function! s:DoStageUnstagedHeading(heading) abort
   return s:DoToggleUnstagedHeading(a:heading)
 endfunction
 
+function! s:DoToggleUntrackedHeading(...) abort
+  call s:TreeChomp('add', '.')
+  return 1
+endfunction
+
+function! s:DoStageUntrackedHeading(heading) abort
+  return s:DoToggleUntrackedHeading(a:heading)
+endfunction
+
 function! s:DoToggleStaged(record) abort
   if a:record.patch
     return s:StageApply(a:record, 1, ['--cached'])
@@ -2579,16 +3170,12 @@ function! s:DoToggleStaged(record) abort
   endif
 endfunction
 
-function! s:DoStageStaged(record) abort
-  return -1
-endfunction
-
 function! s:DoUnstageStaged(record) abort
   return s:DoToggleStaged(a:record)
 endfunction
 
 function! s:DoToggleUnstaged(record) abort
-  if a:record.patch
+  if a:record.patch && a:record.status !=# 'A'
     return s:StageApply(a:record, 0, ['--cached'])
   else
     call s:TreeChomp(['add', '-A', '--'] + a:record.paths)
@@ -2609,184 +3196,223 @@ function! s:DoUnstageUnstaged(record) abort
   endif
 endfunction
 
+function! s:DoToggleUntracked(record) abort
+  call s:TreeChomp(['add', '--'] + a:record.paths)
+  return 1
+endfunction
+
+function! s:DoStageUntracked(record) abort
+  return s:DoToggleUntracked(a:record)
+endfunction
+
 function! s:StagePatch(lnum1,lnum2) abort
   let add = []
   let reset = []
+  let intend = []
 
   for lnum in range(a:lnum1,a:lnum2)
     let info = s:StageInfo(lnum)
-    if empty(info.filename) && info.section ==# 'Staged'
+    if empty(info.paths) && info.section ==# 'Staged'
       return 'Git reset --patch'
-    elseif empty(info.filename) && info.section ==# 'Unstaged'
+    elseif empty(info.paths) && info.section ==# 'Unstaged'
       return 'Git add --patch'
-    elseif info.filename ==# ''
+    elseif empty(info.paths) && info.section ==# 'Untracked'
+      return 'Git add --interactive'
+    elseif empty(info.paths)
       continue
     endif
     execute lnum
-    if info.filename =~ ' -> '
-      let reset += [split(info.filename,' -> ')[1]]
-    elseif info.section ==# 'Staged'
-      let reset += [info.filename]
+    if info.section ==# 'Staged'
+      let reset += info.relative
+    elseif info.section ==# 'Untracked'
+      let intend += info.paths
     elseif info.status !~# '^D'
-      let add += [info.filename]
+      let add += info.relative
     endif
   endfor
   try
+    if !empty(intend)
+      call s:TreeChomp(['add', '--intent-to-add', '--'] + intend)
+    endif
     if !empty(add)
-      execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)'))
+      execute "Git add --patch -- ".join(map(add,'s:fnameescape(v:val)'))
     endif
     if !empty(reset)
-      execute "Git reset --patch -- ".join(map(reset,'s:shellesc(v:val)'))
+      execute "Git reset --patch -- ".join(map(reset,'s:fnameescape(v:val)'))
     endif
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
   return s:ReloadStatus()
 endfunction
 
-" Section: :Gcommit
+" Section: :Gcommit, :Grevert
 
-call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit", "Commit")
+function! s:CommitInteractive(line1, line2, range, bang, mods, args, patch) abort
+  let status = s:StatusCommand(a:line1, a:line2, a:range, a:line2, a:bang, a:mods, '', '', [])
+  let status = len(status) ? status . '|' : ''
+  if a:patch
+    return status . 'if search("^Unstaged")|exe "normal >"|exe "+"|endif'
+  else
+    return status . 'if search("^Untracked\\|^Unstaged")|exe "+"|endif'
+  endif
+endfunction
 
-function! s:CommitCommand(line1, line2, range, count, bang, mods, reg, arg, args, ...) abort
-  let mods = s:gsub(a:mods ==# '<mods>' ? '' : a:mods, '<tab>', '-tab')
+function! s:CommitSubcommand(line1, line2, range, bang, mods, args, ...) abort
+  let mods = substitute(s:Mods(a:mods), '\C\<tab\>', '-tab', 'g')
   let dir = a:0 ? a:1 : s:Dir()
   let tree = s:Tree(dir)
-  let msgfile = dir . '/COMMIT_EDITMSG'
+  let msgfile = fugitive#Find('.git/COMMIT_EDITMSG', dir)
   let outfile = tempname()
-  let errorfile = tempname()
   try
-    let guioptions = &guioptions
-    try
-      if &guioptions =~# '!'
-        setglobal guioptions-=!
-      endif
-      let cdback = s:Cd(tree)
-      if s:winshell()
-        let command = ''
-        let old_editor = $GIT_EDITOR
-        let $GIT_EDITOR = 'false'
+    if s:winshell()
+      let command = 'set GIT_EDITOR=false& '
+    else
+      let command = 'env GIT_EDITOR=false '
+    endif
+    let argv = a:args
+    let i = 0
+    while get(argv, i, '--') !=# '--'
+      if argv[i] =~# '^-[apzsneiovq].'
+        call insert(argv, argv[i][0:1])
+        let argv[i+1] = '-' . argv[i+1][2:-1]
       else
-        let command = 'env GIT_EDITOR=false '
+        let i += 1
       endif
-      let args = s:ShellExpand(a:arg)
-      let command .= s:UserCommand() . ' commit ' . args
-      if &shell =~# 'csh'
-        noautocmd silent execute '!('.escape(command, '!#%').' > '.outfile.') >& '.errorfile
-      elseif a:arg =~# '\%(^\| \)-\%(-interactive\|p\|-patch\)\>'
-        noautocmd execute '!'.command.' 2> '.errorfile
-      else
-        noautocmd silent execute '!'.command.' > '.outfile.' 2> '.errorfile
-      endif
-      let error = v:shell_error
-    finally
-      execute cdback
-      let &guioptions = guioptions
-    endtry
+    endwhile
+    let command .= s:UserCommand(dir, ['commit'] + argv)
+    if (&autowrite || &autowriteall) && !a:0
+      silent! wall
+    endif
+    if s:HasOpt(argv, '-i', '--interactive')
+      return s:CommitInteractive(a:line1, a:line2, a:range, a:bang, a:mods, argv, 0)
+    elseif s:HasOpt(argv, '-p', '--patch')
+      return s:CommitInteractive(a:line1, a:line2, a:range, a:bang, a:mods, argv, 1)
+    else
+      let [error_string, exec_error] = s:TempCmd(outfile, command)
+      let errors = split(error_string, "\n")
+    endif
     if !has('gui_running')
       redraw!
     endif
-    if !error
+    if !exec_error
+      echo join(errors, "\n")
       if filereadable(outfile)
-        for line in readfile(outfile)
-          echo line
-        endfor
+        echo join(readfile(outfile), "\n")
       endif
-      call fugitive#ReloadStatus()
+      call fugitive#ReloadStatus(dir, 1)
       return ''
     else
-      let errors = readfile(errorfile)
       let error = get(errors,-2,get(errors,-1,'!'))
       if error =~# 'false''\=\.$'
-        let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[esp]|--edit|--interactive|--patch|--signoff)%($| )','')
-        let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-c|--reedit-message|--reuse-message|-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
-        let args = s:sub(args, '\ze -- |$', ' --no-edit --no-interactive --no-signoff')
-        let args = '-F '.s:shellesc(msgfile).' '.args
-        if args !~# '\%(^\| \)--cleanup\>'
-          let args = '--cleanup=strip '.args
+        let i = 0
+        while get(argv, i, '--') !=# '--'
+          if argv[i] =~# '^\%(-[eips]\|-[CcFm].\+\|--edit\|--interactive\|--patch\|--signoff\|--reedit-message=.*\|--reuse-message=.*\|--file=.*\|--message=.*\)$'
+            call remove(argv, i)
+          elseif argv[i] =~# '^\%(-[CcFm]\|--reedit-message\|--reuse-message\|--file\|--message\)$'
+            call remove(argv, i, i + 1)
+          else
+            if argv[i] =~# '^--cleanup\>'
+              let cleanup = 1
+            endif
+            let i += 1
+          endif
+        endwhile
+        call insert(argv, '--no-signoff', i)
+        call insert(argv, '--no-interactive', i)
+        call insert(argv, '--no-edit', i)
+        if !exists('cleanup')
+          call insert(argv, '--cleanup=strip')
         endif
-        if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
-          execute mods 'keepalt edit' s:fnameescape(msgfile)
-        elseif a:arg =~# '\%(^\| \)-\w*v' || mods =~# '\<tab\>'
-          execute mods 'keepalt -tabedit' s:fnameescape(msgfile)
+        call extend(argv, ['-F', msgfile], 'keep')
+        if (bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&modified) || a:line2 == 0
+          execute mods . 'keepalt edit' s:fnameescape(msgfile)
+        elseif s:HasOpt(argv, '-v') || mods =~# '\<tab\>'
+          execute mods . 'keepalt -tabedit' s:fnameescape(msgfile)
         else
-          execute mods 'keepalt split' s:fnameescape(msgfile)
+          execute mods . 'keepalt split' s:fnameescape(msgfile)
         endif
-        let b:fugitive_commit_arguments = args
+        let b:fugitive_commit_arguments = argv
         setlocal bufhidden=wipe filetype=gitcommit
         return '1'
-      elseif error ==# '!'
-        echo get(readfile(outfile), -1, '')
+      elseif empty(errors)
+        let out = readfile(outfile)
+        echo get(out, -1, '') =~# 'stash\|\d' ? get(out, -2, '') : get(out, -1, '')
         return ''
       else
-        call s:throw(empty(error)?join(errors, ' '):error)
+        echo join(errors, "\n")
+        return ''
       endif
     endif
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   finally
-    if exists('old_editor')
-      let $GIT_EDITOR = old_editor
-    endif
     call delete(outfile)
-    call delete(errorfile)
   endtry
 endfunction
 
-function! s:CommitComplete(A,L,P) abort
+function! s:RevertSubcommand(line1, line2, range, bang, mods, args) abort
+  let dir = s:Dir()
+  let no_commit = s:HasOpt(a:args, '-n', '--no-commit', '--no-edit', '--abort', '--continue', '--quit')
+  let cmd = s:UserCommand(dir, ['revert'] + (no_commit ? [] : ['-n']) + a:args)
+  let [out, exec_error] = s:SystemError(cmd)
+  call fugitive#ReloadStatus(-1, 1)
+  if no_commit || exec_error
+    return 'echo ' . string(substitute(out, "\n$", '', ''))
+  endif
+  return s:CommitSubcommand(a:line1, a:line2, a:range, a:bang, a:mods, [], dir)
+endfunction
+
+function! s:CommitComplete(A, L, P) abort
   if a:A =~# '^--fixup=\|^--squash='
-    let commits = split(s:TreeChomp('log', '--pretty=format:%s', '@{upstream}..'), "\n")
-    if !v:shell_error
-      let pre = matchstr(a:A, '^--\w*=') . ':/^'
-      return map(commits, 'pre . tr(v:val, "\\ !^$*?[]()''\"`&;<>|#", "....................")')
+    let commits = s:LinesError(['log', '--pretty=format:%s', '@{upstream}..'])[0]
+    let pre = matchstr(a:A, '^--\w*=''\=') . ':/^'
+    if pre =~# "'"
+      call map(commits, 'pre . string(tr(v:val, "|\"^$*[]", "......."))[1:-1]')
+      call filter(commits, 'strpart(v:val, 0, strlen(a:A)) ==# a:A')
+      return commits
+    else
+      return s:FilterEscape(map(commits, 'pre . tr(v:val, "\\ !^$*?[]()''\"`&;<>|#", "....................")'), a:A)
     endif
-  elseif a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
-    let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--fixup=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--squash=', '--template=', '--untracked-files', '--verbose']
-    return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
   else
-    return fugitive#CompletePath(a:A, s:Dir())
+    return s:CompleteSub('commit', a:A, a:L, a:P, function('fugitive#CompletePath'))
   endif
   return []
 endfunction
 
+function! s:RevertComplete(A, L, P) abort
+  return s:CompleteSub('revert', a:A, a:L, a:P, function('s:CompleteRevision'))
+endfunction
+
 function! s:FinishCommit() abort
   let buf = +expand('<abuf>')
   let args = getbufvar(buf, 'fugitive_commit_arguments')
   if !empty(args)
-    call setbufvar(buf, 'fugitive_commit_arguments', '')
+    call setbufvar(buf, 'fugitive_commit_arguments', [])
     if getbufvar(buf, 'fugitive_commit_rebase')
       call setbufvar(buf, 'fugitive_commit_rebase', 0)
       let s:rebase_continue = s:Dir(buf)
     endif
-    return s:CommitCommand(-1, -1, 0, -1, 0, '', '', args, [], s:Dir(buf))
+    return s:CommitSubcommand(-1, -1, 0, 0, '', args, s:Dir(buf))
   endif
   return ''
 endfunction
 
+call s:command("-nargs=? -range=-1 -complete=customlist,s:CommitComplete Gcommit", "commit")
+call s:command("-nargs=? -range=-1 -complete=customlist,s:RevertComplete Grevert", "revert")
+
 " Section: :Gmerge, :Grebase, :Gpull
 
-call s:command("-nargs=? -bang -complete=custom,s:RevisionComplete Gmerge " .
-      \ "execute s:Merge('merge', <bang>0, '<mods>', <q-args>)")
-call s:command("-nargs=? -bang -complete=custom,s:RevisionComplete Grebase " .
-      \ "execute s:Merge('rebase', <bang>0, '<mods>', <q-args>)")
-call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gpull " .
-      \ "execute s:Merge('pull --progress', <bang>0, '<mods>', <q-args>)")
-
-function! s:RevisionComplete(A, L, P) abort
-  return s:TreeChomp('rev-parse', '--symbolic', '--branches', '--tags', '--remotes')
-        \ . "\nHEAD\nFETCH_HEAD\nMERGE_HEAD\nORIG_HEAD"
+function! s:MergeComplete(A, L, P) abort
+  return s:CompleteSub('merge', a:A, a:L, a:P, function('s:CompleteRevision'))
 endfunction
 
-function! s:RemoteComplete(A, L, P) abort
-  let remote = matchstr(a:L, ' \zs\S\+\ze ')
-  if !empty(remote)
-    let matches = split(s:TreeChomp('ls-remote', remote), "\n")
-    call filter(matches, 'v:val =~# "\t" && v:val !~# "{"')
-    call map(matches, 's:sub(v:val, "^.*\t%(refs/%(heads/|tags/)=)=", "")')
-  else
-    let matches = split(s:TreeChomp('remote'), "\n")
-  endif
-  return join(matches, "\n")
+function! s:RebaseComplete(A, L, P) abort
+  return s:CompleteSub('rebase', a:A, a:L, a:P, function('s:CompleteRevision'))
+endfunction
+
+function! s:PullComplete(A, L, P) abort
+  return s:CompleteSub('pull', a:A, a:L, a:P, function('s:CompleteRemote'))
 endfunction
 
 function! s:RebaseSequenceAborter() abort
@@ -2836,14 +3462,35 @@ let s:rebase_abbrevs = {
       \ }
 
 function! s:RebaseEdit(cmd, dir) abort
-  return a:cmd . ' +setlocal\ bufhidden=wipe ' . s:fnameescape(a:dir . '/rebase-merge/git-rebase-todo')
+  let rebase_todo = s:fnameescape(fugitive#Find('.git/rebase-merge/git-rebase-todo', a:dir))
+
+  if filereadable(rebase_todo)
+    let new = readfile(rebase_todo)
+    let sha_length = 0
+    let shas = {}
+
+    for i in range(len(new))
+      if new[i] =~# '^\l\+\s\+[0-9a-f]\{5,\}\>'
+        let sha = matchstr(new[i], '\C\<[a-f0-9]\{5,\}\>')
+        if !sha_length
+          let sha_length = len(s:TreeChomp(a:dir, 'rev-parse', '--short', sha))
+        endif
+        let shortened_sha = strpart(sha, 0, sha_length)
+        let shas[shortened_sha] = sha
+        let new[i] = substitute(new[i], sha, shortened_sha, '')
+      endif
+    endfor
+    call writefile(new, rebase_todo)
+  endif
+  return a:cmd . ' +setlocal\ bufhidden=wipe\|' . escape('let b:fugitive_rebase_shas = ' . string(shas), ' ') . ' ' . rebase_todo
 endfunction
 
-function! s:Merge(cmd, bang, mods, args, ...) abort
+function! s:MergeRebase(cmd, bang, mods, args, ...) abort
   let dir = a:0 ? a:1 : s:Dir()
-  let mods = substitute(a:mods, '\C<mods>', '', '') . ' '
-  if a:cmd =~# '^rebase' && ' '.a:args =~# ' -i\| --interactive'
-    let cmd = fugitive#Prepare(dir, '-c', 'sequence.editor=sh ' . s:RebaseSequenceAborter(), 'rebase') . ' ' . a:args
+  let args = a:args
+  let mods = s:Mods(a:mods)
+  if a:cmd =~# '^rebase' && s:HasOpt(args, '-i', '--interactive')
+    let cmd = fugitive#Prepare(dir, '-c', 'sequence.editor=sh ' . s:RebaseSequenceAborter(), 'rebase') . ' ' . s:shellesc(args)
     let out = system(cmd)[0:-2]
     for file in ['end', 'msgnum']
       let file = fugitive#Find('.git/rebase-merge/' . file, dir)
@@ -2854,24 +3501,38 @@ function! s:Merge(cmd, bang, mods, args, ...) abort
     endfor
     call writefile([], fugitive#Find('.git/rebase-merge/done', dir))
     if a:bang
-      return ''
+      return 'exe'
     endif
     return s:RebaseEdit(mods . 'split', dir)
-  elseif a:cmd =~# '^rebase' && ' '.a:args =~# ' --edit-todo' && filereadable(dir . '/rebase-merge/git-rebase-todo')
+  elseif a:cmd =~# '^rebase' && s:HasOpt(args, '--edit-todo') && filereadable(fugitive#Find('.git/rebase-merge/git-rebase-todo', dir))
     return s:RebaseEdit(mods . 'split', dir)
-  elseif a:cmd =~# '^rebase' && ' '.a:args =~# ' --continue' && !a:0
-    let rdir = dir . '/rebase-merge'
-    call system(fugitive#Prepare(dir, 'diff-index', '--cached', '--quiet', 'HEAD', '--'))
-    if v:shell_error && isdirectory(rdir)
+  elseif a:cmd =~# '^rebase' && s:HasOpt(args, '--continue') && !a:0
+    let rdir = fugitive#Find('.git/rebase-merge', dir)
+    let exec_error = s:ChompError([dir, 'diff-index', '--cached', '--quiet', 'HEAD', '--'])[1]
+    if exec_error && isdirectory(rdir)
       if getfsize(rdir . '/amend') <= 0
-        return 'exe ' . string(mods . 'Gcommit -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
+        return 'exe ' . string(mods . 'Gcommit -n -F ' . s:fnameescape(rdir .'/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
       elseif readfile(rdir . '/amend')[0] ==# fugitive#Head(-1, dir)
-        return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
+        return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:fnameescape(rdir . '/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
       endif
     endif
   endif
+  let had_merge_msg = filereadable(fugitive#Find('.git/MERGE_MSG', dir))
+  let argv = []
+  if a:cmd ==# 'pull'
+    let argv += s:AskPassArgs(dir) + ['pull', '--progress']
+  else
+    call add(argv, a:cmd)
+  endif
+  if !s:HasOpt(args, '--no-edit', '--abort', '-m') && a:cmd !=# 'rebase'
+    call add(argv, '--edit')
+  endif
+  if a:cmd ==# 'rebase' && s:HasOpt(args, '--autosquash') && !s:HasOpt(args, '--interactive', '-i')
+    call add(argv, '--interactive')
+  endif
+  call extend(argv, args)
+
   let [mp, efm] = [&l:mp, &l:efm]
-  let had_merge_msg = filereadable(dir . '/MERGE_MSG')
   try
     let cdback = s:Cd(s:Tree(dir))
     let &l:errorformat = ''
@@ -2895,32 +3556,38 @@ function! s:Merge(cmd, bang, mods, args, ...) abort
           \ . "%+EXUNG \u0110\u1ed8T %.%#,"
           \ . "%+E\u51b2\u7a81 %.%#,"
           \ . 'U%\t%f'
-    if a:cmd =~# '^merge' && empty(a:args) &&
-          \ (had_merge_msg || isdirectory(dir . '/rebase-apply') ||
+    if a:cmd =~# '^merge' && empty(args) &&
+          \ (had_merge_msg || isdirectory(fugitive#Find('.git/rebase-apply', dir)) ||
           \  !empty(s:TreeChomp(dir, 'diff-files', '--diff-filter=U')))
-      let &l:makeprg = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
+      let cmd = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
     else
-      let &l:makeprg = s:sub(s:UserCommand() . ' ' . a:cmd .
-            \ (' ' . a:args =~# ' \%(--no-edit\|--abort\|-m\)\>' || a:cmd =~# '^rebase' ? '' : ' --edit') .
-            \ (' ' . a:args =~# ' --autosquash\>' && a:cmd =~# '^rebase' ? ' --interactive' : '') .
-            \ ' ' . a:args, ' *$', '')
+      let cmd = s:UserCommand(dir, argv)
     endif
     if !empty($GIT_SEQUENCE_EDITOR) || has('win32')
       let old_sequence_editor = $GIT_SEQUENCE_EDITOR
       let $GIT_SEQUENCE_EDITOR = 'true'
     else
-      let &l:makeprg = 'env GIT_SEQUENCE_EDITOR=true ' . &l:makeprg
+      let cmd = 'env GIT_SEQUENCE_EDITOR=true ' . cmd
     endif
     if !empty($GIT_EDITOR) || has('win32')
       let old_editor = $GIT_EDITOR
       let $GIT_EDITOR = 'false'
     else
-      let &l:makeprg = 'env GIT_EDITOR=false ' . substitute(&l:makeprg, '^env ', '', '')
+      let cmd = 'env GIT_EDITOR=false ' . substitute(cmd, '^env ', '', '')
     endif
+    if !has('patch-8.1.0334') && has('terminal') && &autowrite
+      let autowrite_was_set = 1
+      set noautowrite
+      silent! wall
+    endif
+    let &l:makeprg = cmd
     silent noautocmd make!
   catch /^Vim\%((\a\+)\)\=:E211/
     let err = v:exception
   finally
+    if exists('autowrite_was_set')
+      set autowrite
+    endif
     redraw!
     let [&l:mp, &l:efm] = [mp, efm]
     if exists('old_editor')
@@ -2931,17 +3598,17 @@ function! s:Merge(cmd, bang, mods, args, ...) abort
     endif
     execute cdback
   endtry
-  call fugitive#ReloadStatus()
+  call fugitive#ReloadStatus(dir, 1)
   if empty(filter(getqflist(),'v:val.valid && v:val.type !=# "I"'))
     if a:cmd =~# '^rebase' &&
-          \ filereadable(dir . '/rebase-merge/amend') &&
-          \ filereadable(dir . '/rebase-merge/done') &&
-          \ get(readfile(dir . '/rebase-merge/done'), -1, '') =~# '^[^e]'
+          \ filereadable(fugitive#Find('.git/rebase-merge/amend', dir)) &&
+          \ filereadable(fugitive#Find('.git/rebase-merge/done', dir)) &&
+          \ get(readfile(fugitive#Find('.git/rebase-merge/done', dir)), -1, '') =~# '^[^e]'
       cclose
-      return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
-    elseif !had_merge_msg && filereadable(dir . '/MERGE_MSG')
+      return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:fnameescape(fugitive#Find('.git/rebase-merge/message', dir)) . ' -e') . '|let b:fugitive_commit_rebase = 1'
+    elseif !had_merge_msg && filereadable(fugitive#Find('.git/MERGE_MSG', dir))
       cclose
-      return mods . 'Gcommit --no-status -n -t '.s:shellesc(dir . '/MERGE_MSG')
+      return mods . 'Gcommit --no-status -n -t '.s:fnameescape(fugitive#Find('.git/MERGE_MSG', dir))
     endif
   endif
   let qflist = getqflist()
@@ -2956,10 +3623,11 @@ function! s:Merge(cmd, bang, mods, args, ...) abort
   if found
     call setqflist(qflist, 'r')
     if !a:bang
+      call s:BlurStatus()
       return 'cfirst'
     endif
   endif
-  return exists('err') ? 'echoerr '.string(err) : ''
+  return exists('err') ? 'echoerr '.string(err) : 'exe'
 endfunction
 
 function! s:RebaseClean(file) abort
@@ -2970,6 +3638,12 @@ function! s:RebaseClean(file) abort
   let new = copy(old)
   for i in range(len(new))
     let new[i] = substitute(new[i], '^\l\>', '\=get(s:rebase_abbrevs,submatch(0),submatch(0))', '')
+
+    let sha = matchstr(new[i], '\C\<[a-f0-9]\{5,\}\>')
+    let rebase_shas = getbufvar(a:file, 'fugitive_rebase_shas')
+    if len(sha) && type(rebase_shas) == type({}) && has_key(rebase_shas, sha)
+      let new[i] = substitute(new[i], '\C\<' . sha . '\>', rebase_shas[sha], '')
+    endif
   endfor
   if new !=# old
     call writefile(new, a:file)
@@ -2977,6 +3651,18 @@ function! s:RebaseClean(file) abort
   return ''
 endfunction
 
+function! s:MergeSubcommand(line1, line2, range, bang, mods, args) abort
+  return s:MergeRebase('merge', a:bang, a:mods, a:args)
+endfunction
+
+function! s:RebaseSubcommand(line1, line2, range, bang, mods, args) abort
+  return s:MergeRebase('rebase', a:bang, a:mods, a:args)
+endfunction
+
+function! s:PullSubcommand(line1, line2, range, bang, mods, args) abort
+  return s:MergeRebase('pull', a:bang, a:mods, a:args)
+endfunction
+
 augroup fugitive_merge
   autocmd!
   autocmd VimLeavePre,BufDelete git-rebase-todo
@@ -2988,10 +3674,14 @@ augroup fugitive_merge
         \ endif
   autocmd BufEnter * nested
         \ if exists('s:rebase_continue') |
-        \   exe s:Merge('rebase', 0, '', getfsize(fugitive#Find('.git/rebase-merge/git-rebase-todo', s:rebase_continue)) > 0 ? '--continue' : '--abort', remove(s:, 'rebase_continue')) |
+        \   exe s:MergeRebase('rebase', 0, '', [getfsize(fugitive#Find('.git/rebase-merge/git-rebase-todo', s:rebase_continue)) > 0 ? '--continue' : '--abort'], remove(s:, 'rebase_continue')) |
         \ endif
 augroup END
 
+call s:command("-nargs=? -bang -complete=customlist,s:MergeComplete Gmerge", "merge")
+call s:command("-nargs=? -bang -complete=customlist,s:RebaseComplete Grebase", "rebase")
+call s:command("-nargs=? -bang -complete=customlist,s:PullComplete Gpull", "pull")
+
 " Section: :Ggrep, :Glog
 
 if !exists('g:fugitive_summary_format')
@@ -2999,107 +3689,240 @@ if !exists('g:fugitive_summary_format')
 endif
 
 function! s:GrepComplete(A, L, P) abort
-  if strpart(a:L, 0, a:P) =~# ' -- '
-    return fugitive#CompletePath(a:A, s:Dir())
+  return s:CompleteSub('grep', a:A, a:L, a:P)
+endfunction
+
+function! s:LogComplete(A, L, P) abort
+  return s:CompleteSub('log', a:A, a:L, a:P)
+endfunction
+
+function! s:GrepParseLine(prefix, name_only, dir, line) abort
+  let entry = {'valid': 1}
+  let match = matchlist(a:line, '^\(.\{-\}\):\(\d\+\):\(\d\+:\)\=\(.*\)$')
+  if len(match)
+    let entry.module = match[1]
+    let entry.lnum = +match[2]
+    let entry.col = +match[3]
+    let entry.text = match[4]
+  elseif a:line =~# '^git: \|^usage: \|^error: \|^fatal: '
+    return {'text': a:line}
   else
-    return fugitive#CompleteObject(a:A, s:Dir())
+    let entry.module = matchstr(a:line, '\CBinary file \zs.*\ze matches$')
+    if len(entry.module)
+      let entry.text = 'Binary file'
+      let entry.valid = 0
+    endif
+  endif
+  if empty(entry.module) && a:name_only
+    let entry.module = a:line
+  endif
+  if empty(entry.module)
+    return {'text': a:line}
+  endif
+  if entry.module !~# ':'
+    let entry.filename = a:prefix . entry.module
+  else
+    let entry.filename = fugitive#Find(entry.module, a:dir)
+  endif
+  return entry
+endfunction
+
+function! s:GrepSubcommand(line1, line2, range, bang, mods, args) abort
+  let dir = s:Dir()
+  exe s:DirCheck(dir)
+  let listnr = a:line1 == 0 ? a:line1 : a:line2
+  let cmd = ['--no-pager', 'grep', '-n', '--no-color', '--full-name']
+  if fugitive#GitVersion(2, 19)
+    call add(cmd, '--column')
+  endif
+  let tree = s:Tree(dir)
+  if type(a:args) == type([])
+    let [args, after] = [a:args, '']
+  else
+    let [args, after] = s:SplitExpandChain(a:args, tree)
+  endif
+  let prefix = FugitiveVimPath(s:HasOpt(args, '--cached') || empty(tree) ? 'fugitive://' . dir . '//0/' : tree . '/')
+  let name_only = s:HasOpt(args, '-l', '--files-with-matches', '--name-only', '-L', '--files-without-match')
+  let title = [listnr < 0 ? ':Ggrep' : ':Glgrep'] + args
+  if listnr > 0
+    exe listnr 'wincmd w'
+  else
+    call s:BlurStatus()
+  endif
+  redraw
+  call s:QuickfixCreate(listnr, {'title': (listnr < 0 ? ':Ggrep ' : ':Glgrep ') . s:fnameescape(args)})
+  let tempfile = tempname()
+  if v:version >= 704 | exe 'silent doautocmd <nomodeline> QuickFixCmdPre ' (listnr < 0 ? 'Ggrep' : 'Glgrep') | endif
+  exe '!' . escape(s:UserCommand(dir, cmd + args), '%#!')
+        \ printf(&shellpipe . (&shellpipe =~# '%s' ? '' : ' %s'), s:shellesc(tempfile))
+  let list = map(readfile(tempfile), 's:GrepParseLine(prefix, name_only, dir, v:val)')
+  call s:QuickfixSet(listnr, list, 'a')
+  if v:version >= 704 | exe 'silent doautocmd <nomodeline> QuickFixCmdPost ' (listnr < 0 ? 'Ggrep' : 'Glgrep') | endif
+  if !has('gui_running')
+    redraw
+  endif
+  if !a:bang && !empty(list)
+    return (listnr < 0 ? 'c' : 'l').'first' . after
+  else
+    return after[1:-1]
   endif
 endfunction
 
-call s:command("-bang -nargs=? -complete=customlist,s:GrepComplete Ggrep :execute s:Grep('grep',<bang>0,<q-args>)")
-call s:command("-bang -nargs=? -complete=customlist,s:GrepComplete Glgrep :execute s:Grep('lgrep',<bang>0,<q-args>)")
-call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:GrepComplete Glog :call s:Log('grep',<bang>0,<line1>,<count>,<q-args>)")
-call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:GrepComplete Gllog :call s:Log('lgrep',<bang>0,<line1>,<count>,<q-args>)")
-
-function! s:Grep(cmd,bang,arg) abort
-  let grepprg = &grepprg
-  let grepformat = &grepformat
-  try
-    let cdback = s:Cd(s:Tree())
-    let &grepprg = s:UserCommand() . ' --no-pager grep -n --no-color'
-    let &grepformat = '%f:%l:%c:%m,%f:%l:%m,%m %f match%ts,%f'
-    if fugitive#GitVersion(2, 19)
-      let &grepprg .= ' --column'
-    endif
-    exe a:cmd.'! '.escape(s:ShellExpand(matchstr(a:arg, '\v\C.{-}%($|[''" ]\@=\|)@=')), '|#%')
-    let list = a:cmd =~# '^l' ? getloclist(0) : getqflist()
-    for entry in list
-      if bufname(entry.bufnr) =~ ':'
-        let entry.filename = s:Generate(bufname(entry.bufnr))
-        unlet! entry.bufnr
-        let changed = 1
-      elseif a:arg =~# '\%(^\| \)--cached\>'
-        let entry.filename = s:Generate(':0:'.bufname(entry.bufnr))
-        unlet! entry.bufnr
-        let changed = 1
-      endif
-    endfor
-    if a:cmd =~# '^l' && exists('changed')
-      call setloclist(0, list, 'r')
-    elseif exists('changed')
-      call setqflist(list, 'r')
-    endif
-    if !a:bang && !empty(list)
-      return (a:cmd =~# '^l' ? 'l' : 'c').'first'.matchstr(a:arg,'\v\C[''" ]\zs\|.*')
-    else
-      return matchstr(a:arg,'\v\C[''" ]\|\zs.*')
-    endif
-  finally
-    let &grepprg = grepprg
-    let &grepformat = grepformat
-    execute cdback
-  endtry
+function! s:LogFlushQueue(state) abort
+  let queue = remove(a:state, 'queue')
+  if a:state.child_found
+    call remove(queue, 0)
+  endif
+  if len(queue) && queue[-1] ==# {'text': ''}
+    call remove(queue, -1)
+  endif
+  return queue
 endfunction
 
-function! s:Log(cmd, bang, line1, line2, ...) abort
-  let args = ' ' . join(a:000, ' ')
-  let before = substitute(args, ' --\S\@!.*', '', '')
-  let after = strpart(args, len(before))
-  let path = s:Relative('/')
-  let relative = path[1:-1]
-  if path =~# '^/\.git\%(/\|$\)' || len(after)
+function! s:LogParse(state, dir, line) abort
+  if a:state.context ==# 'hunk' && a:line =~# '^[-+ ]'
+    return []
+  endif
+  let list = matchlist(a:line, '^\%(fugitive \(.\{-\}\)\t\|commit \|From \)\=\(\x\{40,\}\)\%( \(.*\)\)\=$')
+  if len(list)
+    let a:state.context = 'commit'
+    let a:state.base = 'fugitive://' . a:dir . '//' . list[2]
+    let a:state.base_module = len(list[1]) ? list[1] : list[2]
+    let a:state.message = list[3]
+    if has_key(a:state, 'diffing')
+      call remove(a:state, 'diffing')
+    endif
+    let queue = s:LogFlushQueue(a:state)
+    let a:state.queue = [{
+          \ 'valid': 1,
+          \ 'filename': a:state.base . a:state.target,
+          \ 'module': a:state.base_module . substitute(a:state.target, '^/', ':', ''),
+          \ 'text': a:state.message}]
+    let a:state.child_found = 0
+    return queue
+  elseif type(a:line) == type(0)
+    return s:LogFlushQueue(a:state)
+  elseif a:line =~# '^diff'
+    let a:state.context = 'diffhead'
+  elseif a:line =~# '^[+-]\{3\} \w/' && a:state.context ==# 'diffhead'
+    let a:state.diffing = a:line[5:-1]
+  elseif a:line =~# '^@@[^@]*+\d' && has_key(a:state, 'diffing') && has_key(a:state, 'base')
+    let a:state.context = 'hunk'
+    if empty(a:state.target) || a:state.target ==# a:state.diffing
+      let a:state.child_found = 1
+      call add(a:state.queue, {
+            \ 'valid': 1,
+            \ 'filename': a:state.base . a:state.diffing,
+            \ 'module': a:state.base_module . substitute(a:state.diffing, '^/', ':', ''),
+            \ 'lnum': +matchstr(a:line, '+\zs\d\+'),
+            \ 'text': a:state.message . matchstr(a:line, ' @@\+ .\+')})
+    endif
+  elseif a:state.follow &&
+        \ a:line =~# '^ \%(mode change \d\|\%(create\|delete\) mode \d\|\%(rename\|copy\|rewrite\) .* (\d\+%)$\)'
+    let rename = matchstr(a:line, '^ rename \zs.* => .*\ze (\d\+%)$')
+    if len(rename)
+      let rename = rename =~# '{.* => .*}' ? rename : '{' . rename . '}'
+      if a:state.target ==# simplify('/' . substitute(rename, '{.* => \(.*\)}', '\1', ''))
+        let a:state.target = simplify('/' . substitute(rename, '{\(.*\) => .*}', '\1', ''))
+      endif
+    endif
+    if !get(a:state, 'ignore_summary')
+      call add(a:state.queue, {'text': a:line})
+    endif
+  elseif a:state.context ==# 'commit' || a:state.context ==# 'init'
+    call add(a:state.queue, {'text': a:line})
+  endif
+  return []
+endfunction
+
+function! s:Log(type, bang, line1, count, args, legacy) abort
+  let dir = s:Dir()
+  exe s:DirCheck(dir)
+  let listnr = a:type =~# '^l' ? 0 : -1
+  let [args, after] = s:SplitExpandChain(a:args, s:Tree(dir))
+  let split = index(args, '--')
+  if split > 0
+    let paths = args[split : -1]
+    let args = args[0 : split - 1]
+  elseif split == 0
+    let paths = args
+    let args = []
+  else
+    let paths = []
+  endif
+  if a:line1 == 0 && a:count
+    let path = fugitive#Path(bufname(a:count), '/', dir)
+  elseif a:count >= 0
+    let path = fugitive#Path(@%, '/', dir)
+  else
+     let path = ''
+  endif
+  let range = ''
+  let extra = []
+  let state = {'context': 'init', 'child_found': 0, 'queue': [], 'follow': 0}
+  if path =~# '^/\.git\%(/\|$\)\|^$'
+    let path = ''
+  elseif a:line1 == 0
+    let range = "0," . (a:count ? a:count : bufnr(''))
+    let extra = ['.' . path]
+    if (empty(paths) || paths ==# ['--']) && !s:HasOpt(args, '--no-follow')
+      let state.follow = 1
+      if !s:HasOpt(args, '--follow')
+        call insert(args, '--follow')
+      endif
+      if !s:HasOpt(args, '--summary')
+        call insert(args, '--summary')
+        let state.ignore_summary = 1
+      endif
+    endif
+  elseif a:count > 0
+    if !s:HasOpt(args, '--merges', '--no-merges')
+      call insert(args, '--no-merges')
+    endif
+    call add(args, '-L' . a:line1 . ',' . a:count . ':' . path[1:-1])
+  endif
+  if len(path) && empty(filter(copy(args), 'v:val =~# "^[^-]"'))
+    let owner = s:Owner(@%, dir)
+    if len(owner)
+      call add(args, owner)
+    endif
+  endif
+  if empty(extra)
     let path = ''
   endif
-  if before !~# '\s[^[:space:]-]'
-    let owner = s:Owner(@%)
-    if len(owner)
-      let before .= ' ' . s:shellesc(owner)
-    endif
+  if s:HasOpt(args, '-g', '--walk-reflogs')
+    let format = "%gd\t%H %gs"
+  else
+    let format = "%h\t%H " . g:fugitive_summary_format
   endif
-  if relative =~# '^\.git\%(/\|$\)'
-    let relative = ''
+  let cmd = ['--no-pager']
+  if fugitive#GitVersion(1, 9)
+    call extend(cmd, ['-c', 'diff.context=0', '-c', 'diff.noprefix=false', 'log'])
+  else
+    call extend(cmd, ['log', '-U0', '--no-patch'])
   endif
-  if len(relative) && a:line2 > 0
-    let before .= ' -L ' . s:shellesc(a:line1 . ',' . a:line2 . ':' . relative)
-  elseif len(relative) && (empty(after) || a:line2 == 0)
-    let after = (len(after) > 3 ? after : ' -- ') . relative
+  call extend(cmd,
+        \ ['--no-color', '--no-ext-diff', '--pretty=format:fugitive ' . format] +
+        \ args + paths + extra)
+  let state.target = path
+  let title = (listnr < 0 ? ':Gclog ' : ':Gllog ') . s:fnameescape(args + paths)
+  if empty(paths + extra) && a:legacy && len(s:Relative('/'))
+    let after = '|echohl WarningMsg|echo ' . string('Use :0Glog or :0Gclog for old behavior of targeting current file') . '|echohl NONE' . after
   endif
-  let grepformat = &grepformat
-  let grepprg = &grepprg
-  try
-    let cdback = s:Cd(s:Tree())
-    let format = before =~# ' -g\| --walk-reflogs' ? '%gD %gs' : g:fugitive_summary_format
-    let &grepprg = escape(s:UserCommand() . ' --no-pager log --no-color ' .
-          \ s:shellesc('--pretty=format:fugitive://'.s:Dir().'//%H'.path.'::'.format), '%#')
-    let &grepformat = '%Cdiff %.%#,%C--- %.%#,%C+++ %.%#,%Z@@ -%\d%\+\,%\d%\+ +%l\,%\d%\+ @@,%-G-%.%#,%-G+%.%#,%-G %.%#,%A%f::%m,%-G%.%#'
-    exe a:cmd . (a:bang ? '! ' : ' ') . s:ShellExpand(before . after)
-    if len(path) && a:line2 == -1
-      redraw
-      echohl WarningMsg
-      echo ':Glog will soon default to all files. Use :0Glog to target current file'
-      echohl NONE
-    endif
-  finally
-    let &grepformat = grepformat
-    let &grepprg = grepprg
-    execute cdback
-  endtry
+  return s:QuickfixStream(listnr, title, s:UserCommandList(dir) + cmd, !a:bang, s:function('s:LogParse'), state, dir) . after
 endfunction
 
+call s:command("-bang -nargs=? -range=-1 -addr=windows -complete=customlist,s:GrepComplete Ggrep", "grep")
+call s:command("-bang -nargs=? -complete=customlist,s:GrepComplete Gcgrep :execute s:GrepSubcommand(-1, -1, 0, <bang>0, '<mods>', <q-args>)")
+call s:command("-bang -nargs=? -complete=customlist,s:GrepComplete Glgrep :execute s:GrepSubcommand(0, 0, 0, <bang>0, '<mods>', <q-args>)")
+call s:command("-bang -nargs=? -range=-1 -addr=other -complete=customlist,s:LogComplete Glog :exe s:Log('c',<bang>0,<line1>,<count>,<q-args>, 1)")
+call s:command("-bang -nargs=? -range=-1 -addr=other -complete=customlist,s:LogComplete Gclog :exe s:Log('c',<bang>0,<line1>,<count>,<q-args>, 0)")
+call s:command("-bang -nargs=? -range=-1 -addr=other -complete=customlist,s:LogComplete Gllog :exe s:Log('l',<bang>0,<line1>,<count>,<q-args>, 0)")
+
 " Section: :Gedit, :Gpedit, :Gsplit, :Gvsplit, :Gtabedit, :Gread
 
 function! s:UsableWin(nr) abort
-  return a:nr && !getwinvar(a:nr, '&previewwindow') &&
+  return a:nr && !getwinvar(a:nr, '&previewwindow') && !getwinvar(a:nr, '&winfixwidth') &&
         \ (empty(getwinvar(a:nr, 'fugitive_status')) || getbufvar(winbufnr(a:nr), 'fugitive_type') !=# 'index') &&
         \ index(['gitrebase', 'gitcommit'], getbufvar(winbufnr(a:nr), '&filetype')) < 0 &&
         \ index(['nofile','help','quickfix'], getbufvar(winbufnr(a:nr), '&buftype')) < 0
@@ -3123,6 +3946,20 @@ function! s:OpenParse(args) abort
   return [s:Expand(file), join(pre)]
 endfunction
 
+function! s:DiffClose() abort
+  let mywinnr = winnr()
+  for winnr in [winnr('#')] + range(winnr('$'),1,-1)
+    if winnr != mywinnr && getwinvar(winnr,'&diff')
+      execute winnr.'wincmd w'
+      close
+      if winnr('$') > 1
+        wincmd p
+      endif
+    endif
+  endfor
+  diffoff!
+endfunction
+
 function! s:BlurStatus() abort
   if (&previewwindow || exists('w:fugitive_status')) && get(b:,'fugitive_type', '') ==# 'index'
     let winnrs = filter([winnr('#')] + range(1, winnr('$')), 's:UsableWin(v:val)')
@@ -3132,50 +3969,53 @@ function! s:BlurStatus() abort
       belowright new
     endif
     if &diff
-      let mywinnr = winnr()
-      for winnr in range(winnr('$'),1,-1)
-        if winnr != mywinnr && getwinvar(winnr,'&diff')
-          execute winnr.'wincmd w'
-          close
-          if winnr('$') > 1
-            wincmd p
-          endif
-        endif
-      endfor
-      diffoff!
+      call s:DiffClose()
     endif
   endif
 endfunction
 
-function! s:Open(cmd, bang, mods, arg, args) abort
-  let mods = a:mods ==# '<mods>' ? '' : a:mods
-
-  if a:bang
-    let temp = tempname()
-    try
-      let cdback = s:Cd(s:Tree())
-      let git = s:UserCommand()
-      let args = s:ShellExpand(a:arg)
-      silent! execute '!' . escape(git . ' --no-pager ' . args, '!#%') .
-            \ (&shell =~# 'csh' ? ' >& ' . temp : ' > ' . temp . ' 2>&1')
-    finally
-      execute cdback
-    endtry
-    let temp = s:Resolve(temp)
-    let s:temp_files[s:cpath(temp)] = { 'dir': s:Dir(), 'filetype': 'git' }
-    if a:cmd ==# 'edit'
-      call s:BlurStatus()
-    endif
-    silent execute mods a:cmd temp
-    call fugitive#ReloadStatus()
-    return 'redraw|echo ' . string(':!' . git . ' ' . args)
+function! s:OpenExec(cmd, mods, args, ...) abort
+  let dir = a:0 ? s:Dir(a:1) : s:Dir()
+  let temp = tempname()
+  let columns = get(g:, 'fugitive_columns', 80)
+  if columns <= 0
+    let env = ''
+  elseif s:winshell()
+    let env = 'set COLUMNS=' . columns . '& '
+  else
+    let env = 'env COLUMNS=' . columns . ' '
   endif
+  silent! execute '!' . escape(env . s:UserCommand(dir, ['--no-pager'] + a:args), '!#%') .
+        \ (&shell =~# 'csh' ? ' >& ' . temp : ' > ' . temp . ' 2>&1')
+  redraw!
+  let temp = s:Resolve(temp)
+  let first = join(readfile(temp, '', 2), "\n")
+  if first =~# '\<\([[:upper:][:digit:]_-]\+(\d\+)\).*\1'
+    let filetype = 'man'
+  else
+    let filetype = 'git'
+  endif
+  let s:temp_files[s:cpath(temp)] = { 'dir': dir, 'filetype': filetype, 'modifiable': first =~# '^diff ' }
+  if a:cmd ==# 'edit'
+    call s:BlurStatus()
+  endif
+  silent execute s:Mods(a:mods) . a:cmd temp
+  call fugitive#ReloadStatus(dir, 1)
+  return 'echo ' . string(':!' . s:UserCommand(dir, a:args))
+endfunction
 
-  let [file, pre] = s:OpenParse(a:args)
+function! s:Open(cmd, bang, mods, arg, args) abort
+  if a:bang
+    return s:OpenExec(a:cmd, a:mods, s:SplitExpand(a:arg, s:Tree()))
+  endif
+  exe s:DirCheck()
+
+  let mods = s:Mods(a:mods)
   try
+    let [file, pre] = s:OpenParse(a:args)
     let file = s:Generate(file)
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
   if file !~# '^\a\a\+:'
     let file = s:sub(file, '/$', '')
@@ -3183,46 +4023,42 @@ function! s:Open(cmd, bang, mods, arg, args) abort
   if a:cmd ==# 'edit'
     call s:BlurStatus()
   endif
-  return mods . ' ' . a:cmd . pre . ' ' . s:fnameescape(file)
+  return mods . a:cmd . pre . ' ' . s:fnameescape(file)
 endfunction
 
 function! s:ReadCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
-  let mods = a:mods ==# '<mods>' ? '' : a:mods
-  let after = a:line2
+  let mods = s:Mods(a:mods)
+  let after = a:count
   if a:count < 0
     let delete = 'silent 1,' . line('$') . 'delete_|'
     let after = line('$')
   elseif a:range == 2
-    let delete = 'silent ' . a:line1 . ',' . a:line2 . 'delete_|'
+    let delete = 'silent ' . a:line1 . ',' . a:count . 'delete_|'
   else
     let delete = ''
   endif
   if a:bang
-    try
-      let cdback = s:Cd(s:Tree())
-      let git = s:UserCommand()
-      let args = s:ShellExpand(a:arg)
-      silent execute mods after.'read!' escape(git . ' --no-pager ' . args, '!#%')
-    finally
-      execute cdback
-    endtry
+    let dir = s:Dir()
+    let args = s:SplitExpand(a:arg, s:Tree(dir))
+    silent execute mods . after . 'read!' escape(s:UserCommand(dir, ['--no-pager'] + args), '!#%')
     execute delete . 'diffupdate'
     call fugitive#ReloadStatus()
-    return 'redraw|echo '.string(':!'.git.' '.args)
+    return 'redraw|echo '.string(':!'.s:UserCommand(dir, args))
   endif
-  let [file, pre] = s:OpenParse(a:args)
+  exe s:DirCheck()
   try
+    let [file, pre] = s:OpenParse(a:args)
     let file = s:Generate(file)
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
   if file =~# '^fugitive:' && after is# 0
-    return 'exe ' .string(mods . ' ' . fugitive#FileReadCmd(file, 0, pre)) . '|diffupdate'
+    return 'exe ' .string(mods . fugitive#FileReadCmd(file, 0, pre)) . '|diffupdate'
   endif
   if foldlevel(after)
     exe after . 'foldopen!'
   endif
-  return mods . ' ' . after . 'read' . pre . ' ' . s:fnameescape(file) . '|' . delete . 'diffupdate' . (a:count < 0 ? '|' . line('.') : '')
+  return mods . after . 'read' . pre . ' ' . s:fnameescape(file) . '|' . delete . 'diffupdate' . (a:count < 0 ? '|' . line('.') : '')
 endfunction
 
 function! s:ReadComplete(A,L,P) abort
@@ -3238,7 +4074,7 @@ call s:command("-bar -bang -nargs=*           -complete=customlist,fugitive#Comp
 call s:command("-bar -bang -nargs=*           -complete=customlist,s:ReadComplete Gpedit   execute s:Open('pedit', <bang>0, '<mods>', <q-args>, [<f-args>])")
 call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:ReadComplete Gsplit   execute s:Open((<count> > 0 ? <count> : '').(<count> ? 'split' : 'edit'), <bang>0, '<mods>', <q-args>, [<f-args>])")
 call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:ReadComplete Gvsplit  execute s:Open((<count> > 0 ? <count> : '').(<count> ? 'vsplit' : 'edit!'), <bang>0, '<mods>', <q-args>, [<f-args>])")
-call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:ReadComplete" . (has('patch-7.4.542') ? ' -addr=tabs' : '') . " Gtabedit execute s:Open((<count> >= 0 ? <count> : '').'tabedit', <bang>0, '<mods>', <q-args>, [<f-args>])")
+call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:ReadComplete -addr=tabs Gtabedit execute s:Open((<count> >= 0 ? <count> : '').'tabedit', <bang>0, '<mods>', <q-args>, [<f-args>])")
 call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:ReadComplete Gread", "Read")
 
 " Section: :Gwrite, :Gwq
@@ -3248,6 +4084,7 @@ call s:command("-bar -bang -nargs=* -complete=customlist,fugitive#CompleteObject
 call s:command("-bar -bang -nargs=* -complete=customlist,fugitive#CompleteObject Gwq", "Wq")
 
 function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
+  exe s:DirCheck()
   if exists('b:fugitive_commit_arguments')
     return 'write|bdelete'
   elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != ''
@@ -3260,13 +4097,15 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
     silent write
     setlocal buftype=nowrite
     if matchstr(getline(2),'index [[:xdigit:]]\+\.\.\zs[[:xdigit:]]\{7\}') ==# fugitive#RevParse(':0:'.filename)[0:6]
-      let err = s:TreeChomp('apply', '--cached', '--reverse', '--', expand('%:p'))
+      let [message, exec_error] = s:ChompError(['apply', '--cached', '--reverse', '--', expand('%:p')])
     else
-      let err = s:TreeChomp('apply', '--cached', '--', expand('%:p'))
+      let [message, exec_error] = s:ChompError(['apply', '--cached', '--', expand('%:p')])
     endif
-    if err !=# ''
-      let v:errmsg = split(err,"\n")[0]
-      return 'echoerr v:errmsg'
+    if exec_error
+      echohl ErrorMsg
+      echo message
+      echohl NONE
+      return ''
     elseif a:bang
       return 'bdelete'
     else
@@ -3275,14 +4114,18 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
   endif
   let mytab = tabpagenr()
   let mybufnr = bufnr('')
-  let file = len(a:args) ? s:Generate(s:Expand(join(a:args, ' '))) : fugitive#Real(@%)
+  try
+    let file = len(a:args) ? s:Generate(s:Expand(join(a:args, ' '))) : fugitive#Real(@%)
+  catch /^fugitive:/
+    return 'echoerr ' . string(v:exception)
+  endtry
   if empty(file)
     return 'echoerr '.string('fugitive: cannot determine file path')
   endif
   if file =~# '^fugitive:'
     return 'write' . (a:bang ? '! ' : ' ') . s:fnameescape(file)
   endif
-  let always_permitted = s:cpath(fugitive#Real(@%), file) && s:DirCommitFile(@%)[1] =~# '^0\=$'
+  let always_permitted = s:cpath(fugitive#Real(@%), file) && empty(s:DirCommitFile(@%)[1])
   if !always_permitted && !a:bang && (len(s:TreeChomp('diff', '--name-status', 'HEAD', '--', file)) || len(s:TreeChomp('ls-files', '--others', '--', file)))
     let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
     return 'echoerr v:errmsg'
@@ -3296,7 +4139,7 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
 
   if treebufnr > 0 && treebufnr != bufnr('')
     let temp = tempname()
-    silent execute '%write '.temp
+    silent execute 'keepalt %write '.temp
     for tab in [mytab] + range(1,tabpagenr('$'))
       for winnr in range(1,tabpagewinnr(tab,'$'))
         if tabpagebuflist(tab)[winnr-1] == treebufnr
@@ -3312,6 +4155,7 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
             silent execute '1,'.last.'delete_'
             silent write!
             silent execute lnum
+            diffupdate
             let did = 1
           finally
             if exists('restorewinnr')
@@ -3319,6 +4163,7 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
             endif
             execute 'tabnext '.mytab
           endtry
+          break
         endif
       endfor
     endfor
@@ -3330,11 +4175,11 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
   endif
 
   if a:bang
-    let error = s:TreeChomp('add', '--force', '--', file)
+    let [error, exec_error] = s:ChompError(['add', '--force', '--', file])
   else
-    let error = s:TreeChomp('add', '--', file)
+    let [error, exec_error] = s:ChompError(['add', '--', file])
   endif
-  if v:shell_error
+  if exec_error
     let v:errmsg = 'fugitive: '.error
     return 'echoerr v:errmsg'
   endif
@@ -3354,7 +4199,7 @@ function! s:WriteCommand(line1, line2, range, count, bang, mods, reg, arg, args)
 
   unlet! restorewinnr
   let zero = s:Generate(':0:'.file)
-  silent execute 'doautocmd BufWritePost' s:fnameescape(zero)
+  silent execute 'doautocmd' s:nomodeline 'BufWritePost' s:fnameescape(zero)
   for tab in range(1,tabpagenr('$'))
     for winnr in range(1,tabpagewinnr(tab,'$'))
       let bufnr = tabpagebuflist(tab)[winnr-1]
@@ -3402,41 +4247,76 @@ endfunction
 
 augroup fugitive_commit
   autocmd!
-  autocmd VimLeavePre,BufDelete COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
+  autocmd VimLeavePre,BufDelete COMMIT_EDITMSG execute substitute(s:FinishCommit(), '\C^echoerr \(''[^'']*''\)*', 'redraw|echohl ErrorMsg|echo \1|echohl NONE', '')
 augroup END
 
 " Section: :Gpush, :Gfetch
 
-call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gpush  execute s:Dispatch('<bang>', 'push '.<q-args>)")
-call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gfetch execute s:Dispatch('<bang>', 'fetch '.<q-args>)")
+function! s:PushComplete(A, L, P) abort
+  return s:CompleteSub('push', a:A, a:L, a:P, function('s:CompleteRemote'))
+endfunction
 
-function! s:Dispatch(bang, args)
+function! s:FetchComplete(A, L, P) abort
+  return s:CompleteSub('fetch', a:A, a:L, a:P, function('s:CompleteRemote'))
+endfunction
+
+function! s:AskPassArgs(dir) abort
+  if (len($DISPLAY) || len($TERM_PROGRAM) || has('gui_running')) && fugitive#GitVersion(1, 8) &&
+        \ empty($GIT_ASKPASS) && empty($SSH_ASKPASS) && empty(fugitive#Config('core.askPass', a:dir))
+    if s:executable(s:ExecPath() . '/git-gui--askpass')
+      return ['-c', 'core.askPass=' . s:ExecPath() . '/git-gui--askpass']
+    elseif s:executable('ssh-askpass')
+      return ['-c', 'core.askPass=ssh-askpass']
+    endif
+  endif
+  return []
+endfunction
+
+function! s:Dispatch(bang, cmd, args) abort
+  let dir = s:Dir()
   let [mp, efm, cc] = [&l:mp, &l:efm, get(b:, 'current_compiler', '')]
   try
-    let cdback = s:Cd(s:Tree())
     let b:current_compiler = 'git'
     let &l:errorformat = s:common_efm
-    let &l:makeprg = substitute(s:UserCommand() . ' ' . a:args, '\s\+$', '', '')
+    let &l:makeprg = s:UserCommand(dir, s:AskPassArgs(dir) + [a:cmd] + a:args)
     if exists(':Make') == 2
       Make
+      return ''
     else
+      if !has('patch-8.1.0334') && has('terminal') && &autowrite
+        let autowrite_was_set = 1
+        set noautowrite
+        silent! wall
+      endif
       silent noautocmd make!
       redraw!
       return 'call fugitive#Cwindow()|call fugitive#ReloadStatus()'
     endif
-    return ''
   finally
     let [&l:mp, &l:efm, b:current_compiler] = [mp, efm, cc]
     if empty(cc) | unlet! b:current_compiler | endif
-    execute cdback
+    if exists('autowrite_was_set')
+      set autowrite
+    endif
   endtry
 endfunction
 
+function! s:PushSubcommand(line1, line2, range, bang, mods, args) abort
+  return s:Dispatch(a:bang ? '!' : '', 'push', a:args)
+endfunction
+
+function! s:FetchSubcommand(line1, line2, range, bang, mods, args) abort
+  return s:Dispatch(a:bang ? '!' : '', 'fetch', a:args)
+endfunction
+
+call s:command("-nargs=? -bang -complete=customlist,s:PushComplete Gpush", "push")
+call s:command("-nargs=? -bang -complete=customlist,s:FetchComplete Gfetch", "fetch")
+
 " Section: :Gdiff
 
-call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Gdiff :execute s:Diff('',<bang>0,<f-args>)")
-call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Gvdiff :execute s:Diff('keepalt vert ',<bang>0,<f-args>)")
-call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Gsdiff :execute s:Diff('keepalt ',<bang>0,<f-args>)")
+call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Gdiffsplit  :execute s:Diff(1, <bang>0, '<mods>', <f-args>)")
+call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Gvdiffsplit :execute s:Diff(0, <bang>0, 'vertical <mods>', <f-args>)")
+call s:command("-bang -bar -nargs=* -complete=customlist,fugitive#CompleteObject Ghdiffsplit :execute s:Diff(0, <bang>0, '<mods>', <f-args>)")
 
 augroup fugitive_diff
   autocmd!
@@ -3463,13 +4343,13 @@ endfunction
 function! s:diff_modifier(count) abort
   let fdc = matchstr(&diffopt, 'foldcolumn:\zs\d\+')
   if &diffopt =~# 'horizontal' && &diffopt !~# 'vertical'
-    return 'keepalt '
+    return ''
   elseif &diffopt =~# 'vertical'
-    return 'keepalt vert '
+    return 'vertical '
   elseif winwidth(0) <= a:count * ((&tw ? &tw : 80) + (empty(fdc) ? 2 : fdc))
-    return 'keepalt '
+    return ''
   else
-    return 'keepalt vert '
+    return 'vertical '
   endif
 endfunction
 
@@ -3550,85 +4430,124 @@ function! s:CompareAge(mine, theirs) abort
   return my_time < their_time ? -1 : my_time != their_time
 endfunction
 
-function! s:Diff(vert,keepfocus,...) abort
+function! s:IsConflicted() abort
+  return len(@%) && !empty(s:ChompDefault('', 'ls-files', '--unmerged', '--', expand('%:p')))
+endfunction
+
+function! s:Diff(autodir, keepfocus, mods, ...) abort
+  if exists(':DiffGitCached') && !a:0
+    return s:Mods(a:mods) . 'DiffGitCached'
+  endif
+  exe s:DirCheck()
   let args = copy(a:000)
   let post = ''
   if get(args, 0) =~# '^+'
     let post = remove(args, 0)[1:-1]
   endif
-  let vert = empty(a:vert) ? s:diff_modifier(2) : a:vert
   let commit = s:DirCommitFile(@%)[1]
-  let back = exists('*win_getid') ? 'call win_gotoid(' . win_getid() . ')' : 'wincmd p'
-  if exists(':DiffGitCached')
-    return 'DiffGitCached'
-  elseif (empty(args) || args[0] ==# ':') && commit =~# '^[0-1]\=$' && !empty(s:TreeChomp('ls-files', '--unmerged', '--', expand('%:p')))
-    if v:shell_error
-      return 'echoerr ' . string("fugitive: error determining merge status of the current buffer")
-    endif
-    let vert = empty(a:vert) ? s:diff_modifier(3) : a:vert
-    let nr = bufnr('')
-    execute 'leftabove '.vert.'split' s:fnameescape(s:Generate(s:Relative(':2:')))
-    execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
-    let nr2 = bufnr('')
-    call s:diffthis()
-    exe back
-    execute 'rightbelow '.vert.'split' s:fnameescape(s:Generate(s:Relative(':3:')))
-    execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
-    let nr3 = bufnr('')
-    call s:diffthis()
-    exe back
-    call s:diffthis()
-    execute 'nnoremap <buffer> <silent> d2o :diffget '.nr2.'<Bar>diffupdate<CR>'
-    execute 'nnoremap <buffer> <silent> d3o :diffget '.nr3.'<Bar>diffupdate<CR>'
-    return post
-  elseif len(args)
-    let arg = join(args, ' ')
-    if arg ==# ''
-      return post
-    elseif arg ==# '/'
-      let file = s:Relative()
-    elseif arg ==# ':'
-      let file = s:Relative(':0:')
-    elseif arg =~# '^:/.'
-      try
-        let file = fugitive#RevParse(arg).s:Relative(':')
-      catch /^fugitive:/
-        return 'echoerr v:errmsg'
-      endtry
-    else
-      let file = s:Expand(arg)
-    endif
-    if file !~# ':' && file !~# '^/' && s:TreeChomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
-      let file = file.s:Relative(':')
-    endif
+  if a:mods =~# '\<tab\>'
+    let mods = substitute(a:mods, '\<tab\>', '', 'g')
+    tab split
   else
-    let file = empty(commit) ? s:Relative(':0:') : s:Relative()
+    let mods = 'keepalt ' . a:mods
+  endif
+  let back = exists('*win_getid') ? 'call win_gotoid(' . win_getid() . ')' : 'wincmd p'
+  if (empty(args) || args[0] ==# ':') && a:keepfocus
+    if empty(commit) && s:IsConflicted()
+      let parents = [s:Relative(':2:'), s:Relative(':3:')]
+    elseif empty(commit)
+      let parents = [s:Relative(':0:')]
+    elseif commit =~# '^\d\=$'
+      let parents = [s:Relative('HEAD:')]
+    elseif commit =~# '^\x\x\+$'
+      let parents = s:LinesError(['rev-parse', commit . '^@'])[0]
+      call map(parents, 's:Relative(v:val . ":")')
+    endif
   endif
   try
-    let spec = s:Generate(file)
-    let restore = s:diff_restore()
-    if exists('+cursorbind')
-      setlocal cursorbind
+    if exists('parents') && len(parents) > 1
+      let mods = (a:autodir ? s:diff_modifier(len(parents) + 1) : '') . s:Mods(mods, 'leftabove')
+      let nr = bufnr('')
+      execute mods 'split' s:fnameescape(s:Generate(parents[0]))
+      call s:Map('n', 'dp', ':diffput '.nr.'<Bar>diffupdate<CR>', '<silent>')
+      let nr2 = bufnr('')
+      call s:diffthis()
+      exe back
+      call s:Map('n', 'd2o', ':diffget '.nr2.'<Bar>diffupdate<CR>', '<silent>')
+      let mods = substitute(mods, '\Cleftabove\|rightbelow\|aboveleft\|belowright', '\=submatch(0) =~# "f" ? "rightbelow" : "leftabove"', '')
+      for i in range(len(parents)-1, 1, -1)
+        execute mods 'split' s:fnameescape(s:Generate(parents[i]))
+        call s:Map('n', 'dp', ':diffput '.nr.'<Bar>diffupdate<CR>', '<silent>')
+        let nrx = bufnr('')
+        call s:diffthis()
+        exe back
+        call s:Map('n', 'd' . (i + 2) . 'o', ':diffget '.nrx.'<Bar>diffupdate<CR>', '<silent>')
+      endfor
+      call s:diffthis()
+      if len(parents) > 1
+        wincmd =
+      endif
+      return post
+    elseif len(args)
+      let arg = join(args, ' ')
+      if arg ==# ''
+        return post
+      elseif arg ==# '/'
+        let file = s:Relative()
+      elseif arg ==# ':'
+        let file = s:Relative(':0:')
+      elseif arg =~# '^:\d$'
+        let file = s:Relative(arg . ':')
+      else
+        try
+          let file = arg =~# '^:/.' ? fugitive#RevParse(arg) . s:Relative(':') : s:Expand(arg)
+        catch /^fugitive:/
+          return 'echoerr ' . string(v:exception)
+        endtry
+      endif
+    elseif exists('parents') && len(parents)
+      let file = parents[-1]
+    elseif len(commit)
+      let file = s:Relative()
+    elseif s:IsConflicted()
+      let file = s:Relative(':1:')
+      let post = 'echohl WarningMsg|echo "Use :Gdiffsplit! for 3 way diff"|echohl NONE|' . post
+    else
+      let file = s:Relative(':0:')
     endif
+    let spec = s:Generate(file)
+    if spec =~# '^fugitive:' && empty(s:DirCommitFile(spec)[2])
+      let spec = FugitiveVimPath(spec . s:Relative('/'))
+    endif
+    let restore = s:diff_restore()
     let w:fugitive_diff_restore = restore
     if s:CompareAge(commit, s:DirCommitFile(spec)[1]) < 0
-      execute 'rightbelow '.vert.'diffsplit '.s:fnameescape(spec)
+      let mods = s:Mods(mods, 'rightbelow')
     else
-      execute 'leftabove '.vert.'diffsplit '.s:fnameescape(spec)
+      let mods = s:Mods(mods, 'leftabove')
     endif
+    let mods = (a:autodir ? s:diff_modifier(2) : '') . mods
+    if &diffopt =~# 'vertical'
+      let diffopt = &diffopt
+      set diffopt-=vertical
+    endif
+    execute mods 'diffsplit' s:fnameescape(spec)
     let &l:readonly = &l:readonly
     redraw
     let w:fugitive_diff_restore = restore
     let winnr = winnr()
     if getwinvar('#', '&diff')
-      exe back
-      if !a:keepfocus
-        call feedkeys(winnr."\<C-W>w", 'n')
+      if a:keepfocus
+        exe back
       endif
     endif
     return post
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
+  finally
+    if exists('diffopt')
+      let &diffopt = diffopt
+    endif
   endtry
 endfunction
 
@@ -3654,8 +4573,8 @@ function! s:Move(force, rename, destination) abort
   if isdirectory(@%)
     setlocal noswapfile
   endif
-  let message = call('s:TreeChomp', ['mv'] + (a:force ? ['-f'] : []) + ['--', expand('%:p'), destination])
-  if v:shell_error
+  let [message, exec_error] = s:ChompError(['mv'] + (a:force ? ['-f'] : []) + ['--', expand('%:p'), destination])
+  if exec_error
     let v:errmsg = 'fugitive: '.message
     return 'echoerr v:errmsg'
   endif
@@ -3695,8 +4614,8 @@ function! s:Remove(after, force) abort
   if a:force
     let cmd += ['--force']
   endif
-  let message = call('s:TreeChomp', cmd + ['--', expand('%:p')])
-  if v:shell_error
+  let [message, exec_error] = s:ChompError(cmd + ['--', expand('%:p')])
+  if exec_error
     let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
     return 'echoerr '.string(v:errmsg)
   else
@@ -3726,18 +4645,6 @@ function! s:Keywordprg() abort
   endif
 endfunction
 
-augroup fugitive_blame
-  autocmd!
-  autocmd FileType fugitiveblame setlocal nomodeline | if len(s:Dir()) | let &l:keywordprg = s:Keywordprg() | endif
-  autocmd Syntax fugitiveblame call s:BlameSyntax()
-  autocmd User Fugitive
-        \ if get(b:, 'fugitive_type') =~# '^\%(file\|blob\|blame\)$' || filereadable(@%) |
-        \   exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:BlameCommand(<line1>,<line2>,+'<range>',<count>,<bang>0,'<mods>',<q-reg>,<q-args>,[<f-args>])" |
-        \ endif
-  autocmd ColorScheme,GUIEnter * call s:RehighlightBlame()
-  autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
-augroup END
-
 function! s:linechars(pattern) abort
   let chars = strlen(s:gsub(matchstr(getline('.'), a:pattern), '.', '.'))
   if exists('*synconcealed') && &conceallevel > 1
@@ -3748,60 +4655,216 @@ function! s:linechars(pattern) abort
   return chars
 endfunction
 
-function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
-  if exists('b:fugitive_blamed_bufnr')
+function! s:BlameBufnr(...) abort
+  let state = s:TempState(bufname(a:0 ? a:1 : ''))
+  if get(state, 'filetype', '') ==# 'fugitiveblame'
+    return get(state, 'bufnr', -1)
+  else
+    return -1
+  endif
+endfunction
+
+function! s:BlameCommitFileLnum(...) abort
+  let line = a:0 ? a:1 : getline('.')
+  let state = a:0 ? a:2 : s:TempState()
+  let commit = matchstr(line, '^\^\=\zs\x\+')
+  if commit =~# '^0\+$'
+    let commit = ''
+  elseif line !~# '^\^' && has_key(state, 'blame_reverse_end')
+    let commit = get(s:LinesError('rev-list', '--ancestry-path', '--reverse', commit . '..' . state.blame_reverse_end)[0], 0, '')
+  endif
+  let lnum = +matchstr(line, ' \zs\d\+\ze \%((\| *\d\+)\)')
+  let path = matchstr(line, '^\^\=\x* \+\%(\d\+ \+\d\+ \+\)\=\zs.\{-\}\ze\s\+\%(\%( \d\+ \)\@<!([^()]*\w \d\+)\|\d\+ \)')
+  if empty(path) && lnum
+    let path = get(state, 'blame_file', '')
+  endif
+  return [commit, path, lnum]
+endfunction
+
+function! s:BlameLeave() abort
+  let bufwinnr = bufwinnr(s:BlameBufnr())
+  if bufwinnr > 0
+    let bufnr = bufnr('')
+    exe bufwinnr . 'wincmd w'
+    return bufnr . 'bdelete'
+  endif
+  return ''
+endfunction
+
+function! s:BlameQuit() abort
+  let cmd = s:BlameLeave()
+  if empty(cmd)
     return 'bdelete'
+  elseif len(s:DirCommitFile(@%)[1])
+    return cmd . '|Gedit'
+  else
+    return cmd
+  endif
+endfunction
+
+function! s:BlameComplete(A, L, P) abort
+  return s:CompleteSub('blame', a:A, a:L, a:P)
+endfunction
+
+function! s:BlameSubcommand(line1, count, range, bang, mods, args) abort
+  exe s:DirCheck()
+  let flags = copy(a:args)
+  let i = 0
+  let raw = 0
+  let commits = []
+  let files = []
+  let ranges = []
+  if a:line1 > 0 && a:count > 0 && a:range != 1
+    call extend(ranges, ['-L', a:line1 . ',' . a:count])
+  endif
+  while i < len(flags)
+    let match = matchlist(flags[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
+    if len(match) && len(match[2])
+      call insert(flags, match[1])
+      let flags[i+1] = '-' . match[2]
+      continue
+    endif
+    let arg = flags[i]
+    if arg =~# '^-p$\|^--\%(help\|porcelain\|line-porcelain\|incremental\)$'
+      let raw = 1
+    elseif arg ==# '--contents' && i + 1 < len(flags)
+      call extend(commits, remove(flags, i, i+1))
+      continue
+    elseif arg ==# '-L' && i + 1 < len(flags)
+      call extend(ranges, remove(flags, i, i+1))
+      continue
+    elseif arg =~# '^--contents='
+      call add(commits, remove(flags, i))
+      continue
+    elseif arg =~# '^-L.'
+      call add(ranges, remove(flags, i))
+      continue
+    elseif arg =~# '^-[GLS]$\|^--\%(date\|encoding\|contents\)$'
+      let i += 1
+      if i == len(flags)
+        echohl ErrorMsg
+        echo s:ChompError(['blame', arg])[0]
+        echohl NONE
+        return ''
+      endif
+    elseif arg ==# '--'
+      if i + 1 < len(flags)
+        call extend(files, remove(flags, i + 1, -1))
+      endif
+      call remove(flags, i)
+      break
+    elseif arg !~# '^-' && (s:HasOpt(flags, '--not') || arg !~# '^\^')
+      if index(flags, '--') >= 0
+        call add(commits, remove(flags, i))
+        continue
+      endif
+      if arg =~# '\.\.' && arg !~# '^\.\.\=\%(/\|$\)' && empty(commits)
+        call add(commits, remove(flags, i))
+        continue
+      endif
+      try
+        let dcf = s:DirCommitFile(fugitive#Find(arg))
+        if len(dcf[1]) && empty(dcf[2])
+          call add(commits, remove(flags, i))
+          continue
+        endif
+      catch /^fugitive:/
+      endtry
+      call add(files, remove(flags, i))
+      continue
+    endif
+    let i += 1
+  endwhile
+  if empty(ranges + commits + files) && has_key(s:TempState(), 'blame_flags')
+    return substitute(s:BlameLeave(), '^$', 'bdelete', '')
+  endif
+  let file = substitute(get(files, 0, get(s:TempState(), 'blame_file', s:Relative('./'))), '^\.\%(/\|$\)', '', '')
+  if empty(commits) && len(files) > 1
+    call add(commits, remove(files, 1))
   endif
   try
-    if empty(s:Relative('/'))
-      call s:throw('file or blob required')
+    let cmd = ['--no-pager', '-c', 'blame.coloring=none', '-c', 'blame.blankBoundary=false', 'blame', '--show-number']
+    call extend(cmd, filter(copy(flags), 'v:val !~# "\\v^%(-b|--%(no-)=color-.*|--progress)$"'))
+    if a:count > 0 && empty(ranges)
+      let cmd += ['-L', (a:line1 ? a:line1 : line('.')) . ',' . (a:line1 ? a:line1 : line('.'))]
     endif
-    if filter(copy(a:args),'v:val !~# "^\\%(--abbrev=\\d*\\|--relative-date\\|--first-parent\\|--root\\|--show-name\\|-\\=\\%([ltfnsew]\\|[MC]\\d*\\)\\+\\)$"') != []
-      call s:throw('unsupported option')
-    endif
-    call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
-    let cmd = ['--no-pager', 'blame', '--show-number']
-    if a:count
-      let cmd += ['-L', a:line1 . ',' . a:line1]
-    endif
-    let cmd += a:args
-    if s:DirCommitFile(@%)[1] =~# '\D\|..'
-      let cmd += [s:DirCommitFile(@%)[1]]
-    else
+    call extend(cmd, ranges)
+    if len(commits)
+      let cmd += commits
+    elseif empty(files) && len(matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$'))
+      let cmd += [matchstr(s:DirCommitFile(@%)[1], '^\x\x\+$')]
+    elseif empty(files) && !s:HasOpt(flags, '--reverse')
       let cmd += ['--contents', '-']
     endif
-    let cmd += ['--', expand('%:p')]
-    let basecmd = escape(fugitive#Prepare(cmd), '!#%')
-    try
-      let cdback = s:Cd(s:Tree())
-      let error = tempname()
-      let temp = error.'.fugitiveblame'
-      if &shell =~# 'csh'
-        silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
-      else
-        silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
-      endif
-    finally
-      execute cdback
-    endtry
+    let basecmd = escape(fugitive#Prepare(cmd) . ' -- ' . s:shellesc(len(files) ? files : file), '!#%')
+    let tempname = tempname()
+    let error = tempname . '.err'
+    let temp = tempname . (raw ? '' : '.fugitiveblame')
+    if &shell =~# 'csh'
+      silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
+    else
+      silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
+    endif
+    redraw
     try
       if v:shell_error
-        call s:throw(join(readfile(error),"\n"))
+        let lines = readfile(error)
+        if empty(lines)
+          let lines = readfile(temp)
+        endif
+        for i in range(len(lines))
+          if lines[i] =~# '^error: \|^fatal: '
+            echohl ErrorMsg
+            echon lines[i]
+            echohl NONE
+            break
+          else
+            echon lines[i]
+          endif
+          if i != len(lines) - 1
+            echon "\n"
+          endif
+        endfor
+        return ''
       endif
-      if a:count
-        let edit = substitute(a:mods, '^<mods>$', '', '') . get(['edit', 'split', 'pedit'], a:line2 - a:line1, ' split')
-        return s:BlameCommit(edit, get(readfile(temp), 0, ''))
+      let temp_state = {'dir': s:Dir(), 'filetype': (raw ? '' : 'fugitiveblame'), 'blame_flags': flags, 'blame_file': file, 'modifiable': 0}
+      if s:HasOpt(flags, '--reverse')
+        let temp_state.blame_reverse_end = matchstr(get(commits, 0, ''), '\.\.\zs.*')
+      endif
+      if (a:line1 == 0 || a:range == 1) && a:count > 0
+        let edit = s:Mods(a:mods) . get(['edit', 'split', 'pedit', 'vsplit', 'tabedit'], a:count - (a:line1 ? a:line1 : 1), 'split')
+        return s:BlameCommit(edit, get(readfile(temp), 0, ''), temp_state)
       else
+        let temp = s:Resolve(temp)
+        let s:temp_files[s:cpath(temp)] = temp_state
+        if len(ranges + commits + files) || raw
+          let mods = s:Mods(a:mods)
+          if a:count != 0
+            exe 'silent keepalt' mods 'split' s:fnameescape(temp)
+          elseif !&modified || a:bang || &bufhidden ==# 'hide' || (empty(&bufhidden) && &hidden)
+            exe 'silent' mods 'edit' . (a:bang ? '! ' : ' ') . s:fnameescape(temp)
+          else
+            return mods . 'edit ' . s:fnameescape(temp)
+          endif
+          return ''
+        endif
+        if a:mods =~# '\<tab\>'
+          silent tabedit %
+        endif
+        let mods = substitute(a:mods, '\<tab\>', '', 'g')
         for winnr in range(winnr('$'),1,-1)
-          call setwinvar(winnr, '&scrollbind', 0)
-          if exists('+cursorbind')
+          if getwinvar(winnr, '&scrollbind')
+            call setwinvar(winnr, '&scrollbind', 0)
+          endif
+          if exists('+cursorbind') && getwinvar(winnr, '&cursorbind')
             call setwinvar(winnr, '&cursorbind', 0)
           endif
-          if getbufvar(winbufnr(winnr), 'fugitive_blamed_bufnr')
+          if s:BlameBufnr(winbufnr(winnr)) > 0
             execute winbufnr(winnr).'bdelete'
           endif
         endfor
         let bufnr = bufnr('')
+        let temp_state.bufnr = bufnr
         let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
         if exists('+cursorbind')
           let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&cursorbind",0)'
@@ -3818,77 +4881,63 @@ function! s:BlameCommand(line1, line2, range, count, bang, mods, reg, arg, args)
         endif
         let top = line('w0') + &scrolloff
         let current = line('.')
-        let temp = s:Resolve(temp)
-        let s:temp_files[s:cpath(temp)] = { 'dir': s:Dir(), 'filetype': 'fugitiveblame', 'args': cmd, 'bufnr': bufnr }
-        exe 'keepalt leftabove vsplit '.temp
-        let b:fugitive_blamed_bufnr = bufnr
-        let b:fugitive_type = 'blame'
+        exe 'silent keepalt' (a:bang ? s:Mods(mods) . 'split' : s:Mods(mods, 'leftabove') . 'vsplit') s:fnameescape(temp)
         let w:fugitive_leave = restore
-        let b:fugitive_blame_arguments = join(a:args,' ')
         execute top
         normal! zt
         execute current
         if exists('+cursorbind')
           setlocal cursorbind
         endif
-        setlocal nomodified nomodifiable nonumber scrollbind nowrap foldcolumn=0 nofoldenable winfixwidth filetype=fugitiveblame buftype=nowrite
-        if exists('+concealcursor')
-          setlocal concealcursor=nc conceallevel=2
-        endif
+        setlocal nonumber scrollbind nowrap foldcolumn=0 nofoldenable winfixwidth
         if exists('+relativenumber')
           setlocal norelativenumber
         endif
         execute "vertical resize ".(s:linechars('.\{-\}\ze\s\+\d\+)')+1)
-        let nowait = v:version >= 704 ? '<nowait>' : ''
-        nnoremap <buffer> <silent> <F1> :help fugitive-:Gblame<CR>
-        nnoremap <buffer> <silent> g?   :help fugitive-:Gblame<CR>
-        nnoremap <buffer> <silent> q    :exe substitute(bufwinnr(b:fugitive_blamed_bufnr).' wincmd w<Bar>'.bufnr('').'bdelete','^-1','','')<CR>
-        exe 'nnoremap <buffer> <silent>' nowait "gq :exe substitute(bufwinnr(b:fugitive_blamed_bufnr).' wincmd w<Bar>'.bufnr('').'bdelete<Bar>if expand(''%:p'') =~# ''^fugitive:[\\/][\\/]''<Bar>Gedit<Bar>endif','^-1','','')<CR>"
-        nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>BlameCommit("exe 'norm q'<Bar>edit")<CR>
-        nnoremap <buffer> <silent> -    :<C-U>exe <SID>BlameJump('')<CR>
-        nnoremap <buffer> <silent> P    :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
-        nnoremap <buffer> <silent> ~    :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
-        nnoremap <buffer> <silent> i    :<C-U>exe <SID>BlameCommit("exe 'norm q'<Bar>edit")<CR>
-        nnoremap <buffer> <silent> o    :<C-U>exe <SID>BlameCommit((&splitbelow ? "botright" : "topleft")." split")<CR>
-        nnoremap <buffer> <silent> O    :<C-U>exe <SID>BlameCommit("tabedit")<CR>
-        nnoremap <buffer> <silent> p    :<C-U>exe <SID>Open((&splitbelow ? "botright" : "topleft").' pedit', 0, '', matchstr(getline('.'), '\x\+'), [matchstr(getline('.'), '\x\+')])<CR>
-        nnoremap <buffer> <silent> A    :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze [0-9:/+-][0-9:/+ -]* \d\+)')+1+v:count)<CR>
-        nnoremap <buffer> <silent> C    :<C-u>exe "vertical resize ".(<SID>linechars('^\S\+')+1+v:count)<CR>
-        nnoremap <buffer> <silent> D    :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze\d\ze\s\+\d\+)')+1-v:count)<CR>
+        call s:Map('n', 'A', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze [0-9:/+-][0-9:/+ -]* \\d\\+)')+1+v:count)<CR>", '<silent>')
+        call s:Map('n', 'C', ":<C-u>exe 'vertical resize '.(<SID>linechars('^\\S\\+')+1+v:count)<CR>", '<silent>')
+        call s:Map('n', 'D', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze\\d\\ze\\s\\+\\d\\+)')+1-v:count)<CR>", '<silent>')
         redraw
         syncbind
       endif
     endtry
     return ''
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
 endfunction
 
 function! s:BlameCommit(cmd, ...) abort
   let line = a:0 ? a:1 : getline('.')
-  if line =~# '^0\{4,40\} '
-    return 'echoerr ' . string('Not Committed Yet')
+  let state = a:0 ? a:2 : s:TempState()
+  let sigil = has_key(state, 'blame_reverse_end') ? '-' : '+'
+  let mods = (s:BlameBufnr() < 0 ? '' : &splitbelow ? "botright " : "topleft ")
+  let [commit, path, lnum] = s:BlameCommitFileLnum(line, state)
+  if empty(commit) && len(path) && has_key(state, 'blame_reverse_end')
+    let path = (len(state.blame_reverse_end) ? state.blame_reverse_end . ':' : ':(top)') . path
+    return s:Open(mods . a:cmd, 0, '', '+' . lnum . ' ' . s:fnameescape(path), ['+' . lnum, path])
   endif
-  let cmd = s:Open(a:cmd, 0, '', matchstr(line, '\x\+'), [matchstr(line, '\x\+')])
+  if commit =~# '^0*$'
+    return 'echoerr ' . string('fugitive: no commit')
+  endif
+  if line =~# '^\^' && !has_key(state, 'blame_reverse_end')
+    let path = commit . ':' . path
+    return s:Open(mods . a:cmd, 0, '', '+' . lnum . ' ' . s:fnameescape(path), ['+' . lnum, path])
+  endif
+  let cmd = s:Open(mods . a:cmd, 0, '', commit, [commit])
   if cmd =~# '^echoerr'
     return cmd
   endif
-  let lnum = matchstr(line, ' \zs\d\+\ze\s\+[([:digit:]]')
-  let path = matchstr(line, '^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
-  if path ==# ''
-    let path = fugitive#Path(a:0 ? @% : bufname(b:fugitive_blamed_bufnr), '')
-  endif
   execute cmd
-  if a:cmd ==# 'pedit'
+  if a:cmd ==# 'pedit' || empty(path)
     return ''
   endif
   if search('^diff .* b/\M'.escape(path,'\').'$','W')
     call search('^+++')
     let head = line('.')
     while search('^@@ \|^diff ') && getline('.') =~# '^@@ '
-      let top = +matchstr(getline('.'),' +\zs\d\+')
-      let len = +matchstr(getline('.'),' +\d\+,\zs\d\+')
+      let top = +matchstr(getline('.'),' ' . sigil .'\zs\d\+')
+      let len = +matchstr(getline('.'),' ' . sigil . '\d\+,\zs\d\+')
       if lnum >= top && lnum <= top + len
         let offset = lnum - top
         if &scrolloff
@@ -3900,7 +4949,7 @@ function! s:BlameCommit(cmd, ...) abort
         endif
         while offset > 0 && line('.') < line('$')
           +
-          if getline('.') =~# '^[ +]'
+          if getline('.') =~# '^[ ' . sigil . ']'
             let offset -= 1
           endif
         endwhile
@@ -3913,32 +4962,51 @@ function! s:BlameCommit(cmd, ...) abort
   return ''
 endfunction
 
-function! s:BlameJump(suffix) abort
-  let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
+function! s:BlameJump(suffix, ...) abort
   let suffix = a:suffix
-  if commit =~# '^0\+$'
+  let [commit, path, lnum] = s:BlameCommitFileLnum()
+  if empty(path)
+    return 'echoerr ' . string('fugitive: could not determine filename for blame')
+  endif
+  if commit =~# '^0*$'
     let commit = 'HEAD'
     let suffix = ''
   endif
-  let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
-  let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
-  if path ==# ''
-    let path = fugitive#Path(bufname(b:fugitive_blamed_bufnr), '')
-  endif
-  let args = b:fugitive_blame_arguments
   let offset = line('.') - line('w0')
-  let bufnr = bufnr('%')
-  let winnr = bufwinnr(b:fugitive_blamed_bufnr)
-  if winnr > 0
-    exe winnr.'wincmd w'
+  let flags = get(s:TempState(), 'blame_flags', [])
+  if a:0 && a:1
+    if s:HasOpt(flags, '--reverse')
+      call remove(flags, '--reverse')
+    else
+      call add(flags, '--reverse')
+    endif
   endif
-  execute 'Gedit' s:fnameescape(commit . suffix . ':' . path)
-  execute lnum
-  if winnr > 0
-    exe bufnr.'bdelete'
+  let blame_bufnr = s:BlameBufnr()
+  if blame_bufnr > 0
+    let bufnr = bufnr('')
+    let winnr = bufwinnr(blame_bufnr)
+    if winnr > 0
+      exe winnr.'wincmd w'
+    endif
+    execute 'Gedit' s:fnameescape(commit . suffix . ':' . path)
+    execute lnum
+    if winnr > 0
+      exe bufnr.'bdelete'
+    endif
   endif
   if exists(':Gblame')
-    execute 'Gblame '.args
+    let my_bufnr = bufnr('')
+    if blame_bufnr < 0
+      let blame_args = flags + [commit . suffix, '--', path]
+      let result = s:BlameSubcommand(0, 0, 0, 0, '', blame_args)
+    else
+      let blame_args = flags
+      let result = s:BlameSubcommand(-1, -1, 0, 0, '', blame_args)
+    endif
+    if bufnr('') == my_bufnr
+      return result
+    endif
+    execute result
     execute lnum
     let delta = line('.') - line('w0') - offset
     if delta > 0
@@ -3946,32 +5014,41 @@ function! s:BlameJump(suffix) abort
     elseif delta < 0
       execute 'normal! '.(-delta)."\<C-Y>"
     endif
-    syncbind
+    keepjumps syncbind
+    redraw
+    echo ':Gblame' s:fnameescape(blame_args)
   endif
   return ''
 endfunction
 
 let s:hash_colors = {}
 
-function! s:BlameSyntax() abort
-  let b:current_syntax = 'fugitiveblame'
+function! fugitive#BlameSyntax() abort
   let conceal = has('conceal') ? ' conceal' : ''
-  let arg = exists('b:fugitive_blame_arguments') ? b:fugitive_blame_arguments : ''
-  syn match FugitiveblameBoundary "^\^"
-  syn match FugitiveblameBlank                      "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
-  syn match FugitiveblameHash       "\%(^\^\=\)\@<=\<\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
-  syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=\<0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
-  syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
-  syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
-  exec 'syn match FugitiveblameLineNumber         " *\d\+)\@=" contained containedin=FugitiveblameAnnotation'.conceal
-  exec 'syn match FugitiveblameOriginalFile       " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite'.(arg =~# 'f' ? '' : conceal)
-  exec 'syn match FugitiveblameOriginalLineNumber " *\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite'.(arg =~# 'n' ? '' : conceal)
-  exec 'syn match FugitiveblameOriginalLineNumber " *\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite'.(arg =~# 'n' ? '' : conceal)
+  let config = fugitive#Config()
+  let flags = get(s:TempState(), 'blame_flags', [])
+  syn match FugitiveblameBlank                      "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
+  syn match FugitiveblameHash       "\%(^\^\=\)\@<=\<\x\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
+  syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=\<0\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
+  if get(get(config, 'blame.blankboundary', ['x']), 0, 'x') =~# '^$\|^true$' || s:HasOpt(flags, '-b')
+    syn match FugitiveblameBoundaryIgnore "^\^\x\{7,\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameScoreDebug,FugitiveblameOriginalLineNumber,FugitiveblameOriginalFile skipwhite
+  else
+    syn match FugitiveblameBoundary "^\^"
+  endif
+  syn match FugitiveblameScoreDebug        " *\d\+\s\+\d\+\s\@=" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile contained skipwhite
+  syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%(\s\d\+\)\@<=)" contained keepend oneline
+  syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%(\s\+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
+  exec 'syn match FugitiveblameLineNumber         "\s*\d\+)\@=" contained containedin=FugitiveblameAnnotation' conceal
+  exec 'syn match FugitiveblameOriginalFile       "\s\%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite' (s:HasOpt(flags, '--show-name', '-f') ? '' : conceal)
+  exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite' (s:HasOpt(flags, '--show-number', '-n') ? '' : conceal)
+  exec 'syn match FugitiveblameOriginalLineNumber "\s*\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite' (s:HasOpt(flags, '--show-number', '-n') ? '' : conceal)
   syn match FugitiveblameShort              " \d\+)" contained contains=FugitiveblameLineNumber
   syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
   hi def link FugitiveblameBoundary           Keyword
   hi def link FugitiveblameHash               Identifier
+  hi def link FugitiveblameBoundaryIgnore     Ignore
   hi def link FugitiveblameUncommitted        Ignore
+  hi def link FugitiveblameScoreDebug         Debug
   hi def link FugitiveblameTime               PreProc
   hi def link FugitiveblameLineNumber         Number
   hi def link FugitiveblameOriginalFile       String
@@ -3979,6 +5056,9 @@ function! s:BlameSyntax() abort
   hi def link FugitiveblameShort              FugitiveblameDelimiter
   hi def link FugitiveblameDelimiter          Delimiter
   hi def link FugitiveblameNotCommittedYet    Comment
+  if !get(g:, 'fugitive_dynamic_colors', 1) && !s:HasOpt(flags, '--color-lines') || s:HasOpt(flags, '--no-color-lines')
+    return
+  endif
   let seen = {}
   for lnum in range(1, line('$'))
     let hash = matchstr(getline(lnum), '^\^\=\zs\x\{6\}')
@@ -3999,10 +5079,10 @@ function! s:BlameSyntax() abort
     endif
     exe 'syn match FugitiveblameHash'.hash.'       "\%(^\^\=\)\@<='.hash.'\x\{1,34\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite'
   endfor
-  call s:RehighlightBlame()
+  call s:BlameRehighlight()
 endfunction
 
-function! s:RehighlightBlame() abort
+function! s:BlameRehighlight() abort
   for [hash, cterm] in items(s:hash_colors)
     if !empty(cterm) || has('gui_running') || has('termguicolors') && &termguicolors
       exe 'hi FugitiveblameHash'.hash.' guifg=#'.hash.get(s:hash_colors, hash, '')
@@ -4012,17 +5092,64 @@ function! s:RehighlightBlame() abort
   endfor
 endfunction
 
+function! s:BlameFileType() abort
+  setlocal nomodeline
+  setlocal foldmethod=manual
+  if len(s:Dir())
+    let &l:keywordprg = s:Keywordprg()
+  endif
+  let b:undo_ftplugin = 'setl keywordprg= foldmethod<'
+  if exists('+concealcursor')
+    setlocal concealcursor=nc conceallevel=2
+    let b:undo_ftplugin .= ' concealcursor< conceallevel<'
+  endif
+  if &modifiable
+    return ''
+  endif
+  call s:Map('n', '<F1>', ':help fugitive-:Gblame<CR>', '<silent>')
+  call s:Map('n', 'g?',   ':help fugitive-:Gblame<CR>', '<silent>')
+  if mapcheck('q', 'n') =~# '^$\|bdelete'
+    call s:Map('n', 'q',  ':exe <SID>BlameQuit()<Bar>echohl WarningMsg<Bar>echo ":Gblame q is deprecated in favor of gq"<Bar>echohl NONE<CR>', '<silent>')
+  endif
+  call s:Map('n', 'gq',   ':exe <SID>BlameQuit()<CR>', '<silent>')
+  call s:Map('n', '<2-LeftMouse>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
+  call s:Map('n', '<CR>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
+  call s:Map('n', '-',    ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>')
+  call s:Map('n', 'P',    ':<C-U>exe <SID>BlameJump("^".v:count1)<CR>', '<silent>')
+  call s:Map('n', '~',    ':<C-U>exe <SID>BlameJump("~".v:count1)<CR>', '<silent>')
+  call s:Map('n', 'i',    ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
+  call s:Map('n', 'o',    ':<C-U>exe <SID>BlameCommit("split")<CR>', '<silent>')
+  call s:Map('n', 'O',    ':<C-U>exe <SID>BlameCommit("tabedit")<CR>', '<silent>')
+  call s:Map('n', 'p',    ':<C-U>exe <SID>BlameCommit("pedit")<CR>', '<silent>')
+endfunction
+
+augroup fugitive_blame
+  autocmd!
+  autocmd FileType fugitiveblame call s:BlameFileType()
+  autocmd ColorScheme,GUIEnter * call s:BlameRehighlight()
+  autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
+augroup END
+
+call s:command('-buffer -bang -range=-1 -nargs=? -complete=customlist,s:BlameComplete Gblame', 'blame')
+
 " Section: :Gbrowse
 
-call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse", "Browse")
+call s:command("-bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse", "Browse")
 
 let s:redirects = {}
 
 function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args) abort
   let dir = s:Dir()
+  exe s:DirCheck(dir)
   try
     let validremote = '\.\|\.\=/.*\|[[:alnum:]_-]\+\%(://.\{-\}\)\='
-    if len(a:args)
+    if a:args ==# ['-']
+      if a:count >= 0
+        return 'echoerr ' . string('fugitive: ''-'' no longer required to get persistent URL if range given')
+      else
+        return 'echoerr ' . string('fugitive: use :0Gbrowse instead of :Gbrowse -')
+      endif
+    elseif len(a:args)
       let remote = matchstr(join(a:args, ' '),'@\zs\%('.validremote.'\)$')
       let rev = substitute(join(a:args, ' '),'@\%('.validremote.'\)$','','')
     else
@@ -4037,7 +5164,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
     else
       let expanded = s:Expand(rev)
     endif
-    let cdir = fugitive#CommonDir(s:Dir())
+    let cdir = FugitiveVimPath(fugitive#CommonDir(s:Dir()))
     for subdir in ['tags/', 'heads/', 'remotes/']
       if expanded !~# '^[./]' && filereadable(cdir . '/refs/' . subdir . expanded)
         let expanded = '.git/refs/' . subdir . expanded
@@ -4075,7 +5202,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
     endif
     if path =~# '^\.git/.*HEAD$' && filereadable(dir . '/' . path[5:-1])
       let body = readfile(dir . '/' . path[5:-1])[0]
-      if body =~# '^\x\{40\}$'
+      if body =~# '^\x\{40,\}$'
         let commit = body
         let type = 'commit'
         let path = ''
@@ -4122,23 +5249,23 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
     let line1 = a:count > 0 ? a:line1 : 0
     let line2 = a:count > 0 ? a:count : 0
     if empty(commit) && path !~# '^\.git/'
-      if a:line1 && !a:count && !empty(merge)
+      if a:count < 0 && !empty(merge)
         let commit = merge
       else
         let commit = ''
         if len(merge)
           let owner = s:Owner(@%)
-          let commit = s:TreeChomp('merge-base', 'refs/remotes/' . remote . '/' . merge, empty(owner) ? 'HEAD' : owner, '--')
-          if v:shell_error
+          let [commit, exec_error] = s:ChompError(['merge-base', 'refs/remotes/' . remote . '/' . merge, empty(owner) ? 'HEAD' : owner, '--'])
+          if exec_error
             let commit = ''
           endif
-          if a:count && empty(a:args) && commit =~# '^\x\{40\}$'
+          if a:count > 0 && empty(a:args) && commit =~# '^\x\{40,\}$'
             let blame_list = tempname()
             call writefile([commit, ''], blame_list, 'b')
             let blame_in = tempname()
             silent exe '%write' blame_in
-            let blame = split(s:TreeChomp('blame', '--contents', blame_in, '-L', a:line1.','.a:count, '-S', blame_list, '-s', '--show-number', './' . path), "\n")
-            if !v:shell_error
+            let [blame, exec_error] = s:LinesError(['-c', 'blame.coloring=none', 'blame', '--contents', blame_in, '-L', a:line1.','.a:count, '-S', blame_list, '-s', '--show-number', './' . path])
+            if !exec_error
               let blame_regex = '^\^\x\+\s\+\zs\d\+\ze\s'
               if get(blame, 0) =~# blame_regex && get(blame, -1) =~# blame_regex
                 let line1 = +matchstr(blame[0], blame_regex)
@@ -4151,7 +5278,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
         endif
       endif
       if empty(commit)
-        let commit = readfile(dir . '/HEAD', '', 1)[0]
+        let commit = readfile(fugitive#Find('.git/HEAD', dir), '', 1)[0]
       endif
       let i = 0
       while commit =~# '^ref: ' && i < 10
@@ -4199,7 +5326,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
     endfor
 
     if empty(url)
-      call s:throw("No Gbrowse handler found for '".raw."'")
+      call s:throw("No Gbrowse handler installed for '".raw."'")
     endif
 
     let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
@@ -4221,7 +5348,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args
       endif
     endif
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
 endfunction
 
@@ -4232,11 +5359,11 @@ function! fugitive#MapCfile(...) abort
   exe 'cnoremap <buffer> <expr> <Plug><cfile>' (a:0 ? a:1 : 'fugitive#Cfile()')
   let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|sil! exe "cunmap <buffer> <Plug><cfile>"'
   if !exists('g:fugitive_no_maps')
-    call s:map('n', 'gf',          '<SID>:find <Plug><cfile><CR>', '<silent><unique>', 1)
-    call s:map('n', '<C-W>f',     '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>', 1)
-    call s:map('n', '<C-W><C-F>', '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>', 1)
-    call s:map('n', '<C-W>gf',  '<SID>:tabfind <Plug><cfile><CR>', '<silent><unique>', 1)
-    call s:map('c', '<C-R><C-F>', '<Plug><cfile>', '<silent><unique>', 1)
+    call s:Map('n', 'gf',          '<SID>:find <Plug><cfile><CR>', '<silent><unique>', 1)
+    call s:Map('n', '<C-W>f',     '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>', 1)
+    call s:Map('n', '<C-W><C-F>', '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>', 1)
+    call s:Map('n', '<C-W>gf',  '<SID>:tabfind <Plug><cfile><CR>', '<silent><unique>', 1)
+    call s:Map('c', '<C-R><C-F>', '<Plug><cfile>', '<silent><unique>', 1)
   endif
 endfunction
 
@@ -4245,12 +5372,19 @@ function! s:ContainingCommit() abort
   return empty(commit) ? 'HEAD' : commit
 endfunction
 
-function! s:SquashArgument() abort
+function! s:SquashArgument(...) abort
   if &filetype == 'fugitive'
-    return matchstr(getline('.'), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze ')
+    let commit = matchstr(getline('.'), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze ')
+  elseif has_key(s:temp_files, s:cpath(expand('%:p')))
+    let commit = matchstr(getline('.'), '\<\x\{4,\}\>')
   else
-    return s:Owner(@%)
+    let commit = s:Owner(@%)
   endif
+  return len(commit) && a:0 ? printf(a:1, commit) : commit
+endfunction
+
+function! s:RebaseArgument() abort
+  return s:SquashArgument(' %s^')
 endfunction
 
 function! s:NavigateUp(count) abort
@@ -4273,61 +5407,146 @@ function! s:NavigateUp(count) abort
   return rev
 endfunction
 
+function! s:MapMotion(lhs, rhs) abort
+  call s:Map('n', a:lhs, ":<C-U>" . a:rhs . "<CR>", "<silent>")
+  call s:Map('o', a:lhs, ":<C-U>" . a:rhs . "<CR>", "<silent>")
+  call s:Map('x', a:lhs, ":<C-U>exe 'normal! gv'<Bar>" . a:rhs . "<CR>", "<silent>")
+endfunction
+
 function! fugitive#MapJumps(...) abort
-  if get(b:, 'fugitive_type', '') ==# 'blob'
-    nnoremap <buffer> <silent> <CR>    :<C-U>.Gblame<CR>
-  else
-    nnoremap <buffer> <silent> <CR>    :<C-U>exe <SID>GF("edit")<CR>
-  endif
   if !&modifiable
-    let nowait = v:version >= 704 ? '<nowait>' : ''
     if get(b:, 'fugitive_type', '') ==# 'blob'
-      nnoremap <buffer> <silent> o     :<C-U>.,.+1Gblame<CR>
-      nnoremap <buffer> <silent> S     :<C-U>echoerr 'Use gO'<CR>
-      nnoremap <buffer> <silent> gO    :<C-U>vertical .,.+1Gblame<CR>
-      nnoremap <buffer> <silent> O     :<C-U>tab .,.+1Gblame<CR>
-      nnoremap <buffer> <silent> p     :<C-U>.,.+2Gblame<CR>
+      let blame_map = 'Gblame<C-R>=v:count ? " --reverse" : ""<CR><CR>'
+      call s:Map('n', '<2-LeftMouse>', ':<C-U>0,1' . blame_map, '<silent>')
+      call s:Map('n', '<CR>', ':<C-U>0,1' . blame_map, '<silent>')
+      call s:Map('n', 'o',    ':<C-U>0,2' . blame_map, '<silent>')
+      call s:Map('n', 'p',    ':<C-U>0,3' . blame_map, '<silent>')
+      call s:Map('n', 'gO',   ':<C-U>0,4' . blame_map, '<silent>')
+      call s:Map('n', 'O',    ':<C-U>0,5' . blame_map, '<silent>')
+
+      call s:Map('n', 'D',  ":<C-U>call <SID>DiffClose()<Bar>Gdiffsplit!<Bar>redraw<Bar>echohl WarningMsg<Bar> echo ':Gstatus D is deprecated in favor of dd'<Bar>echohl NONE<CR>", '<silent>')
+      call s:Map('n', 'dd', ":<C-U>call <SID>DiffClose()<Bar>Gdiffsplit!<CR>", '<silent>')
+      call s:Map('n', 'dh', ":<C-U>call <SID>DiffClose()<Bar>Ghdiffsplit!<CR>", '<silent>')
+      call s:Map('n', 'ds', ":<C-U>call <SID>DiffClose()<Bar>Ghdiffsplit!<CR>", '<silent>')
+      call s:Map('n', 'dv', ":<C-U>call <SID>DiffClose()<Bar>Gvdiffsplit!<CR>", '<silent>')
+      call s:Map('n', 'd?', ":<C-U>help fugitive_d<CR>", '<silent>')
+
     else
-      nnoremap <buffer> <silent> o     :<C-U>exe <SID>GF("split")<CR>
-      nnoremap <buffer> <silent> S     :<C-U>echoerr 'Use gO'<CR>
-      nnoremap <buffer> <silent> gO    :<C-U>exe <SID>GF("vsplit")<CR>
-      nnoremap <buffer> <silent> O     :<C-U>exe <SID>GF("tabedit")<CR>
-      nnoremap <buffer> <silent> p     :<C-U>exe <SID>GF("pedit")<CR>
+      call s:Map('n', '<2-LeftMouse>', ':<C-U>exe <SID>GF("edit")<CR>', '<silent>')
+      call s:Map('n', '<CR>', ':<C-U>exe <SID>GF("edit")<CR>', '<silent>')
+      call s:Map('n', 'o',    ':<C-U>exe <SID>GF("split")<CR>', '<silent>')
+      call s:Map('n', 'gO',   ':<C-U>exe <SID>GF("vsplit")<CR>', '<silent>')
+      call s:Map('n', 'O',    ':<C-U>exe <SID>GF("tabedit")<CR>', '<silent>')
+      call s:Map('n', 'p',    ':<C-U>exe <SID>GF("pedit")<CR>', '<silent>')
+
+      if !exists('g:fugitive_no_maps')
+        if exists(':CtrlP') && get(g:, 'ctrl_p_map') =~? '^<c-p>$'
+          nnoremap <buffer> <silent> <C-P> :<C-U>execute line('.') == 1 ? 'CtrlP ' . fnameescape(<SID>Tree()) : <SID>PreviousItem(v:count1)<CR>
+        else
+          nnoremap <buffer> <silent> <C-P> :<C-U>execute <SID>PreviousItem(v:count1)<CR>
+        endif
+        nnoremap <buffer> <silent> <C-N> :<C-U>execute <SID>NextItem(v:count1)<CR>
+      endif
+      call s:MapMotion('(', 'exe <SID>PreviousItem(v:count1)')
+      call s:MapMotion(')', 'exe <SID>NextItem(v:count1)')
+      call s:MapMotion('K', 'exe <SID>PreviousHunk(v:count1)')
+      call s:MapMotion('J', 'exe <SID>NextHunk(v:count1)')
+      call s:MapMotion('[c', 'exe <SID>PreviousHunk(v:count1)')
+      call s:MapMotion(']c', 'exe <SID>NextHunk(v:count1)')
+      call s:MapMotion('[/', 'exe <SID>PreviousFile(v:count1)')
+      call s:MapMotion(']/', 'exe <SID>NextFile(v:count1)')
+      call s:MapMotion('[m', 'exe <SID>PreviousFile(v:count1)')
+      call s:MapMotion(']m', 'exe <SID>NextFile(v:count1)')
+      call s:MapMotion('[[', 'exe <SID>PreviousSection(v:count1)')
+      call s:MapMotion(']]', 'exe <SID>NextSection(v:count1)')
+      call s:MapMotion('[]', 'exe <SID>PreviousSectionEnd(v:count1)')
+      call s:MapMotion('][', 'exe <SID>NextSectionEnd(v:count1)')
+      call s:Map('nxo', '*', '<SID>PatchSearchExpr(0)', '<expr>')
+      call s:Map('nxo', '#', '<SID>PatchSearchExpr(1)', '<expr>')
     endif
-    exe "nnoremap <buffer> <silent>" nowait  "-     :<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>NavigateUp(v:count1))<Bar> if getline(1) =~# '^tree \x\{40\}$' && empty(getline(2))<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>"
-    nnoremap <buffer> <silent> P     :<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit().'^'.v:count1.<SID>Relative(':'))<CR>
-    nnoremap <buffer> <silent> ~     :<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit().'~'.v:count1.<SID>Relative(':'))<CR>
-    nnoremap <buffer> <silent> C     :<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>
-    nnoremap <buffer> <silent> co    :<C-U>echoerr 'Use CTRL-W C'<CR>
-    nnoremap <buffer> <silent> <C-W>C :<C-U>exe 'Gsplit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>
-    nnoremap <buffer> <silent> cp    :<C-U>echoerr 'Use gC'<CR>
-    nnoremap <buffer> <silent> gC    :<C-U>exe 'Gpedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>
-    nnoremap <buffer> <silent> gc    :<C-U>exe 'Gpedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>
+    call s:Map('n', 'S',    ':<C-U>echoerr "Use gO"<CR>', '<silent>')
+    call s:Map('n', 'dq', ":<C-U>call <SID>DiffClose()<CR>", '<silent>')
+    call s:Map('n', '-', ":<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>NavigateUp(v:count1))<Bar> if getline(1) =~# '^tree \x\{40,\}$' && empty(getline(2))<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>", '<silent>')
+    call s:Map('n', 'P',     ":<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit().'^'.v:count1.<SID>Relative(':'))<CR>", '<silent>')
+    call s:Map('n', '~',     ":<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit().'~'.v:count1.<SID>Relative(':'))<CR>", '<silent>')
+    call s:Map('n', 'C',     ":<C-U>exe 'Gedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>", '<silent>')
+    call s:Map('n', 'cp',    ":<C-U>echoerr 'Use gC'<CR>", '<silent>')
+    call s:Map('n', 'gC',    ":<C-U>exe 'Gpedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>", '<silent>')
+    call s:Map('n', 'gc',    ":<C-U>exe 'Gpedit ' . <SID>fnameescape(<SID>ContainingCommit())<CR>", '<silent>')
+    call s:Map('n', 'gi',    ":<C-U>exe 'Gsplit' (v:count ? '.gitignore' : '.git/info/exclude')<CR>", '<silent>')
+    call s:Map('x', 'gi',    ":<C-U>exe 'Gsplit' (v:count ? '.gitignore' : '.git/info/exclude')<CR>", '<silent>')
+
+    nnoremap <buffer>       c<Space> :Gcommit<Space>
+    nnoremap <buffer>          c<CR> :Gcommit<CR>
+    nnoremap <buffer>      cv<Space> :Gcommit -v<Space>
+    nnoremap <buffer>         cv<CR> :Gcommit -v<CR>
     nnoremap <buffer> <silent> ca    :<C-U>Gcommit --amend<CR>
     nnoremap <buffer> <silent> cc    :<C-U>Gcommit<CR>
     nnoremap <buffer> <silent> ce    :<C-U>Gcommit --amend --no-edit<CR>
     nnoremap <buffer> <silent> cw    :<C-U>Gcommit --amend --only<CR>
     nnoremap <buffer> <silent> cva   :<C-U>Gcommit -v --amend<CR>
     nnoremap <buffer> <silent> cvc   :<C-U>Gcommit -v<CR>
+    nnoremap <buffer> <silent> cRa   :<C-U>Gcommit --reset-author --amend<CR>
+    nnoremap <buffer> <silent> cRe   :<C-U>Gcommit --reset-author --amend --no-edit<CR>
+    nnoremap <buffer> <silent> cRw   :<C-U>Gcommit --reset-author --amend --only<CR>
     nnoremap <buffer>          cf    :<C-U>Gcommit --fixup=<C-R>=<SID>SquashArgument()<CR>
+    nnoremap <buffer>          cF    :<C-U><Bar>Grebase --autosquash<C-R>=<SID>RebaseArgument()<CR><Home>Gcommit --fixup=<C-R>=<SID>SquashArgument()<CR>
     nnoremap <buffer>          cs    :<C-U>Gcommit --squash=<C-R>=<SID>SquashArgument()<CR>
+    nnoremap <buffer>          cS    :<C-U><Bar>Grebase --autosquash<C-R>=<SID>RebaseArgument()<CR><Home>Gcommit --squash=<C-R>=<SID>SquashArgument()<CR>
     nnoremap <buffer>          cA    :<C-U>Gcommit --edit --squash=<C-R>=<SID>SquashArgument()<CR>
-    nnoremap <buffer> <silent> ri    :<C-U>Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR><CR>
-    nnoremap <buffer> <silent> rf    :<C-U>Grebase --autosquash<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR><CR>
+    nnoremap <buffer> <silent> c?    :<C-U>help fugitive_c<CR>
+
+    nnoremap <buffer>      cr<Space> :Grevert<Space>
+    nnoremap <buffer>         cr<CR> :Grevert<CR>
+    nnoremap <buffer> <silent> crc   :<C-U>Grevert <C-R>=<SID>SquashArgument()<CR><CR>
+    nnoremap <buffer> <silent> crn   :<C-U>Grevert --no-commit <C-R>=<SID>SquashArgument()<CR><CR>
+    nnoremap <buffer> <silent> cr?   :help fugitive_cr<CR>
+
+    nnoremap <buffer>      cm<Space> :Gmerge<Space>
+    nnoremap <buffer>         cm<CR> :Gmerge<CR>
+    nnoremap <buffer> <silent> cm?   :help fugitive_cm<CR>
+
+    nnoremap <buffer>      cz<Space> :G stash<Space>
+    nnoremap <buffer>         cz<CR> :G stash<CR>
+    nnoremap <buffer> <silent> cza   :<C-U>exe <SID>EchoExec(['stash', 'apply', '--quiet', '--index', 'stash@{' . v:count . '}'])<CR>
+    nnoremap <buffer> <silent> czA   :<C-U>exe <SID>EchoExec(['stash', 'apply', '--quiet', 'stash@{' . v:count . '}'])<CR>
+    nnoremap <buffer> <silent> czp   :<C-U>exe <SID>EchoExec(['stash', 'pop', '--quiet', '--index', 'stash@{' . v:count . '}'])<CR>
+    nnoremap <buffer> <silent> czP   :<C-U>exe <SID>EchoExec(['stash', 'pop', '--quiet', 'stash@{' . v:count . '}'])<CR>
+    nnoremap <buffer> <silent> czv   :<C-U>exe 'Gedit' fugitive#RevParse('stash@{' . v:count . '}')<CR>
+    nnoremap <buffer> <silent> czw   :<C-U>exe <SID>EchoExec(['stash', '--keep-index'] + (v:count > 1 ? ['--all'] : v:count ? ['--include-untracked'] : []))<CR>
+    nnoremap <buffer> <silent> czz   :<C-U>exe <SID>EchoExec(['stash'] + (v:count > 1 ? ['--all'] : v:count ? ['--include-untracked'] : []))<CR>
+    nnoremap <buffer> <silent> cz?   :<C-U>help fugitive_cz<CR>
+
+    nnoremap <buffer>      co<Space> :G checkout<Space>
+    nnoremap <buffer>         co<CR> :G checkout<CR>
+    nnoremap <buffer>          coo   :exe <SID>EchoExec(['checkout'] + split(<SID>SquashArgument()) + ['--'])<CR>
+    nnoremap <buffer>          co?   :<C-U>help fugitive_co<CR>
+
+    nnoremap <buffer>      cb<Space> :G branch<Space>
+    nnoremap <buffer>         cb<CR> :G branch<CR>
+    nnoremap <buffer>         cb?    :<C-U>help fugitive_cb<CR>
+
+    nnoremap <buffer>       r<Space> :Grebase<Space>
+    nnoremap <buffer>          r<CR> :Grebase<CR>
+    nnoremap <buffer> <silent> ri    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><CR>
+    nnoremap <buffer> <silent> rf    :<C-U>Grebase --autosquash<C-R>=<SID>RebaseArgument()<CR><CR>
     nnoremap <buffer> <silent> ru    :<C-U>Grebase --interactive @{upstream}<CR>
     nnoremap <buffer> <silent> rp    :<C-U>Grebase --interactive @{push}<CR>
-    nnoremap <buffer> <silent> rw    :<C-U>exe 'Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR>'<Bar>s/^pick/reword/e<CR>
-    nnoremap <buffer> <silent> rm    :<C-U>exe 'Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR>'<Bar>s/^pick/edit/e<CR>
-    nnoremap <buffer> <silent> rd    :<C-U>exe 'Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR>'<Bar>s/^pick/drop/e<CR>
-    nnoremap <buffer> <silent> rk    :<C-U>exe 'Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR>'<Bar>s/^pick/drop/e<CR>
-    nnoremap <buffer> <silent> rx    :<C-U>exe 'Grebase --interactive<C-R>=substitute(<SID>SquashArgument(),'.\+',' &^','')<CR>'<Bar>s/^pick/drop/e<CR>
+    nnoremap <buffer> <silent> rw    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><Bar>s/^pick/reword/e<CR>
+    nnoremap <buffer> <silent> rm    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><Bar>s/^pick/edit/e<CR>
+    nnoremap <buffer> <silent> rd    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><Bar>s/^pick/drop/e<CR>
+    nnoremap <buffer> <silent> rk    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><Bar>s/^pick/drop/e<CR>
+    nnoremap <buffer> <silent> rx    :<C-U>Grebase --interactive<C-R>=<SID>RebaseArgument()<CR><Bar>s/^pick/drop/e<CR>
     nnoremap <buffer> <silent> rr    :<C-U>Grebase --continue<CR>
     nnoremap <buffer> <silent> rs    :<C-U>Grebase --skip<CR>
     nnoremap <buffer> <silent> re    :<C-U>Grebase --edit-todo<CR>
     nnoremap <buffer> <silent> ra    :<C-U>Grebase --abort<CR>
-    nnoremap <buffer>          .     :<C-U> <C-R>=<SID>fnameescape(fugitive#Real(@%))<CR><Home>
-    xnoremap <buffer>          .     :<C-U> <C-R>=<SID>fnameescape(fugitive#Real(@%))<CR><Home>
-    nnoremap <buffer> <silent> g?   :help fugitive-mappings<CR>
+    nnoremap <buffer> <silent> r?    :<C-U>help fugitive_r<CR>
+
+    call s:Map('n', '.',     ":<C-U> <C-R>=<SID>fnameescape(fugitive#Real(@%))<CR><Home>")
+    call s:Map('x', '.',     ":<C-U> <C-R>=<SID>fnameescape(fugitive#Real(@%))<CR><Home>")
+    call s:Map('n', 'g?',    ":<C-U>help fugitive-mappings<CR>", '<silent>')
+    call s:Map('n', '<F1>',  ":<C-U>help fugitive-mappings<CR>", '<silent>')
   endif
 endfunction
 
@@ -4336,16 +5555,16 @@ function! s:StatusCfile(...) abort
   let lead = s:cpath(tree, getcwd()) ? './' : tree . '/'
   let info = s:StageInfo()
   let line = getline('.')
-  if len(info.sigil) && len(info.section) && len(info.filename)
+  if len(info.sigil) && len(info.section) && len(info.paths)
     if info.section ==# 'Unstaged' && info.sigil !=# '-'
-      return [lead . info.filename, info.offset, 'normal!zv']
+      return [lead . info.relative[0], info.offset, 'normal!zv']
     elseif info.section ==# 'Staged' && info.sigil ==# '-'
-      return ['@:' . info.filename, info.offset, 'normal!zv']
+      return ['@:' . info.relative[0], info.offset, 'normal!zv']
     else
-      return [':0:' . info.filename, info.offset, 'normal!zv']
+      return [':0:' . info.relative[0], info.offset, 'normal!zv']
     endif
-  elseif len(info.filename)
-    return [lead . info.filename]
+  elseif len(info.paths)
+    return [lead . info.relative[0]]
   elseif len(info.commit)
     return [info.commit]
   elseif line =~# '^\%(Head\|Merge\|Rebase\|Upstream\|Pull\|Push\): '
@@ -4406,7 +5625,7 @@ function! s:cfile() abort
     let treebase = substitute(s:DirCommitFile(@%)[1], '^\d$', ':&', '') . ':' .
           \ s:Relative('') . (s:Relative('') =~# '^$\|/$' ? '' : '/')
 
-    if getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
+    if getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40,\}\t'
       return [treebase . s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')]
     elseif showtree
       return [treebase . s:sub(getline('.'),'/$','')]
@@ -4416,8 +5635,8 @@ function! s:cfile() abort
       let dcmds = []
 
       " Index
-      if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      if getline('.') =~# '^\d\{6\} \x\{40,\} \d\t'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
         return [file]
       endif
@@ -4425,12 +5644,12 @@ function! s:cfile() abort
       if getline('.') =~# '^ref: '
         let ref = strpart(getline('.'),5)
 
-      elseif getline('.') =~# '^commit \x\{40\}\>'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      elseif getline('.') =~# '^commit \x\{40,\}\>'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         return [ref]
 
-      elseif getline('.') =~# '^parent \x\{40\}\>'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      elseif getline('.') =~# '^parent \x\{40,\}\>'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         let line = line('.')
         let parent = 0
         while getline(line) =~# '^parent '
@@ -4439,22 +5658,22 @@ function! s:cfile() abort
         endwhile
         return [ref]
 
-      elseif getline('.') =~# '^tree \x\{40\}$'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      elseif getline('.') =~# '^tree \x\{40,\}$'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         if len(myhash) && fugitive#RevParse(myhash.':') ==# ref
           let ref = myhash.':'
         endif
         return [ref]
 
-      elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      elseif getline('.') =~# '^object \x\{40,\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         let type = matchstr(getline(line('.')+1),'type \zs.*')
 
       elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$'
         let ref = s:DirRev(@%)[1]
 
-      elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>'
-        let ref = matchstr(getline('.'),'\x\{40\}')
+      elseif getline('.') =~# '^\l\{3,8\} \x\{40,\}\>'
+        let ref = matchstr(getline('.'),'\x\{40,\}')
         echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
 
       elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
@@ -4485,23 +5704,23 @@ function! s:cfile() abort
 
         let dref = matchstr(diff, '\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
         let ref = matchstr(diff, '\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
-        let dcmd = 'Gdiff! +'.offset
+        let dcmd = 'Gdiffsplit! +'.offset
 
       elseif getline('.') =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
         let dref = matchstr(getline('.'),'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
         let ref = matchstr(getline('.'),'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
-        let dcmd = 'Gdiff!'
+        let dcmd = 'Gdiffsplit!'
 
       elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
         let line = getline(line('.')-1)
         let dref = matchstr(line,'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
         let ref = matchstr(line,'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
-        let dcmd = 'Gdiff!'
+        let dcmd = 'Gdiffsplit!'
 
-      elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
+      elseif line('$') == 1 && getline('.') =~ '^\x\{40,\}$'
         let ref = getline('.')
 
-      elseif expand('<cword>') =~# '^\x\{7,40\}\>'
+      elseif expand('<cword>') =~# '^\x\{7,\}\>'
         return [expand('<cword>')]
 
       else
@@ -4545,12 +5764,12 @@ function! s:GF(mode) abort
   try
     let results = &filetype ==# 'fugitive' ? s:StatusCfile() : &filetype ==# 'gitcommit' ? [s:MessageCfile()] : s:cfile()
   catch /^fugitive:/
-    return 'echoerr v:errmsg'
+    return 'echoerr ' . string(v:exception)
   endtry
   if len(results) > 1
     return 'G' . a:mode .
-          \ ' +' . escape(join(results[1:-1], '|'), '| ') . ' ' .
-          \ s:fnameescape(results[0])
+          \ ' +' . escape(results[1], ' ') . ' ' .
+          \ s:fnameescape(results[0]) . join(map(results[2:-1], '"|" . v:val'), '')
   elseif len(results) && len(results[0])
     return 'G' . a:mode . ' ' . s:fnameescape(results[0])
   else
@@ -4669,19 +5888,20 @@ function! fugitive#Init() abort
     endtry
   endif
   if !exists('g:fugitive_no_maps')
-    call s:map('c', '<C-R><C-G>', '<SID>fnameescape(fugitive#Object(@%))', '<expr>')
-    call s:map('n', 'y<C-G>', ':<C-U>call setreg(v:register, fugitive#Object(@%))<CR>', '<silent>')
+    call s:Map('c', '<C-R><C-G>', '<SID>fnameescape(fugitive#Object(@%))', '<expr>')
+    call s:Map('n', 'y<C-G>', ':<C-U>call setreg(v:register, fugitive#Object(@%))<CR>', '<silent>')
   endif
   if expand('%:p') =~# ':[\/][\/]'
     let &l:path = s:sub(&path, '^\.%(,|$)', '')
   endif
   let dir = s:Dir()
   if stridx(&tags, escape(dir, ', ')) == -1
-    if filereadable(dir.'/tags')
-      let &l:tags = escape(dir.'/tags', ', ').','.&tags
+    let actualdir = fugitive#Find('.git/', dir)
+    if filereadable(actualdir . 'tags')
+      let &l:tags = escape(actualdir . 'tags', ', ').','.&tags
     endif
-    if &filetype !=# '' && filereadable(dir.'/'.&filetype.'.tags')
-      let &l:tags = escape(dir.'/'.&filetype.'.tags', ', ').','.&tags
+    if &filetype !=# '' && filereadable(actualdir . &filetype . '.tags')
+      let &l:tags = escape(actualdir . &filetype . '.tags', ', ').','.&tags
     endif
   endif
   try
diff --git a/sources_non_forked/vim-fugitive/doc/fugitive.txt b/sources_non_forked/vim-fugitive/doc/fugitive.txt
index 16f20f15..d4750ddc 100644
--- a/sources_non_forked/vim-fugitive/doc/fugitive.txt
+++ b/sources_non_forked/vim-fugitive/doc/fugitive.txt
@@ -15,13 +15,21 @@ COMMANDS                                        *fugitive-commands*
 These commands are local to the buffers in which they work (generally, buffers
 that are part of Git repositories).
 
+                                        *fugitive-:G* *fugitive-:Gstatus*
+:G                      Bring up a summary window vaguely akin to git-status.
+:Gstatus                Press g? or see |fugitive-mappings| for usage.
+
                                                 *fugitive-:Git*
-:Git [args]             Run an arbitrary git command. Similar to :!git [args]
-                        but chdir to the repository tree first.
+:Git {args}             Run an arbitrary git command. Similar to :!git [args]
+:G {args}               but chdir to the repository tree first.  For some
+                        subcommands, a Fugitive command is called instead.
+                        Invoking :Git push will call :Gpush for example.
 
                                                 *fugitive-:Git!*
-:Git! [args]            Like |:Git|, but capture the output into a temp file,
-                        and edit that temp file.
+:Git! {args}            Like |:Git|, but capture the output into a temp file,
+:Git --no-pager {args}  and |:split| that temp file.  Use :0Git to
+:Git -P {args}          |:edit| the temp file instead.  A temp file is always
+                        used for diff and log commands.
 
                                                 *fugitive-:Gcd*
 :Gcd [directory]        |:cd| relative to the repository.
@@ -29,20 +37,16 @@ that are part of Git repositories).
                                                 *fugitive-:Glcd*
 :Glcd [directory]       |:lcd| relative to the repository.
 
-                                        *fugitive-:Gstatus* *fugitive-:G*
-:G                      Bring up a summary window vaguely akin to git-status.
-:Gstatus                Press g? or see |fugitive-mappings| for usage.
-
                                                 *fugitive-:Gcommit*
 :Gcommit [args]         A wrapper around git-commit.  Unless the arguments
                         given would skip the invocation of an editor (e.g.,
                         -m), a split window will be used to obtain a commit
                         message, or a new tab if -v is given.  Write and close
-                        that window (:wq or |:Gwrite|) to finish the commit.
-                        Unlike when running the actual git-commit command, it
-                        is possible (but unadvisable) to alter the index with
-                        commands like git-add and git-reset while a commit
-                        message is pending.
+                        the window (:wq) to finish the commit. To cancel, use
+                        an empty message.
+
+                                                *fugitive-:Grevert*
+:Grevert [args]         A wrapper around git-revert.  Similar to |:Gcommit|.
 
                                                 *fugitive-:Gmerge*
 :Gmerge [args]          Calls git-merge and loads errors and conflicted files
@@ -68,28 +72,25 @@ that are part of Git repositories).
                                                 *fugitive-:Gfetch*
 :Gfetch [args]          Like |:Gpush|, but for git-fetch.
 
-                                                *fugitive-:Ggrep*
+                                        *fugitive-:Ggrep* *fugitive-:Gcgrep*
 :Ggrep[!] [args]        |:grep|[!] with git-grep as 'grepprg'.
 
                                                 *fugitive-:Glgrep*
 :Glgrep[!] [args]       |:lgrep|[!] with git-grep as 'grepprg'.
 
-                                                *fugitive-:Glog*
-:Glog [args]            Load the commit history into the |quickfix| list.
-                        Additional git-log arguments can be given (for
-                        example, --reverse).  Provide "--" in the argument
-                        list to target all commits.  Otherwise, only commits
-                        changing the current file will be targeted.  This
-                        special casing is slated to be removed.
+                                        *fugitive-:Gclog* *fugitive-:Glog*
+:Gclog[!] [args]        Use git-log [args] to load the commit history into the
+:Glog[!] [args]         |quickfix| list.  Jump to the first commit unless [!]
+                        is given.
 
-:{range}Glog [args]     Use git-log -L to load previous revisions of the given
+:{range}Gclog[!] [args] Use git-log -L to load previous revisions of the given
                         range of the current file into the |quickfix| list.
                         The cursor is positioned on the first line of the
-                        first diff hunk for each commit.  Use :0Glog to target
-                        the entire file.
+                        first diff hunk for each commit.  Use :0Gclog to
+                        target the entire file.
 
                                                 *fugitive-:Gllog*
-:Gllog [args]           Like |:Glog|, but use the location list instead of the
+:Gllog [args]           Like |:Gclog|, but use the location list instead of the
                         |quickfix| list.
 
                                         *fugitive-:Gedit* *fugitive-:Ge*
@@ -109,8 +110,10 @@ that are part of Git repositories).
 
 :Gsplit! [args]                 *fugitive-:Gsplit!* *fugitive-:Gvsplit!*
 :Gvsplit! [args]                *fugitive-:Gtabedit!* *fugitive-:Gpedit!*
-:Gtabedit! [args]       Like |:Git!|, but open the resulting temp file in a
-:Gpedit! [args]         split, tab, or preview window.
+:Gtabedit! [args]       Capture the output of `git [args]` to a temp file and
+:Gpedit! [args]         open it in a split, tab, or preview window.  Use
+                        :0Gsplit! to suppress the split and open it in the
+                        current window.
 
                                                 *fugitive-:Gread*
 :Gread [object]         Empty the buffer and |:read| a |fugitive-object|.
@@ -136,7 +139,7 @@ that are part of Git repositories).
 
 :Gwrite {path}          You can give |:Gwrite| an explicit path of where in
                         the work tree to write.  You can also give a path like
-                        :0:foo.txt or even :0 to write to just that stage in
+                        :0:foo.txt or :0:% to write to just that stage in
                         the index.
 
                                                 *fugitive-:Gwq*
@@ -146,25 +149,31 @@ that are part of Git repositories).
 :Gwq! [path]            Like |:Gwrite|! followed by |:quit|! if the write
                         succeeded.
 
-                                                *fugitive-:Gdiff*
-:Gdiff [object]         Perform a |vimdiff| against the given file, or if a
+                                                *fugitive-:Gdiffsplit*
+:Gdiffsplit [object]    Perform a |vimdiff| against the given file, or if a
                         commit is given, the current file in that commit.
-                        With no argument, the version in the index is used
-                        (which means a three-way diff during a merge conflict,
-                        making it a git-mergetool alternative).  The newer of
-                        the two files is placed to the right or bottom,
-                        depending on 'diffopt', and the width of the window
-                        relative to 'textwidth'.  Use |do| and |dp| and write
-                        to the index file to simulate "git add --patch". For
-                        the three-way diff, there is also d2o and d3o pulling
-                        the hunk to the middle from the left or the right
-                        window, respectively.
+                        With no argument, the version in the index or work
+                        tree is used.  The newer of the two files is placed to
+                        the right or bottom, depending on 'diffopt' and the
+                        width of the window relative to 'textwidth'.  Use
+                        Vim's |do| and |dp| to stage and unstage changes.
 
-                                                *fugitive-:Gsdiff*
-:Gsdiff [object]        Like |:Gdiff|, but always split horizontally.
+                                                *fugitive-:Gdiffsplit!*
+:Gdiffsplit!            Diff against any and all direct ancestors, retaining
+                        focus on the current window.  During a merge conflict,
+                        this is a three-way diff against the "ours" and
+                        "theirs" ancestors.  Additional d2o and d3o maps are
+                        provided to to obtain the hunk from the "ours" or
+                        "theirs" ancestor, respectively.
 
-                                                *fugitive-:Gvdiff*
-:Gvdiff [object]        Like |:Gdiff|, but always split vertically.
+:Gdiffsplit! {object}   Like |:Gdiffsplit|, but retain focus on the current
+                        window.
+
+                                                *fugitive-:Gvdiffsplit*
+:Gvdiffsplit [object]   Like |:Gdiffsplit|, but always split vertically.
+
+                                *fugitive-:Ghdiffsplit* *fugitive-:Gsdiff*
+:Ghdiffsplit [object]   Like |:Gdiffsplit|, but always split horizontally.
 
                                                 *fugitive-:Gmove*
 :Gmove {destination}    Wrapper around git-mv that renames the buffer
@@ -184,26 +193,31 @@ that are part of Git repositories).
 :Gremove                Like :Gdelete, but keep the (now empty) buffer around.
 
                                                 *fugitive-:Gblame*
-:Gblame [flags]         Run git-blame on the file and open the results in a
-                        scroll bound vertical split.  You can give any of
-                        ltfnsewMC as flags and they will be passed along to
-                        git-blame.  The following maps, which work on the
-                        cursor line commit where sensible, are provided:
+:Gblame [flags]         Run git-blame [flags] on the current file and open the
+                        results in a scroll-bound vertical split.  The
+                        following maps, which work on the cursor line commit
+                        where sensible, are provided:
 
                         g?    show this help
                         A     resize to end of author column
                         C     resize to end of commit column
                         D     resize to end of date/time column
-                        q     close blame and return to blamed window
-                        gq    q, then |:Gedit| to return to work tree version
-                        <CR>  q, then open commit
-                        o     open commit in horizontal split
-                        O     open commit in new tab
-                        p     open commit in preview window
+                        gq    close blame, then |:Gedit| to return to work
+                              tree version
+                        <CR>  close blame, and jump to patch that added line
+                              (or directly to blob for boundary commit)
+                        o     jump to patch or blob in horizontal split
+                        O     jump to patch or blob in new tab
+                        p     jump to patch or blob in preview window
                         -     reblame at commit
                         ~     reblame at [count]th first grandparent
                         P     reblame at [count]th parent (like HEAD^[count])
 
+:[range]Gblame [flags]  If a range is given, just that part of the file will
+:Gblame [flags] {file}  be blamed, and a horizontal split without
+                        scrollbinding is used.  You can also give an arbitrary
+                        filename.
+
                                                 *fugitive-:Gbrowse*
 :Gbrowse                Open the current file, blob, tree, commit, or tag
                         in your browser at the upstream hosting provider.
@@ -238,7 +252,7 @@ operate on the file or hunk under the cursor are generally available in visual
 mode to operate on multiple files or partial hunks.
 
                                                 *fugitive-staging-mappings*
-Staging and resetting mappings ~
+Staging/unstaging mappings ~
 
                                                 *fugitive_s*
 s                       Stage (add) the file or hunk under the cursor.
@@ -249,11 +263,8 @@ u                       Unstage (reset) the file or hunk under the cursor.
                                                 *fugitive_-*
 -                       Stage or unstage the file or hunk under the cursor.
 
-                                                *fugitive_CTRL-N*
-<C-N>                   Skip to the next file or hunk.
-
-                                                *fugitive_CTRL-P*
-<C-P>                   Skip to the previous file or hunk.
+                                                *fugitive_U*
+U                       Unstage everything.
 
                                                 *fugitive_X*
 X                       Discard the change under the cursor.  This uses
@@ -267,39 +278,53 @@ X                       Discard the change under the cursor.  This uses
                                                 *fugitive_=*
 =                       Toggle an inline diff of the file under the cursor.
 
-                                                *fugitive_<*
-<                       Insert an inline diff of the file under the cursor.
-
                                                 *fugitive_>*
->                       Remove the inline diff of the file under the cursor.
+>                       Insert an inline diff of the file under the cursor.
 
-                                                *fugitive_i*
-i                       On untracked files, call |:Git| add --intent-to-add.
-                        Otherwise, move to next hunk, expanding inline diffs
-                        automatically.
+                                                *fugitive_<*
+<                       Remove the inline diff of the file under the cursor.
 
-                                                *fugitive_dd*
-dd                      Perform a |:Gdiff| on the file under the cursor.
+                                                *fugitive_gI*
+gI                      Open .git/info/exclude in a split and add the file
+                        under the cursor.  Use a count to open .gitignore.
 
-                                                *fugitive_ds*
-ds                      Perform a |:Gsdiff| on the file under the cursor.
-
-                                                *fugitive_dv*
-dv                      Perform a |:Gvdiff| on the file under the cursor.
+                                                *fugitive_I*
+I                       Invoke |:Git| add --patch or reset --patch on the file
+P                       under the cursor. On untracked files, this instead
+                        calls |:Git| add --intent-to-add.
 
+                                                *fugitive_d*
+Diff mappings ~
                                                 *fugitive_dp*
 dp                      Invoke |:Git!| diff on the file under the cursor.
-                        Deprecated in favor of inline diffs. On untracked
-                        files, this instead calls |:Git| add --intent-to-add.
+                        Deprecated in favor of inline diffs.
 
-P                       Invoke |:Git| add --patch or reset --patch on the file
-                        under the cursor.
+                                                *fugitive_dd*
+dd                      Perform a |:Gdiffsplit| on the file under the cursor.
+
+                                                *fugitive_dv*
+dv                      Perform a |:Gvdiffsplit| on the file under the cursor.
+
+                                                *fugitive_ds* *fugitive_dh*
+ds                      Perform a |:Ghdiffsplit| on the file under the cursor.
+dh
+                                                *fugitive_dq*
+dq                      Close all but one diff buffer, and |:diffoff|! the
+                        last one.
+
+                                                *fugitive_d?*
+d?                      Show this help.
 
                                                 *fugitive-navigation-mappings*
 Navigation mappings ~
 
                                                 *fugitive_<CR>*
 <CR>                    Open the file or |fugitive-object| under the cursor.
+                        in a blob, this and similar maps jump to the patch
+                        from the diff where this was added, or where it was
+                        removed if a count was given.  If the line is still in
+                        the work tree version, passing a count takes you to
+                        it.
 
                                                 *fugitive_o*
 o                       Open the file or |fugitive-object| under the cursor in
@@ -313,6 +338,11 @@ gO                      Open the file or |fugitive-object| under the cursor in
 O                       Open the file or |fugitive-object| under the cursor in
                         a new tab.
 
+                                                *fugitive_p*
+p                       Open the file or |fugitive-object| under the cursor in
+                        a preview window.  In the status buffer, 1p is
+                        required to bypass the legacy usage instructions.
+
                                                 *fugitive_~*
 ~                       Open the current file in the [count]th first ancestor.
 
@@ -322,9 +352,78 @@ P                       Open the current file in the [count]th parent.
                                                 *fugitive_C*
 C                       Open the commit containing the current file.
 
-                                                *fugitive_CTRL-W_C*
-<C-W>C                  Open the commit containing the current file in a new
-                        split.
+                                                *fugitive_CTRL-P* *fugitive_(*
+(                       Jump to the previous file, hunk, or revision.
+
+                                                *fugitive_CTRL-N* *fugitive_)*
+)                       Jump to the next file, hunk, or revision.
+
+                                                *fugitive_[c*
+[c                      Jump to previous hunk, expanding inline diffs
+                        automatically.  (This shadows the Vim built-in |[c|
+                        that provides a similar operation in |diff| mode.)
+
+                                                *fugitive_]c*
+]c                      Jump to next hunk, expanding inline diffs
+                        automatically.  (This shadows the Vim built-in |]c|
+                        that provides a similar operation in |diff| mode.)
+
+                                                *fugitive_[/* *fugitive_[m*
+[/                      Jump to previous file, collapsing inline diffs
+[m                      automatically.  (Mnemonic: "/" appears in filenames,
+                        "m" appears in "filenames".)
+
+                                                *fugitive_]/* *fugitive_]m*
+]/                      Jump to next file, collapsing inline diffs
+]m                      automatically.  (Mnemonic: "/" appears in filenames,
+                        "m" appears in "filenames".)
+
+                                                *fugitive_i*
+i                       Jump to the next file or hunk, expanding inline diffs
+                        automatically.
+
+                                                *fugitive_[[*
+[[                      Jump [count] sections backward.
+
+                                                *fugitive_]]*
+]]                      Jump [count] sections forward.
+
+                                                *fugitive_[]*
+[]                      Jump [count] section ends backward.
+
+                                                *fugitive_][*
+][                      Jump [count] section ends forward.
+
+                                                *fugitive_star*
+*                       One the first column of a + or - diff line, search for
+                        the corresponding - or + line.  Otherwise, defer to
+                        built-in |star|.
+
+                                                *fugitive_#*
+#                       Same as "*", but search backward.
+
+                                                *fugitive_gu*
+gu                      Jump to file [count] in the "Untracked" or "Unstaged"
+                        section.
+
+                                                *fugitive_gU*
+gU                      Jump to file [count] in the "Unstaged" section.
+
+                                                *fugitive_gs*
+gs                      Jump to file [count] in the "Staged" section.
+
+                                                *fugitive_gp*
+gp                      Jump to file [count] in the "Unpushed" section.
+
+                                                *fugitive_gP*
+gP                      Jump to file [count] in the "Unpulled" section.
+
+                                                *fugitive_gr*
+gr                      Jump to file [count] in the "Rebasing" section.
+
+                                                *fugitive_gi*
+gi                      Open .git/info/exclude in a split.  Use a count to
+                        open .gitignore.
 
                                                 *fugitive_c*
 Commit mappings ~
@@ -344,17 +443,74 @@ cva                     Amend the last commit with -v
 cf                      Create a `fixup!` commit for the commit under the
                         cursor.
 
+cF                      Create a `fixup!` commit for the commit under the
+                        cursor and immediately rebase it.
+
 cs                      Create a `squash!` commit for the commit under the
                         cursor.
 
+cS                      Create a `squash!` commit for the commit under the
+                        cursor and immediately rebase it.
+
 cA                      Create a `squash!` commit for the commit under the
                         cursor and edit the message.
 
+c<Space>                Populate command line with ":Gcommit ".
+
+                                                *fugitive_cr*
+crc                     Revert the commit under the cursor.
+
+crn                     Revert the commit under the cursor in the index and
+                        work tree, but do not actually commit the changes.
+
+cr<Space>               Populate command line with ":Grevert ".
+
+                                                *fugitive_cm*
+cm<Space>               Populate command line with ":Gmerge ".
+
+c?                      Show this help.
+
+                                                *fugitive_cb*
+                                                *fugitive_co*
+Checkout/branch mappings ~
+
+coo                     Check out the commit under the cursor.
+
+cb<Space>               Populate command line with ":G branch ".
+
+co<Space>               Populate command line with ":G checkout ".
+
+cb?                     Show this help.
+co?
+
+                                                *fugitive_cz*
+Stash mappings ~
+
+czz                     Push stash.  Pass a [count] of 1 to add
+                        `--include-untracked` or 2 to add `--all`.
+
+czw                     Push stash of worktree.  Like `czz` with
+                        `--include-index`.
+
+czA                     Apply topmost stash, or stash@{count}.
+
+cza                     Apply topmost stash, or stash@{count}, preserving the
+                        index.
+
+czP                     Pop topmost stash, or stash@{count}.
+
+czp                     Pop topmost stash, or stash@{count}, preserving the
+                        index.
+
+cz<Space>               Populate command line with ":G stash ".
+
+cz?                     Show this help.
+
                                                 *fugitive_r*
 Rebase mappings ~
 
 ri                      Perform an interactive rebase.  Uses ancestor of
-                        commit under cursor as upstream if available.
+u                       commit under cursor as upstream if available.
 
 rf                      Perform an autosquash rebase without editing the todo
                         list.  Uses ancestor of commit under cursor as
@@ -382,21 +538,22 @@ rm                      Perform an interactive rebase with the commit under
 rd                      Perform an interactive rebase with the commit under
                         the cursor set to `drop`.
 
+r<Space>                Populate command line with ":Grebase ".
+
+r?                      Show this help.
+
                                                 *fugitive-misc-mappings*
 Miscellaneous mappings ~
 
                                                 *fugitive_gq* *fugitive_q*
 gq                      Close the status buffer.
 
-                                                *fugitive_R*
-R                       Reload the status buffer.
-
                                                 *fugitive_.*
 .                       Start a |:| command line with the file under the
                         cursor prepopulated.
 
                                                 *fugitive_g?*
-g?                      Open this help.
+g?                      Show help for |fugitive-mappings|.
 
                                                 *fugitive-global-mappings*
 Global mappings ~
@@ -418,12 +575,13 @@ optional object, the default is the file in the index for work tree files and
 the work tree file for everything else.  Example objects follow.
 
 Object          Meaning ~
-HEAD            .git/HEAD
-refs/heads/x    .git/refs/heads/x (in "common dir" if present)
 @               The commit referenced by @ aka HEAD
+master          The commit referenced by master
 master^         The parent of the commit referenced by master
+master...other  The merge base of master and other
 master:         The tree referenced by master
 ./master        The file named master in the working directory
+:(top)master    The file named master in the the work tree
 Makefile        The file named Makefile in the work tree
 @^:Makefile     The file named Makefile in the parent of HEAD
 :Makefile       The file named Makefile in the index (writable)
@@ -457,6 +615,6 @@ ABOUT                                           *fugitive-about*
 
 Grab the latest version or report a bug on GitHub:
 
-http://github.com/tpope/vim-fugitive
+https://github.com/tpope/vim-fugitive
 
  vim:tw=78:et:ft=help:norl:
diff --git a/sources_non_forked/vim-fugitive/plugin/fugitive.vim b/sources_non_forked/vim-fugitive/plugin/fugitive.vim
index 9d23a7dd..b7d191fd 100644
--- a/sources_non_forked/vim-fugitive/plugin/fugitive.vim
+++ b/sources_non_forked/vim-fugitive/plugin/fugitive.vim
@@ -1,6 +1,6 @@
 " fugitive.vim - A Git wrapper so awesome, it should be illegal
 " Maintainer:   Tim Pope <http://tpo.pe/>
-" Version:      2.5
+" Version:      3.0
 " GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
 
 if exists('g:loaded_fugitive')
@@ -20,18 +20,14 @@ function! FugitiveGitDir(...) abort
   endif
 endfunction
 
-function! FugitiveCommonDir(...) abort
-  let dir = FugitiveGitDir(a:0 ? a:1 : -1)
-  if empty(dir)
-    return ''
-  endif
-  return fugitive#CommonDir(dir)
-endfunction
-
-function! FugitiveWorkTree(...) abort
-  return s:Tree(FugitiveGitDir(a:0 ? a:1 : -1))
-endfunction
-
+" FugitiveReal() takes a fugitive:// URL and returns the corresponding path in
+" the work tree.  This may be useful to get a cleaner path for inclusion in
+" the statusline, for example.  Note that the file and its parent directories
+" are not guaranteed to exist.
+"
+" This is intended as an abstract API to be used on any "virtual" path.  For a
+" buffer named foo://bar, check for a function named FooReal(), and if it
+" exists, call FooReal("foo://bar").
 function! FugitiveReal(...) abort
   let file = a:0 ? a:1 : @%
   if file =~# '^\a\a\+:' || a:0 > 1
@@ -43,6 +39,13 @@ function! FugitiveReal(...) abort
   endif
 endfunction
 
+" FugitiveFind() takes a Fugitive object and returns the appropriate Vim
+" buffer name.  You can use this to generate Fugitive URLs ("HEAD:README") or
+" to get the absolute path to a file in the Git dir (".git/HEAD"), the common
+" dir (".git/config"), or the work tree (":(top)Makefile").
+"
+" An optional second argument provides the Git dir, or the buffer number of a
+" buffer with a Git dir.  The default is the current buffer.
 function! FugitiveFind(...) abort
   return fugitive#Find(a:0 ? a:1 : bufnr(''), FugitiveGitDir(a:0 > 1 ? a:2 : -1))
 endfunction
@@ -55,12 +58,15 @@ function! FugitivePath(...) abort
   endif
 endfunction
 
+" FugitiveParse() takes a fugitive:// URL and returns a 2 element list
+" containing the Git dir and an object name ("commit:file").  It's effectively
+" then inverse of FugitiveFind().
 function! FugitiveParse(...) abort
   let path = s:Slash(a:0 ? a:1 : @%)
   if path !~# '^fugitive:'
     return ['', '']
   endif
-  let vals = matchlist(path, '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\x\{40\}\|[0-3]\)\(/.*\)\=$')
+  let vals = matchlist(path, '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\x\{40,\}\|[0-3]\)\(/.*\)\=$')
   if len(vals)
     return [(vals[2] =~# '^.$' ? ':' : '') . vals[2] . substitute(vals[3], '^/', ':', ''), vals[1]]
   endif
@@ -68,6 +74,14 @@ function! FugitiveParse(...) abort
   throw v:errmsg
 endfunction
 
+" FugitivePrepare() constructs a Git command string which can be executed with
+" functions like system() and commands like :!.  Integer arguments will be
+" treated as buffer numbers, and the appropriate relative path inserted in
+" their place.
+"
+" If the first argument is a string that looks like a path or an empty string,
+" it will be used as the Git dir.  If it's a buffer number, the Git dir for
+" that buffer will be used.  The default is the current buffer.
 function! FugitivePrepare(...) abort
   return call('fugitive#Prepare', a:000)
 endfunction
@@ -101,9 +115,21 @@ function! FugitiveStatusline(...) abort
   return fugitive#Statusline()
 endfunction
 
+function! FugitiveCommonDir(...) abort
+  let dir = FugitiveGitDir(a:0 ? a:1 : -1)
+  if empty(dir)
+    return ''
+  endif
+  return fugitive#CommonDir(dir)
+endfunction
+
+function! FugitiveWorkTree(...) abort
+  return s:Tree(FugitiveGitDir(a:0 ? a:1 : -1))
+endfunction
+
 function! FugitiveIsGitDir(path) abort
   let path = substitute(a:path, '[\/]$', '', '') . '/'
-  return getfsize(path.'HEAD') > 10 && (
+  return len(a:path) && getfsize(path.'HEAD') > 10 && (
         \ isdirectory(path.'objects') && isdirectory(path.'refs') ||
         \ getftype(path.'commondir') ==# 'file')
 endfunction
@@ -124,10 +150,10 @@ function! s:Tree(path) abort
       let config = readfile(config_file,'',10)
       call filter(config,'v:val =~# "^\\s*worktree *="')
       if len(config) == 1
-        let worktree = matchstr(config[0], '= *\zs.*')
+        let worktree = s:Slash(FugitiveVimPath(matchstr(config[0], '= *\zs.*')))
       endif
     elseif filereadable(dir . '/gitdir')
-      let worktree = fnamemodify(readfile(dir . '/gitdir')[0], ':h')
+      let worktree = s:Slash(fnamemodify(FugitiveVimPath(readfile(dir . '/gitdir')[0]), ':h'))
       if worktree ==# '.'
         unlet! worktree
       endif
@@ -159,9 +185,11 @@ function! FugitiveExtractGitDir(path) abort
   endif
   let root = resolve(path)
   if root !=# path
-    silent! exe haslocaldir() ? 'lcd .' : 'cd .'
+    silent! exe (haslocaldir() ? 'lcd' : exists(':tcd') && haslocaldir(-1) ? 'tcd' : 'cd') '.'
   endif
   let previous = ""
+  let env_git_dir = len($GIT_DIR) ? s:Slash(simplify(fnamemodify(FugitiveVimPath($GIT_DIR), ':p:s?[\/]$??'))) : ''
+  call s:Tree(env_git_dir)
   while root !=# previous
     if root =~# '\v^//%([^/]+/?)?$'
       break
@@ -169,14 +197,10 @@ function! FugitiveExtractGitDir(path) abort
     if index(split($GIT_CEILING_DIRECTORIES, ':'), root) >= 0
       break
     endif
-    if root ==# $GIT_WORK_TREE && FugitiveIsGitDir($GIT_DIR)
-      return simplify(fnamemodify($GIT_DIR, ':p:s?[\/]$??'))
-    endif
-    if FugitiveIsGitDir($GIT_DIR)
-      call s:Tree(simplify(fnamemodify($GIT_DIR, ':p:s?[\/]$??')))
-      if has_key(s:dir_for_worktree, root)
-        return s:dir_for_worktree[root]
-      endif
+    if root ==# $GIT_WORK_TREE && FugitiveIsGitDir(env_git_dir)
+      return env_git_dir
+    elseif has_key(s:dir_for_worktree, root)
+      return s:dir_for_worktree[root]
     endif
     let dir = substitute(root, '[\/]$', '', '') . '/.git'
     let type = getftype(dir)
@@ -186,10 +210,11 @@ function! FugitiveExtractGitDir(path) abort
       return resolve(dir)
     elseif type !=# '' && filereadable(dir)
       let line = get(readfile(dir, '', 1), 0, '')
-      if line =~# '^gitdir: \.' && FugitiveIsGitDir(root.'/'.line[8:-1])
-        return simplify(root.'/'.line[8:-1])
-      elseif line =~# '^gitdir: ' && FugitiveIsGitDir(line[8:-1])
-        return line[8:-1]
+      let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
+      if file_dir !~# '^/\|^\a:' && FugitiveIsGitDir(root . '/' . file_dir)
+        return simplify(root . '/' . file_dir)
+      elseif len(file_dir) && FugitiveIsGitDir(file_dir)
+        return file_dir
       endif
     elseif FugitiveIsGitDir(root)
       return root
@@ -215,6 +240,18 @@ function! FugitiveDetect(path) abort
   endif
 endfunction
 
+function! FugitiveVimPath(path) abort
+  if exists('+shellslash') && !&shellslash
+    return tr(a:path, '/', '\')
+  else
+    return a:path
+  endif
+endfunction
+
+function! FugitiveGitPath(path) abort
+  return s:Slash(a:path)
+endfunction
+
 function! s:Slash(path) abort
   if exists('+shellslash')
     return tr(a:path, '\', '/')
@@ -234,7 +271,10 @@ function! s:ProjectionistDetect() abort
     if exists('+shellslash') && !&shellslash
       let base = tr(base, '/', '\')
     endif
-    call projectionist#append(base, FugitiveCommonDir(dir) . '/info/projections.json')
+    let file = FugitiveCommonDir(dir) . '/info/projections.json'
+    if filereadable(file)
+      call projectionist#append(base, file)
+    endif
   endif
 endfunction
 
@@ -266,7 +306,7 @@ augroup fugitive
   autocmd FileType gitrebase
         \ let &l:include = '^\%(pick\|squash\|edit\|reword\|fixup\|drop\|[pserfd]\)\>' |
         \ if len(FugitiveGitDir()) |
-        \   let &l:includeexpr = 'v:fname =~# ''^\x\{4,40\}$'' ? FugitiveFind(v:fname) : ' .
+        \   let &l:includeexpr = 'v:fname =~# ''^\x\{4,\}$'' ? FugitiveFind(v:fname) : ' .
         \   (len(&l:includeexpr) ? &l:includeexpr : 'v:fname') |
         \ endif |
         \ let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|setl inex= inc='
@@ -296,3 +336,20 @@ augroup fugitive
 
   autocmd User ProjectionistDetect call s:ProjectionistDetect()
 augroup END
+
+let g:io_fugitive = {
+      \ 'simplify': function('fugitive#simplify'),
+      \ 'resolve': function('fugitive#resolve'),
+      \ 'getftime': function('fugitive#getftime'),
+      \ 'getfsize': function('fugitive#getfsize'),
+      \ 'getftype': function('fugitive#getftype'),
+      \ 'filereadable': function('fugitive#filereadable'),
+      \ 'filewritable': function('fugitive#filewritable'),
+      \ 'isdirectory': function('fugitive#isdirectory'),
+      \ 'getfperm': function('fugitive#getfperm'),
+      \ 'setfperm': function('fugitive#setfperm'),
+      \ 'readfile': function('fugitive#readfile'),
+      \ 'writefile': function('fugitive#writefile'),
+      \ 'glob': function('fugitive#glob'),
+      \ 'delete': function('fugitive#delete'),
+      \ 'Real': function('FugitiveReal')}
diff --git a/sources_non_forked/vim-fugitive/syntax/fugitive.vim b/sources_non_forked/vim-fugitive/syntax/fugitive.vim
index e2389b5c..afc0c0bc 100644
--- a/sources_non_forked/vim-fugitive/syntax/fugitive.vim
+++ b/sources_non_forked/vim-fugitive/syntax/fugitive.vim
@@ -9,24 +9,39 @@ syn include @fugitiveDiff syntax/diff.vim
 
 syn match fugitiveHeader /^[A-Z][a-z][^:]*:/ nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
 
-syn region fugitiveSection start=/^\%(.*(\d\+)$\)\@=/ contains=fugitiveHeading end=/^$\@=/
+syn region fugitiveSection start=/^\%(.*(\d\+)$\)\@=/ contains=fugitiveHeading end=/^$/
+syn cluster fugitiveSection contains=fugitiveSection
 syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\+)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite
 syn match fugitiveCount /(\d\+)/hs=s+1,he=e-1 contained
 syn match fugitivePreposition /\<\%([io]nto\|from\|to\|Rebasing\%( detached\)\=\)\>/ transparent contained nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
 
-syn match fugitiveInstruction /^\l\l\+\>/ contained containedin=fugitiveSection nextgroup=fugitiveHash skipwhite
-syn match fugitiveDone /^done\>/ contained containedin=fugitiveSection nextgroup=fugitiveHash skipwhite
-syn match fugitiveStop /^stop\>/ contained containedin=fugitiveSection nextgroup=fugitiveHash skipwhite
-syn match fugitiveModifier /^[MADRCU?]\{1,2} / contained containedin=fugitiveSection
-syn match FugitiveSymbolicRef /\.\@!\%(\.\.\@!\|[^[:space:][:cntrl:]\:.]\)\+\.\@<!/ contained
-syn match fugitiveHash /^\x\{4,\}\>/ contained containedin=fugitiveSection
+syn match fugitiveInstruction /^\l\l\+\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
+syn match fugitiveDone /^done\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
+syn match fugitiveStop /^stop\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
+syn match fugitiveModifier /^[MADRCU?]\{1,2} / contained containedin=@fugitiveSection
+syn match fugitiveSymbolicRef /\.\@!\%(\.\.\@!\|[^[:space:][:cntrl:]\:.]\)\+\.\@<!/ contained
+syn match fugitiveHash /^\x\{4,\}\>/ contained containedin=@fugitiveSection
 syn match fugitiveHash /\<\x\{4,\}\>/ contained
 
-syn region fugitiveHunk start=/^\%(@@ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=@fugitiveDiff containedin=fugitiveSection fold
+syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=@fugitiveDiff containedin=@fugitiveSection fold
+
+for s:section in ['Untracked', 'Unstaged', 'Staged']
+  exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\+)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/'
+  exe 'syn match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section'
+  exe 'syn cluster fugitiveSection add=fugitive' . s:section . 'Section'
+  exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\+)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite'
+endfor
+unlet s:section
 
 hi def link fugitiveHeader Label
 hi def link fugitiveHeading PreProc
+hi def link fugitiveUntrackedHeading PreCondit
+hi def link fugitiveUnstagedHeading Macro
+hi def link fugitiveStagedHeading Include
 hi def link fugitiveModifier Type
+hi def link fugitiveUntrackedModifier StorageClass
+hi def link fugitiveUnstagedModifier Structure
+hi def link fugitiveStagedModifier Typedef
 hi def link fugitiveInstruction Type
 hi def link fugitiveStop Function
 hi def link fugitiveHash Identifier
diff --git a/sources_non_forked/vim-fugitive/syntax/fugitiveblame.vim b/sources_non_forked/vim-fugitive/syntax/fugitiveblame.vim
new file mode 100644
index 00000000..c06d19e0
--- /dev/null
+++ b/sources_non_forked/vim-fugitive/syntax/fugitiveblame.vim
@@ -0,0 +1,7 @@
+if exists("b:current_syntax")
+  finish
+endif
+
+call fugitive#BlameSyntax()
+
+let b:current_syntax = "fugitiveblame"
diff --git a/sources_non_forked/vim-gitgutter/.github/issue_template.md b/sources_non_forked/vim-gitgutter/.github/issue_template.md
index 732d22ef..d700ce98 100644
--- a/sources_non_forked/vim-gitgutter/.github/issue_template.md
+++ b/sources_non_forked/vim-gitgutter/.github/issue_template.md
@@ -2,7 +2,3 @@
 
 > What vim/nvim version are you on?
 
-> If no signs are showing at all, what does `:echo b:gitgutter.path` give?
-
-> If no signs are showing at all, and the `path` value is a path and not `-2`, does it work with `let g:gitgutter_grep=''`?
-
diff --git a/sources_non_forked/vim-gitgutter/README.mkd b/sources_non_forked/vim-gitgutter/README.mkd
index a08507b0..3261f905 100644
--- a/sources_non_forked/vim-gitgutter/README.mkd
+++ b/sources_non_forked/vim-gitgutter/README.mkd
@@ -12,12 +12,14 @@ Features:
 * Never saves the buffer.
 * Quick jumping between blocks of changed lines ("hunks").
 * Stage/undo/preview individual hunks.
+* Stage partial hunks.
 * Provides a hunk text object.
 * Diffs against index (default) or any commit.
 * Allows folding all unchanged text.
 * Handles line endings correctly, even with repos that do CRLF conversion.
 * Optional line highlighting.
-* Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc).
+* Optional line number highlighting. (Only available in Neovim 0.3.2 or higher)
+* Fully customisable (signs, sign column, line (number) highlights, mappings, extra git-diff arguments, etc).
 * Can be toggled on/off, globally or per buffer.
 * Preserves signs from other plugins.
 * Easy to integrate diff stats into status line; built-in integration with [vim-airline](https://github.com/bling/vim-airline/).
@@ -26,7 +28,7 @@ Features:
 Constraints:
 
 * Supports git only.  If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify).
-* Relies on the `FocusGained` event.  If your terminal doesn't report focus events, either use something like [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.
+* Relies on the `FocusGained` event.  If your terminal doesn't report focus events, either use something like [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.  For tmux, `set -g focus-events on` in your tmux.conf.
 
 
 ### Screenshot
@@ -103,6 +105,17 @@ cp -r vim-gitgutter/* ~/.vim/
 See `:help add-global-plugin`.
 
 
+### Windows
+
+I recommend configuring vim-gitgutter with the full path to your git executable.  For example:
+
+```viml
+let g:gitgutter_git_executable = 'C:\Program Files\Git\bin\git.exe'
+```
+
+This is to avoid a problem which occurs if you have file named `git.*` (i.e. with any extension in `PATHEXT`) in your current folder.  `cmd.exe` prioritises the current folder over folders in `PATH` and will try to execute your file instead of the `git` binary.
+
+
 ### Getting started
 
 When you make a change to a file tracked by git, the diff markers should appear automatically.  The delay is governed by vim's `updatetime` option; the default value is `4000`, i.e. 4 seconds, but I suggest reducing it to around 100ms (add `set updatetime=100` to your vimrc).
@@ -138,9 +151,15 @@ And you can turn line highlighting on and off (defaults to off):
 * turn off with `:GitGutterLineHighlightsDisable`
 * toggle with `:GitGutterLineHighlightsToggle`.
 
+With Neovim 0.3.2 or higher, you can turn line number highlighting on and off (defaults to off):
+
+* turn on with `:GitGutterLineNrHighlightsEnable`
+* turn off with `:GitGutterLineNrHighlightsDisable`
+* toggle with `:GitGutterLineNrHighlightsToggle`.
+
 Note that if you have line highlighting on and signs off, you will have an empty sign column – more accurately, a sign column with invisible signs.  This is because line highlighting requires signs and Vim always shows the sign column even if the signs are invisible.
 
-If you switch off both line highlighting and signs, you won't see the sign column.  That is unless you configure the sign column always to be there (see Sign Column section).
+If you switch off both line highlighting and signs, you won't see the sign column.
 
 To keep your Vim snappy, vim-gitgutter will suppress the signs when a file has more than 500 changes.  As soon as the number of changes falls below the limit vim-gitgutter will show the signs again.  You can configure the threshold with:
 
@@ -169,6 +188,18 @@ You can stage or undo an individual hunk when your cursor is in it:
 * stage the hunk with `<Leader>hs` or
 * undo it with `<Leader>hu`.
 
+To stage part of an additions-only hunk by:
+
+* either visually selecting the part you want and staging with your mapping, e.g. `<Leader>hs`;
+* or using a range with the `GitGutterStageHunk` command, e.g. `:42,45GitGutterStageHunk`.
+
+To stage part of any hunk:
+
+* preview the hunk, e.g. `<Leader>hp`;
+* move to the preview window, e.g. `:wincmd P`;
+* delete the lines you do not want to stage;
+* stage the remaining lines: either write (`:w`) the window or stage via `<Leader>hs` or `:GitGutterStageHunk`.
+
 See the FAQ if you want to unstage staged changes.
 
 The `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat).
@@ -180,7 +211,7 @@ nmap <Leader>ha <Plug>GitGutterStageHunk
 nmap <Leader>hr <Plug>GitGutterUndoHunk
 ```
 
-And you can preview a hunk's changes with `<Leader>hp`.  You can of course change this mapping, e.g:
+And you can preview a hunk's changes with `<Leader>hp`.  The location of the preview window is configured with `g:gitgutter_preview_win_location` (default `'bo'`).  You can of course change this mapping, e.g:
 
 ```viml
 nmap <Leader>hv <Plug>GitGutterPreviewHunk
@@ -224,18 +255,20 @@ You can customise:
 
 * The sign column's colours
 * Whether or not the sign column is shown when there aren't any signs (defaults to no)
+* How to handle non-gitgutter signs
 * The signs' colours and symbols
 * Line highlights
 * The base of the diff
 * Extra arguments for `git` when running `git diff`
 * Extra arguments for `git diff`
 * Key mappings
-* Whether or not vim-gitgutter is on initially (defaults to on)
-* Whether or not signs are shown (defaults to yes)
-* Whether or not line highlighting is on initially (defaults to off)
-* Whether or not vim-gitgutter runs in "realtime" (defaults to yes)
-* Whether or not vim-gitgutter runs eagerly (defaults to yes)
-* Whether or not vim-gitgutter runs asynchronously (defaults to yes)
+* Whether vim-gitgutter is on initially (defaults to on)
+* Whether signs are shown (defaults to yes)
+* Whether line highlighting is on initially (defaults to off)
+* Whether line number highlighting is on initially (defaults to off)
+* Whether vim-gitgutter runs asynchronously (defaults to yes)
+* Whether to clobber or preserve non-gitgutter signs
+* The priority of gitgutter's signs.
 
 Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme.
 
@@ -260,11 +293,14 @@ highlight SignColumn guibg=whatever      " gVim/MacVim
 By default the sign column will appear when there are signs to show and disappear when there aren't.  To always have the sign column, add to your vimrc:
 
 ```viml
-if exists('&signcolumn')  " Vim 7.4.2201
-  set signcolumn=yes
-else
-  let g:gitgutter_sign_column_always = 1
-endif
+" Vim 7.4.2201
+set signcolumn=yes
+```
+
+GitGutter can preserve or ignore non-gitgutter signs.  For Vim v8.1.0614 and later you can set gitgutter's signs' priorities with `g:gitgutter_sign_priority`, so gitgutter defaults to clobbering other signs.  For Neovim v0.4.0 and later you can set an expanding sign column so gitgutter again defaults to clobbering other signs.  Otherwise, gitgutter defaults to preserving other signs.  You can configure this with:
+
+```viml
+let g:gitgutter_sign_allow_clobber = 1
 ```
 
 
@@ -324,6 +360,26 @@ highlight link GitGutterChangeLine DiffText
 ```
 
 
+#### Line number highlights
+
+NOTE: This feature requires Neovim 0.3.2 or higher.
+
+Similarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`:
+
+```viml
+GitGutterAddLineNr          " default: links to CursorLineNr
+GitGutterChangeLineNr       " default: links to CursorLineNr
+GitGutterDeleteLineNr       " default: links to CursorLineNr
+GitGutterChangeDeleteLineNr " default: links to CursorLineNr
+```
+
+Maybe you think `CursorLineNr` is a bit annoying.  For example, you could use `Underlined` for this:
+
+```viml
+highlight link GitGutterChangeLineNr Underlined
+```
+
+
 #### The base of the diff
 
 By default buffers are diffed against the index.  However you can diff against any commit by setting:
@@ -384,6 +440,11 @@ Add `let g:gitgutter_signs = 0` to your `~/.vimrc`.
 Add `let g:gitgutter_highlight_lines = 1` to your `~/.vimrc`.
 
 
+#### To turn on line number highlighting by default
+
+Add `let g:gitgutter_highlight_linenrs = 1` to your `~/.vimrc`.
+
+
 #### To turn off asynchronous updates
 
 By default diffs are run asynchronously.  To run diffs synchronously instead:
@@ -532,7 +593,7 @@ Your colorscheme is configuring the `SignColumn` highlight group weirdly.  Pleas
 
 > What happens if I also use another plugin which uses signs (e.g. Syntastic)?
 
-Vim only allows one sign per line.  Before adding a sign to a line, vim-gitgutter checks whether a sign has already been added by somebody else.  If so it doesn't do anything.  In other words vim-gitgutter won't overwrite another plugin's signs.  It also won't remove another plugin's signs.
+You can configure whether GitGutter preserves or clobbers other signs using `g:gitgutter_sign_allow_clobber`.  Set to `1` to clobber other signs (default on Vim >= 8.1.0614 and NeoVim >= 0.4.0) or `0` to preserve them.
 
 
 ### Troubleshooting
@@ -557,7 +618,7 @@ Here are some things you can check:
 
 #### When signs don't update after focusing Vim
 
-* Your terminal probably isn't reporting focus events.  Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.
+* Your terminal probably isn't reporting focus events.  Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.  For tmux, try `set -g focus-events on` in your tmux.conf.
 
 
 ### Shameless Plug
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter.vim
index 2e17fdb8..98188713 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter.vim
@@ -10,7 +10,6 @@ function! gitgutter#all(force) abort
       let file = expand('#'.bufnr.':p')
       if !empty(file)
         if index(visible, bufnr) != -1
-          call gitgutter#init_buffer(bufnr)
           call gitgutter#process_buffer(bufnr, a:force)
         elseif a:force
           call s:reset_tick(bufnr)
@@ -21,22 +20,21 @@ function! gitgutter#all(force) abort
 endfunction
 
 
-" Finds the file's path relative to the repo root.
-function! gitgutter#init_buffer(bufnr)
-  if gitgutter#utility#is_active(a:bufnr)
-    let p = gitgutter#utility#repo_path(a:bufnr, 0)
-    if type(p) != s:t_string || empty(p)
-      call gitgutter#utility#set_repo_path(a:bufnr)
-      call s:setup_maps()
-    endif
-  endif
-endfunction
-
-
 function! gitgutter#process_buffer(bufnr, force) abort
   " NOTE a:bufnr is not necessarily the current buffer.
 
   if gitgutter#utility#is_active(a:bufnr)
+
+    if has('patch-7.4.1559')
+      let l:Callback = function('gitgutter#process_buffer', [a:bufnr, a:force])
+    else
+      let l:Callback = {'function': 'gitgutter#process_buffer', 'arguments': [a:bufnr, a:force]}
+    endif
+    let how = s:setup_path(a:bufnr, l:Callback)
+    if [how] == ['async']  " avoid string-to-number conversion if how is a number
+      return
+    endif
+
     if a:force || s:has_fresh_changes(a:bufnr)
 
       let diff = ''
@@ -108,11 +106,19 @@ endfunction
 
 " }}}
 
-function! s:setup_maps()
+function! gitgutter#setup_maps()
   if !g:gitgutter_map_keys
     return
   endif
 
+  " Note hasmapto() and maparg() operate on the current buffer.
+
+  let bufnr = bufnr('')
+
+  if gitgutter#utility#getbufvar(bufnr, 'mapped', 0)
+    return
+  endif
+
   if !hasmapto('<Plug>GitGutterPrevHunk') && maparg('[c', 'n') ==# ''
     nmap <buffer> [c <Plug>GitGutterPrevHunk
   endif
@@ -120,7 +126,10 @@ function! s:setup_maps()
     nmap <buffer> ]c <Plug>GitGutterNextHunk
   endif
 
-  if !hasmapto('<Plug>GitGutterStageHunk') && maparg('<Leader>hs', 'n') ==# ''
+  if !hasmapto('<Plug>GitGutterStageHunk', 'v') && maparg('<Leader>hs', 'x') ==# ''
+    xmap <buffer> <Leader>hs <Plug>GitGutterStageHunk
+  endif
+  if !hasmapto('<Plug>GitGutterStageHunk', 'n') && maparg('<Leader>hs', 'n') ==# ''
     nmap <buffer> <Leader>hs <Plug>GitGutterStageHunk
   endif
   if !hasmapto('<Plug>GitGutterUndoHunk') && maparg('<Leader>hu', 'n') ==# ''
@@ -142,6 +151,18 @@ function! s:setup_maps()
   if !hasmapto('<Plug>GitGutterTextObjectOuterVisual') && maparg('ac', 'x') ==# ''
     xmap <buffer> ac <Plug>GitGutterTextObjectOuterVisual
   endif
+
+  call gitgutter#utility#setbufvar(bufnr, 'mapped', 1)
+endfunction
+
+function! s:setup_path(bufnr, continuation)
+  let p = gitgutter#utility#repo_path(a:bufnr, 0)
+
+  if type(p) == s:t_string && !empty(p)  " if path is known
+    return
+  endif
+
+  return gitgutter#utility#set_repo_path(a:bufnr, a:continuation)
 endfunction
 
 function! s:has_fresh_changes(bufnr) abort
@@ -154,7 +175,7 @@ endfunction
 
 function! s:clear(bufnr)
   call gitgutter#sign#clear_signs(a:bufnr)
-  call gitgutter#sign#remove_dummy_sign(a:bufnr, 1)
   call gitgutter#hunk#reset(a:bufnr)
   call s:reset_tick(a:bufnr)
+  call gitgutter#utility#setbufvar(a:bufnr, 'path', '')
 endfunction
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter/diff.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter/diff.vim
index b270db73..99861cca 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter/diff.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter/diff.vim
@@ -4,7 +4,7 @@ let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
 
 " True for git v1.7.2+.
 function! s:git_supports_command_line_config_override() abort
-  call system(g:gitgutter_git_executable.' -c foo.bar=baz --version')
+  call system(g:gitgutter_git_executable.' '.g:gitgutter_git_args.' -c foo.bar=baz --version')
   return !v:shell_error
 endfunction
 
@@ -68,9 +68,9 @@ let s:counter = 0
 "                      the hunk headers (@@ -x,y +m,n @@); only possible if
 "                      grep is available.
 function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort
-  while gitgutter#utility#repo_path(a:bufnr, 0) == -1
-    sleep 5m
-  endwhile
+  if gitgutter#utility#repo_path(a:bufnr, 0) == -1
+    throw 'gitgutter author fail'
+  endif
 
   if gitgutter#utility#repo_path(a:bufnr, 0) == -2
     throw 'gitgutter not tracked'
@@ -119,14 +119,14 @@ function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort
 
     " Write file from index to temporary file.
     let index_name = g:gitgutter_diff_base.':'.gitgutter#utility#repo_path(a:bufnr, 1)
-    let cmd .= g:gitgutter_git_executable.' --no-pager show '.index_name.' > '.from_file.' && '
+    let cmd .= g:gitgutter_git_executable.' '.g:gitgutter_git_args.' --no-pager show '.index_name.' > '.from_file.' && '
 
   elseif a:from ==# 'working_tree'
     let from_file = gitgutter#utility#repo_path(a:bufnr, 1)
   endif
 
   " Call git-diff.
-  let cmd .= g:gitgutter_git_executable.' --no-pager '.g:gitgutter_git_args
+  let cmd .= g:gitgutter_git_executable.' '.g:gitgutter_git_args.' --no-pager '.g:gitgutter_git_args
   if s:c_flag
     let cmd .= ' -c "diff.autorefreshindex=0"'
     let cmd .= ' -c "diff.noprefix=false"'
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter/highlight.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter/highlight.vim
index 160856f7..5b14fc30 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter/highlight.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter/highlight.vim
@@ -4,7 +4,6 @@ function! gitgutter#highlight#line_disable() abort
 
   if !g:gitgutter_signs
     call gitgutter#sign#clear_signs(bufnr(''))
-    call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
   endif
 
   redraw!
@@ -31,6 +30,38 @@ function! gitgutter#highlight#line_toggle() abort
   endif
 endfunction
 
+function! gitgutter#highlight#linenr_disable() abort
+  let g:gitgutter_highlight_linenrs = 0
+  call s:define_sign_linenr_highlights()
+
+  if !g:gitgutter_signs
+    call gitgutter#sign#clear_signs(bufnr(''))
+  endif
+
+  redraw!
+endfunction
+
+function! gitgutter#highlight#linenr_enable() abort
+  let old_highlight_lines = g:gitgutter_highlight_linenrs
+
+  let g:gitgutter_highlight_linenrs = 1
+  call s:define_sign_linenr_highlights()
+
+  if !old_highlight_lines && !g:gitgutter_signs
+    call gitgutter#all(1)
+  endif
+
+  redraw!
+endfunction
+
+function! gitgutter#highlight#linenr_toggle() abort
+  if g:gitgutter_highlight_linenrs
+    call gitgutter#highlight#linenr_disable()
+  else
+    call gitgutter#highlight#linenr_enable()
+  endif
+endfunction
+
 
 function! gitgutter#highlight#define_sign_column_highlight() abort
   if g:gitgutter_override_sign_column_highlight
@@ -66,6 +97,11 @@ function! gitgutter#highlight#define_highlights() abort
   highlight default link GitGutterChangeLine       DiffChange
   highlight default link GitGutterDeleteLine       DiffDelete
   highlight default link GitGutterChangeDeleteLine GitGutterChangeLine
+
+  highlight default link GitGutterAddLineNr          CursorLineNr
+  highlight default link GitGutterChangeLineNr       CursorLineNr
+  highlight default link GitGutterDeleteLineNr       CursorLineNr
+  highlight default link GitGutterChangeDeleteLineNr CursorLineNr
 endfunction
 
 function! gitgutter#highlight#define_signs() abort
@@ -75,11 +111,11 @@ function! gitgutter#highlight#define_signs() abort
   sign define GitGutterLineRemovedFirstLine
   sign define GitGutterLineRemovedAboveAndBelow
   sign define GitGutterLineModifiedRemoved
-  sign define GitGutterDummy
 
   call s:define_sign_text()
   call gitgutter#highlight#define_sign_text_highlights()
   call s:define_sign_line_highlights()
+  call s:define_sign_linenr_highlights()
 endfunction
 
 function! s:define_sign_text() abort
@@ -131,40 +167,45 @@ function! s:define_sign_line_highlights() abort
   endif
 endfunction
 
-function! s:get_foreground_colors(group) abort
-  redir => highlight
-  silent execute 'silent highlight ' . a:group
-  redir END
-
-  let link_matches = matchlist(highlight, 'links to \(\S\+\)')
-  if len(link_matches) > 0 " follow the link
-    return s:get_foreground_colors(link_matches[1])
+function! s:define_sign_linenr_highlights() abort
+  if has('nvim-0.3.2')
+    try
+      if g:gitgutter_highlight_linenrs
+          sign define GitGutterLineAdded                 numhl=GitGutterAddLineNr
+          sign define GitGutterLineModified              numhl=GitGutterChangeLineNr
+          sign define GitGutterLineRemoved               numhl=GitGutterDeleteLineNr
+          sign define GitGutterLineRemovedFirstLine      numhl=GitGutterDeleteLineNr
+          sign define GitGutterLineRemovedAboveAndBelow  numhl=GitGutterDeleteLineNr
+          sign define GitGutterLineModifiedRemoved       numhl=GitGutterChangeDeleteLineNr
+      else
+        sign define GitGutterLineAdded                 numhl=
+        sign define GitGutterLineModified              numhl=
+        sign define GitGutterLineRemoved               numhl=
+        sign define GitGutterLineRemovedFirstLine      numhl=
+        sign define GitGutterLineRemovedAboveAndBelow  numhl=
+        sign define GitGutterLineModifiedRemoved       numhl=
+      endif
+    catch /E475/
+    endtry
   endif
+endfunction
 
-  let ctermfg = s:match_highlight(highlight, 'ctermfg=\([0-9A-Za-z]\+\)')
-  let guifg   = s:match_highlight(highlight, 'guifg=\([#0-9A-Za-z]\+\)')
+function! s:get_hl(group, what, mode) abort
+  let r = synIDattr(synIDtrans(hlID(a:group)), a:what, a:mode)
+  if empty(r) || r == -1
+    return 'NONE'
+  endif
+  return r
+endfunction
+
+function! s:get_foreground_colors(group) abort
+  let ctermfg = s:get_hl(a:group, 'fg', 'cterm')
+  let guifg = s:get_hl(a:group, 'fg', 'gui')
   return [guifg, ctermfg]
 endfunction
 
 function! s:get_background_colors(group) abort
-  redir => highlight
-  silent execute 'silent highlight ' . a:group
-  redir END
-
-  let link_matches = matchlist(highlight, 'links to \(\S\+\)')
-  if len(link_matches) > 0 " follow the link
-    return s:get_background_colors(link_matches[1])
-  endif
-
-  let ctermbg = s:match_highlight(highlight, 'ctermbg=\([0-9A-Za-z]\+\)')
-  let guibg   = s:match_highlight(highlight, 'guibg=\([#0-9A-Za-z]\+\)')
+  let ctermbg = s:get_hl(a:group, 'bg', 'cterm')
+  let guibg = s:get_hl(a:group, 'bg', 'gui')
   return [guibg, ctermbg]
 endfunction
-
-function! s:match_highlight(highlight, pattern) abort
-  let matches = matchlist(a:highlight, a:pattern)
-  if len(matches) == 0
-    return 'NONE'
-  endif
-  return matches[1]
-endfunction
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter/hunk.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter/hunk.vim
index c5111f89..6f4a6ffd 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter/hunk.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter/hunk.vim
@@ -169,8 +169,12 @@ function! gitgutter#hunk#text_object(inner) abort
 endfunction
 
 
-function! gitgutter#hunk#stage() abort
-  call s:hunk_op(function('s:stage'))
+function! gitgutter#hunk#stage(...) abort
+  if a:0 && (a:1 != 1 || a:2 != line('$'))
+    call s:hunk_op(function('s:stage'), a:1, a:2)
+  else
+    call s:hunk_op(function('s:stage'))
+  endif
   silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)
 endfunction
 
@@ -185,9 +189,39 @@ function! gitgutter#hunk#preview() abort
 endfunction
 
 
-function! s:hunk_op(op)
+function! s:hunk_op(op, ...)
   let bufnr = bufnr('')
 
+  if &previewwindow
+    if string(a:op) =~ '_stage'
+      " combine hunk-body in preview window with updated hunk-header
+      let hunk_body = getline(1, '$')
+
+      let [removed, added] = [0, 0]
+      for line in hunk_body
+        if line[0] == '-'
+          let removed += 1
+        elseif line[0] == '+'
+          let added += 1
+        endif
+      endfor
+
+      let hunk_header = b:hunk_header
+      " from count
+      let hunk_header[4] = substitute(hunk_header[4], '\(-\d\+\)\(,\d\+\)\?', '\=submatch(1).",".removed', '')
+      " to count
+      let hunk_header[4] = substitute(hunk_header[4], '\(+\d\+\)\(,\d\+\)\?', '\=submatch(1).",".added', '')
+
+      let hunk_diff = join(hunk_header + hunk_body, "\n")."\n"
+
+      wincmd p
+      pclose
+      call s:stage(hunk_diff)
+    endif
+
+    return
+  endif
+
   if gitgutter#utility#is_active(bufnr)
     " Get a (synchronous) diff.
     let [async, g:gitgutter_async] = [g:gitgutter_async, 0]
@@ -210,7 +244,14 @@ function! s:hunk_op(op)
         call gitgutter#utility#warn('did not recognise your choice')
       endif
     else
-      call a:op(gitgutter#diff#hunk_diff(bufnr, diff))
+      let hunk_diff = gitgutter#diff#hunk_diff(bufnr, diff)
+
+      if a:0
+        let hunk_first_line = s:current_hunk()[2]
+        let hunk_diff = s:part_of_diff(hunk_diff, a:1-hunk_first_line, a:2-hunk_first_line)
+      endif
+
+      call a:op(hunk_diff)
     endif
   endif
 endfunction
@@ -221,8 +262,11 @@ function! s:stage(hunk_diff)
   let diff = s:adjust_header(bufnr, a:hunk_diff)
   " Apply patch to index.
   call gitgutter#utility#system(
-        \ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' apply --cached --unidiff-zero - '),
+        \ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' apply --cached --unidiff-zero - '),
         \ diff)
+  if v:shell_error
+    call gitgutter#utility#warn('patch does not apply')
+  endif
 
   " Refresh gitgutter's view of buffer.
   call gitgutter#process_buffer(bufnr, 1)
@@ -240,37 +284,58 @@ function! s:undo(hunk_diff)
   if removed_only
     call append(lnum, lines)
   elseif added_only
-    execute lnum .','. (lnum+len(lines)-1) .'d'
+    execute lnum .','. (lnum+len(lines)-1) .'d _'
   else
     call append(lnum-1, lines[0:hunk[1]])
-    execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d'
+    execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d _'
   endif
 endfunction
 
 
 function! s:preview(hunk_diff)
-  let hunk_lines = split(s:discard_header(a:hunk_diff), "\n")
-  let hunk_lines_length = len(hunk_lines)
-  let previewheight = min([hunk_lines_length, &previewheight])
+  let lines = split(a:hunk_diff, '\n')
+  let header = lines[0:4]
+  let body = lines[5:]
+
+  let body_length = len(body)
+  let previewheight = min([body_length, &previewheight])
 
   silent! wincmd P
   if !&previewwindow
-    noautocmd execute 'bo' previewheight 'new'
+    noautocmd execute g:gitgutter_preview_win_location previewheight 'new'
     set previewwindow
   else
     execute 'resize' previewheight
   endif
 
+  let b:hunk_header = header
+
   setlocal noreadonly modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
   execute "%delete_"
-  call append(0, hunk_lines)
+  call setline(1, body)
   normal! gg
-  setlocal readonly nomodifiable
+
+  cnoreabbrev <buffer> <expr> w  getcmdtype() == ':' && getcmdline() == 'w'  ? 'GitGutterStageHunk' : 'w'
+  " Staging hunk from the preview window closes the window anyway.
+  cnoreabbrev <buffer> <expr> wq getcmdtype() == ':' && getcmdline() == 'wq' ? 'GitGutterStageHunk' : 'wq'
 
   noautocmd wincmd p
 endfunction
 
 
+" Returns a new hunk diff using the specified lines from the given one.
+" Assumes all lines are additions.
+" a:first, a:last - 0-based indexes into the body of the hunk.
+function! s:part_of_diff(hunk_diff, first, last)
+  let diff_lines = split(a:hunk_diff, '\n', 1)
+
+  " adjust 'to' line count in header
+  let diff_lines[4] = substitute(diff_lines[4], '\(+\d\+\)\(,\d\+\)\?', '\=submatch(1).",".(a:last-a:first+1)', '')
+
+  return join(diff_lines[0:4] + diff_lines[5+a:first:5+a:last], "\n")."\n"
+endfunction
+
+
 function! s:adjust_header(bufnr, hunk_diff)
   let filepath = gitgutter#utility#repo_path(a:bufnr, 0)
   return s:adjust_hunk_summary(s:fix_file_references(filepath, a:hunk_diff))
@@ -305,16 +370,11 @@ endif
 function! s:adjust_hunk_summary(hunk_diff) abort
   let line_adjustment = s:line_adjustment_for_current_hunk()
   let diff = split(a:hunk_diff, '\n', 1)
-  let diff[4] = substitute(diff[4], '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '')
+  let diff[4] = substitute(diff[4], '+\zs\(\d\+\)', '\=submatch(1)+line_adjustment', '')
   return join(diff, "\n")
 endfunction
 
 
-function! s:discard_header(hunk_diff)
-  return join(split(a:hunk_diff, '\n', 1)[5:], "\n")
-endfunction
-
-
 " Returns the number of lines the current hunk is offset from where it would
 " be if any changes above it in the file didn't exist.
 function! s:line_adjustment_for_current_hunk() abort
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter/sign.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter/sign.vim
index 4c23dbe0..1ee305a7 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter/sign.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter/sign.vim
@@ -1,11 +1,6 @@
-" Vim doesn't namespace sign ids so every plugin shares the same
-" namespace.  Sign ids are simply integers so to avoid clashes with other
-" signs we guess at a clear run.
-"
-" Note also we currently never reset s:next_sign_id.
+" For older Vims without sign_place() the plugin has to manaage the sign ids.
 let s:first_sign_id = 3000
 let s:next_sign_id  = s:first_sign_id
-let s:dummy_sign_id = s:first_sign_id - 1
 " Remove-all-signs optimisation requires Vim 7.3.596+.
 let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596"))
 
@@ -27,7 +22,6 @@ function! gitgutter#sign#disable() abort
 
   if !g:gitgutter_highlight_lines
     call gitgutter#sign#clear_signs(bufnr(''))
-    call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
   endif
 endfunction
 
@@ -40,8 +34,14 @@ function! gitgutter#sign#toggle() abort
 endfunction
 
 
-" Removes gitgutter's signs (excluding dummy sign) from the buffer being processed.
+" Removes gitgutter's signs from the buffer being processed.
 function! gitgutter#sign#clear_signs(bufnr) abort
+  if exists('*sign_unplace')
+    call sign_unplace('gitgutter', {'buffer': a:bufnr})
+    return
+  endif
+
+
   call s:find_current_signs(a:bufnr)
 
   let sign_ids = map(values(gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')), 'v:val.id')
@@ -55,37 +55,42 @@ endfunction
 " modified_lines: list of [<line_number (number)>, <name (string)>]
 " where name = 'added|removed|modified|modified_removed'
 function! gitgutter#sign#update_signs(bufnr, modified_lines) abort
+  if exists('*sign_unplace')
+    " Vim is (hopefully) now quick enough to remove all signs then place new ones.
+    call sign_unplace('gitgutter', {'buffer': a:bufnr})
+
+    let modified_lines = s:handle_double_hunk(a:modified_lines)
+    let signs = map(copy(modified_lines), '{'.
+          \ '"buffer":   a:bufnr,'.
+          \ '"group":    "gitgutter",'.
+          \ '"name":     s:highlight_name_for_change(v:val[1]),'.
+          \ '"lnum":     v:val[0],'.
+          \ '"priority": g:gitgutter_sign_priority'.
+          \ '}')
+
+    if exists('*sign_placelist')
+      call sign_placelist(signs)
+      return
+    endif
+
+    for sign in signs
+      call sign_place(0, sign.group, sign.name, sign.buffer, {'lnum': sign.lnum, 'priority': sign.priority})
+    endfor
+    return
+  endif
+
+
+  " Derive a delta between the current signs and the ones we want.
+  " Remove signs from lines that no longer need a sign.
+  " Upsert the remaining signs.
+
   call s:find_current_signs(a:bufnr)
 
   let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]')
   let obsolete_signs = s:obsolete_gitgutter_signs_to_remove(a:bufnr, new_gitgutter_signs_line_numbers)
 
-  let flicker_possible = s:remove_all_old_signs && !empty(a:modified_lines)
-  if flicker_possible
-    call s:add_dummy_sign(a:bufnr)
-  endif
-
   call s:remove_signs(a:bufnr, obsolete_signs, s:remove_all_old_signs)
   call s:upsert_new_gitgutter_signs(a:bufnr, a:modified_lines)
-
-  if flicker_possible
-    call gitgutter#sign#remove_dummy_sign(a:bufnr, 0)
-  endif
-endfunction
-
-
-function! s:add_dummy_sign(bufnr) abort
-  if !gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
-    execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
-    call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 1)
-  endif
-endfunction
-
-function! gitgutter#sign#remove_dummy_sign(bufnr, force) abort
-  if gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') && (a:force || !g:gitgutter_sign_column_always)
-    execute "sign unplace" s:dummy_sign_id "buffer=" . a:bufnr
-    call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 0)
-  endif
 endfunction
 
 
@@ -96,40 +101,52 @@ endfunction
 
 function! s:find_current_signs(bufnr) abort
   let gitgutter_signs = {}  " <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}
-  let other_signs = []      " [<line_number (number),...]
-  let dummy_sign_placed = 0
+  if !g:gitgutter_sign_allow_clobber
+    let other_signs = []      " [<line_number (number),...]
+  endif
 
-  redir => signs
-    silent execute "sign place buffer=" . a:bufnr
-  redir END
+  if exists('*getbufinfo')
+    let bufinfo = getbufinfo(a:bufnr)[0]
+    let signs = has_key(bufinfo, 'signs') ? bufinfo.signs : []
+  else
+    let signs = []
 
-  for sign_line in filter(split(signs, '\n')[2:], 'v:val =~# "="')
-    " Typical sign line:  line=88 id=1234 name=GitGutterLineAdded
-    " We assume splitting is faster than a regexp.
-    let components  = split(sign_line)
-    let name        = split(components[2], '=')[1]
-    if name =~# 'GitGutterDummy'
-      let dummy_sign_placed = 1
-    else
-      let line_number = str2nr(split(components[0], '=')[1])
-      if name =~# 'GitGutter'
-        let id = str2nr(split(components[1], '=')[1])
-        " Remove orphaned signs (signs placed on lines which have been deleted).
-        " (When a line is deleted its sign lingers.  Subsequent lines' signs'
-        " line numbers are decremented appropriately.)
-        if has_key(gitgutter_signs, line_number)
-          execute "sign unplace" gitgutter_signs[line_number].id
-        endif
-        let gitgutter_signs[line_number] = {'id': id, 'name': name}
-      else
-        call add(other_signs, line_number)
+    redir => signlines
+      silent execute "sign place buffer=" . a:bufnr
+    redir END
+
+    for signline in filter(split(signlines, '\n')[2:], 'v:val =~# "="')
+      " Typical sign line before v8.1.0614:  line=88 id=1234 name=GitGutterLineAdded
+      " We assume splitting is faster than a regexp.
+      let components = split(signline)
+      call add(signs, {
+            \ 'lnum': str2nr(split(components[0], '=')[1]),
+            \ 'id':   str2nr(split(components[1], '=')[1]),
+            \ 'name':        split(components[2], '=')[1]
+            \ })
+    endfor
+  endif
+
+  for sign in signs
+    if sign.name =~# 'GitGutter'
+      " Remove orphaned signs (signs placed on lines which have been deleted).
+      " (When a line is deleted its sign lingers.  Subsequent lines' signs'
+      " line numbers are decremented appropriately.)
+      if has_key(gitgutter_signs, sign.lnum)
+        execute "sign unplace" gitgutter_signs[sign.lnum].id
       endif
-    end
+      let gitgutter_signs[sign.lnum] = {'id': sign.id, 'name': sign.name}
+    else
+      if !g:gitgutter_sign_allow_clobber
+        call add(other_signs, sign.lnum)
+      endif
+    endif
   endfor
 
-  call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', dummy_sign_placed)
   call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', gitgutter_signs)
-  call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)
+  if !g:gitgutter_sign_allow_clobber
+    call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)
+  endif
 endfunction
 
 
@@ -152,12 +169,8 @@ endfunction
 
 
 function! s:remove_signs(bufnr, sign_ids, all_signs) abort
-  if a:all_signs && s:supports_star && empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs'))
-    let dummy_sign_present = gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
+  if a:all_signs && s:supports_star && (g:gitgutter_sign_allow_clobber || empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs')))
     execute "sign unplace * buffer=" . a:bufnr
-    if dummy_sign_present
-      execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
-    endif
   else
     for id in a:sign_ids
       execute "sign unplace" id
@@ -167,21 +180,16 @@ endfunction
 
 
 function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
-  let other_signs         = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
+  if !g:gitgutter_sign_allow_clobber
+    let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
+  endif
   let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')
 
-  " Handle special case where the first line is the site of two hunks:
-  " lines deleted above at the start of the file, and lines deleted
-  " immediately below.
-  if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]
-    let modified_lines = [[1, 'removed_above_and_below']] + a:modified_lines[2:]
-  else
-    let modified_lines = a:modified_lines
-  endif
+  let modified_lines = s:handle_double_hunk(a:modified_lines)
 
   for line in modified_lines
     let line_number = line[0]  " <number>
-    if index(other_signs, line_number) == -1  " don't clobber others' signs
+    if g:gitgutter_sign_allow_clobber || index(other_signs, line_number) == -1  " don't clobber others' signs
       let name = s:highlight_name_for_change(line[1])
       if !has_key(old_gitgutter_signs, line_number)  " insert
         let id = s:next_sign_id()
@@ -198,6 +206,18 @@ function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
 endfunction
 
 
+" Handle special case where the first line is the site of two hunks:
+" lines deleted above at the start of the file, and lines deleted
+" immediately below.
+function! s:handle_double_hunk(modified_lines)
+  if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]
+    return [[1, 'removed_above_and_below']] + a:modified_lines[2:]
+  endif
+
+  return a:modified_lines
+endfunction
+
+
 function! s:next_sign_id() abort
   let next_id = s:next_sign_id
   let s:next_sign_id += 1
diff --git a/sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim b/sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim
index 470f2229..3f533ba4 100644
--- a/sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim
+++ b/sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim
@@ -22,14 +22,16 @@ function! gitgutter#utility#setbufvar(buffer, varname, val)
 endfunction
 
 function! gitgutter#utility#getbufvar(buffer, varname, ...)
-  let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {})
-  if has_key(dict, a:varname)
-    return dict[a:varname]
-  else
-    if a:0
-      return a:1
+  let bvars = getbufvar(a:buffer, '')
+  if !empty(bvars)
+    let dict = get(bvars, 'gitgutter', {})
+    if has_key(dict, a:varname)
+      return dict[a:varname]
     endif
   endif
+  if a:0
+    return a:1
+  endif
 endfunction
 
 function! gitgutter#utility#warn(message) abort
@@ -114,58 +116,52 @@ function! gitgutter#utility#repo_path(bufnr, shellesc) abort
   return a:shellesc ? gitgutter#utility#shellescape(p) : p
 endfunction
 
-function! gitgutter#utility#set_repo_path(bufnr) abort
+
+let s:set_path_handler = {}
+
+function! s:set_path_handler.out(buffer, path) abort
+  let path = s:strip_trailing_new_line(a:path)
+  call gitgutter#utility#setbufvar(a:buffer, 'path', path)
+
+  if type(self.continuation) == type(function('tr'))
+    call self.continuation()
+  else
+    call call(self.continuation.function, self.continuation.arguments)
+  endif
+endfunction
+
+function! s:set_path_handler.err(buffer) abort
+  call gitgutter#utility#setbufvar(a:buffer, 'path', -2)
+endfunction
+
+
+" continuation - a funcref or hash to call after setting the repo path asynchronously.
+"
+" Returns 'async' if the the path is set asynchronously, 0 otherwise.
+function! gitgutter#utility#set_repo_path(bufnr, continuation) abort
   " Values of path:
   " * non-empty string - path
   " *               -1 - pending
   " *               -2 - not tracked by git
 
   call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)
-  let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
+  let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
 
-  if g:gitgutter_async && gitgutter#async#available()
-    if has('lambda')
-      call gitgutter#async#execute(cmd, a:bufnr, {
-            \   'out': {bufnr, path -> gitgutter#utility#setbufvar(bufnr, 'path', s:strip_trailing_new_line(path))},
-            \   'err': {bufnr       -> gitgutter#utility#setbufvar(bufnr, 'path', -2)},
-            \ })
-    else
-      if has('nvim') && !has('nvim-0.2.0')
-        call gitgutter#async#execute(cmd, a:bufnr, {
-              \   'out': function('s:set_path'),
-              \   'err': function('s:not_tracked_by_git')
-              \ })
-      else
-        call gitgutter#async#execute(cmd, a:bufnr, {
-              \   'out': function('s:set_path'),
-              \   'err': function('s:set_path', [-2])
-              \ })
-      endif
-    endif
+  if g:gitgutter_async && gitgutter#async#available() && !has('vim_starting')
+    let handler = copy(s:set_path_handler)
+    let handler.continuation = a:continuation
+    call gitgutter#async#execute(cmd, a:bufnr, handler)
+    return 'async'
+  endif
+
+  let path = gitgutter#utility#system(cmd)
+  if v:shell_error
+    call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
   else
-    let path = gitgutter#utility#system(cmd)
-    if v:shell_error
-      call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
-    else
-      call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
-    endif
+    call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
   endif
 endfunction
 
-if has('nvim') && !has('nvim-0.2.0')
-  function! s:not_tracked_by_git(bufnr)
-    call s:set_path(a:bufnr, -2)
-  endfunction
-endif
-
-function! s:set_path(bufnr, path)
-  if a:bufnr == -2
-    let [bufnr, path] = [a:path, a:bufnr]
-    call gitgutter#utility#setbufvar(bufnr, 'path', path)
-  else
-    call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(a:path))
-  endif
-endfunction
 
 function! gitgutter#utility#cd_cmd(bufnr, cmd) abort
   let cd = s:unc_path(a:bufnr) ? 'pushd' : (gitgutter#utility#windows() ? 'cd /d' : 'cd')
diff --git a/sources_non_forked/vim-gitgutter/doc/gitgutter.txt b/sources_non_forked/vim-gitgutter/doc/gitgutter.txt
index 87825da1..5dafcbbf 100644
--- a/sources_non_forked/vim-gitgutter/doc/gitgutter.txt
+++ b/sources_non_forked/vim-gitgutter/doc/gitgutter.txt
@@ -79,6 +79,19 @@ Copy vim-gitgutter's subdirectories into your vim configuration directory:
 See |add-global-plugin|.
 
 
+WINDOWS                                                     *gitgutter-windows*
+
+I recommend configuring vim-gitgutter with the full path to your git executable.
+For example:
+>
+    let g:gitgutter_git_executable = 'C:\Program Files\Git\bin\git.exe'
+<
+This is to avoid a problem which occurs if you have file named "git.*" (i.e.
+with any extension in "PATHEXT") in your current folder.  "cmd.exe" prioritises
+the current folder over folders in 'PATH' and will try to execute your file
+instead of the "git" binary.
+
+
 ===============================================================================
 COMMANDS                                                   *gitgutter-commands*
 
@@ -126,6 +139,19 @@ Commands for turning line highlighting on and off (defaults to off):~
 :GitGutterLineHighlightsToggle  Turn line highlighting on or off.
 
 
+Commands for turning line number highlighting on and off (defaults to off):~
+NOTE: This feature requires Neovim 0.3.2 or higher.
+
+                                   *gitgutter-:GitGutterLineNrHighlightsEnable*
+:GitGutterLineNrHighlightsEnable  Turn on line highlighting.
+
+                                  *gitgutter-:GitGutterLineNrHighlightsDisable*
+:GitGutterLineNrHighlightsDisable Turn off line highlighting.
+
+                                   *gitgutter-:GitGutterLineNrHighlightsToggle*
+:GitGutterLineNrHighlightsToggle  Turn line highlighting on or off.
+
+
 Commands for jumping between hunks:~
 
                                                  *gitgutter-:GitGutterNextHunk*
@@ -138,7 +164,14 @@ Commands for jumping between hunks:~
 Commands for operating on a hunk:~
 
                                                 *gitgutter-:GitGutterStageHunk*
-:GitGutterStageHunk     Stage the hunk the cursor is in.
+:GitGutterStageHunk     Stage the hunk the cursor is in.  Use a visual selection
+                        to stage part of an (additions-only) hunk; or use a
+                        range.
+
+                        To stage part of any hunk, first |GitGutterPreviewHunk|
+                        it, then move to the preview window, delete the lines
+                        you do not want to stage, and |write| or
+                        |GitGutterStageHunk|.
 
                                                  *gitgutter-:GitGutterUndoHunk*
 :GitGutterUndoHunk      Undo the hunk the cursor is in.
@@ -148,6 +181,10 @@ Commands for operating on a hunk:~
                         Use |:pclose| or |CTRL-W_CTRL-Z| to close the preview
                         window.
 
+                        To stage part of the hunk, move to the preview window,
+                        delete any lines you do not want to stage, and
+                        |GitGutterStageHunk|.
+
 Commands for folds:~
 
                                                      *gitgutter-:GitGutterFold*
@@ -249,13 +286,15 @@ Signs:~
 
     |g:gitgutter_signs|
     |g:gitgutter_highlight_lines|
+    |g:gitgutter_highlight_linenrs|
     |g:gitgutter_max_signs|
+    |g:gitgutter_sign_priority|
+    |g:gitgutter_sign_allow_clobber|
     |g:gitgutter_sign_added|
     |g:gitgutter_sign_modified|
     |g:gitgutter_sign_removed|
     |g:gitgutter_sign_removed_first_line|
     |g:gitgutter_sign_modified_removed|
-    |g:gitgutter_sign_column_always|
     |g:gitgutter_override_sign_column_highlight|
 
 Terminal:~
@@ -270,6 +309,13 @@ General:~
     |g:gitgutter_log|
 
 
+                                             *g:gitgutter_preview_win_location*
+Default: 'bo'
+
+This option determines where the preview window pops up as a result of the
+:GitGutterPreviewHunk command. Other plausible values are 'to', 'bel', 'abo'.
+See the end of the |opening-window| docs.
+
                                                    *g:gitgutter_git_executable*
 Default: 'git'
 
@@ -329,6 +375,11 @@ Default: 0
 
 Determines whether or not to show line highlights.
 
+                                                *g:gitgutter_highlight_linenrs*
+Default: 0
+
+Determines whether or not to show line number highlights.
+
                                                         *g:gitgutter_max_signs*
 Default: 500
 
@@ -337,6 +388,18 @@ signs, so to avoid slowing down the GUI the number of signs is capped.  When
 the number of changed lines exceeds this value, the plugin removes all signs
 and displays a warning message.
 
+                                                   *g:gitgutter_sign_priority*
+Default: 10
+
+Sets the |sign-priority| gitgutter assigns to its signs.
+
+                                               *g:gitgutter_sign_allow_clobber*
+Default: 0 (Vim < 8.1.0614, Neovim < 0.4.0)
+         1 (otherwise)
+
+Determines whether gitgutter preserves non-gitgutter signs. When 1, gitgutter
+will not preserve non-gitgutter signs.
+
                                           *g:gitgutter_sign_added*
                                           *g:gitgutter_sign_modified*
                                           *g:gitgutter_sign_removed*
@@ -353,17 +416,6 @@ Defaults:
 You can use unicode characters but not images.  Signs must not take up more than
 2 columns.
 
-                                               *g:gitgutter_sign_column_always*
-Default: 0
-
-This legacy option controls whether the sign column should always be shown, even
-if there are no signs to display.
-
-From Vim 7.4.2201, use 'signcolumn' instead:
->
-    set signcolumn=yes
-<
-
                                    *g:gitgutter_override_sign_column_highlight*
 Default: 1
 
@@ -396,6 +448,11 @@ If this applies to you, either install something like Terminus
 (https://github.com/wincent/terminus) to make |FocusGained| work or set this
 option to 0.
 
+If you use tmux, try this in your tmux.conf:
+>
+    set -g focus-events on
+<
+
 When this option is 0, the plugin force-updates the buffer on |BufEnter|
 (instead of only updating if the buffer's contents has changed since the last
 update).
@@ -452,7 +509,19 @@ colorscheme or |vimrc|:
 
 For example, to use |hl-DiffText| instead of |hl-DiffChange|:
 >
-    highlight link GitGutterChangeLine DiffChange
+    highlight link GitGutterChangeLine DiffText
+<
+To change the line number highlights, set up the following highlight groups in
+your colorscheme or |vimrc|:
+>
+    GitGutterAddLineNr          " default: links to CursorLineNr
+    GitGutterChangeLineNr       " default: links to CursorLineNr
+    GitGutterDeleteLineNr       " default: links to CursorLineNr
+    GitGutterChangeDeleteLineNr " default: links to CursorLineNr
+<
+For example, to use |hl-Underlined| instead of |hl-CursorLineNr|:
+>
+    highlight link GitGutterChangeLineNr Underlined
 <
 
 
diff --git a/sources_non_forked/vim-gitgutter/plugin/gitgutter.vim b/sources_non_forked/vim-gitgutter/plugin/gitgutter.vim
index 9ca45afd..0901f0b1 100644
--- a/sources_non_forked/vim-gitgutter/plugin/gitgutter.vim
+++ b/sources_non_forked/vim-gitgutter/plugin/gitgutter.vim
@@ -22,17 +22,19 @@ function! s:set(var, default) abort
   endif
 endfunction
 
+call s:set('g:gitgutter_preview_win_location',     'bo')
 call s:set('g:gitgutter_enabled',                     1)
 call s:set('g:gitgutter_max_signs',                 500)
 call s:set('g:gitgutter_signs',                       1)
 call s:set('g:gitgutter_highlight_lines',             0)
-call s:set('g:gitgutter_sign_column_always',          0)
-if g:gitgutter_sign_column_always && exists('&signcolumn')
-  " Vim 7.4.2201.
-  set signcolumn=yes
-  let g:gitgutter_sign_column_always = 0
-  call gitgutter#utility#warn('please replace "let g:gitgutter_sign_column_always=1" with "set signcolumn=yes"')
+call s:set('g:gitgutter_highlight_linenrs',           0)
+call s:set('g:gitgutter_sign_priority',              10)
+" Nvim 0.4.0 has an expanding sign column
+" The sign_place() function supports sign priority.
+if (has('nvim-0.4.0') || exists('*sign_place')) && !exists('g:gitgutter_sign_allow_clobber')
+  let g:gitgutter_sign_allow_clobber = 1
 endif
+call s:set('g:gitgutter_sign_allow_clobber',          0)
 call s:set('g:gitgutter_override_sign_column_highlight', 1)
 call s:set('g:gitgutter_sign_added',                   '+')
 call s:set('g:gitgutter_sign_modified',                '~')
@@ -111,6 +113,12 @@ command! -bar GitGutterLineHighlightsToggle  call gitgutter#highlight#line_toggl
 
 " }}}
 
+" 'number' column highlights {{{
+command! -bar GitGutterLineNrHighlightsDisable call gitgutter#highlight#linenr_disable()
+command! -bar GitGutterLineNrHighlightsEnable  call gitgutter#highlight#linenr_enable()
+command! -bar GitGutterLineNrHighlightsToggle  call gitgutter#highlight#linenr_toggle()
+" }}}
+
 " Signs {{{
 
 command! -bar GitGutterSignsEnable  call gitgutter#sign#enable()
@@ -124,7 +132,7 @@ command! -bar GitGutterSignsToggle  call gitgutter#sign#toggle()
 command! -bar -count=1 GitGutterNextHunk call gitgutter#hunk#next_hunk(<count>)
 command! -bar -count=1 GitGutterPrevHunk call gitgutter#hunk#prev_hunk(<count>)
 
-command! -bar GitGutterStageHunk   call gitgutter#hunk#stage()
+command! -bar -range=% GitGutterStageHunk call gitgutter#hunk#stage(<line1>,<line2>)
 command! -bar GitGutterUndoHunk    call gitgutter#hunk#undo()
 command! -bar GitGutterPreviewHunk call gitgutter#hunk#preview()
 
@@ -179,6 +187,7 @@ command! -bar GitGutterDebug call gitgutter#debug#debug()
 nnoremap <silent> <expr> <Plug>GitGutterNextHunk &diff ? ']c' : ":\<C-U>execute v:count1 . 'GitGutterNextHunk'\<CR>"
 nnoremap <silent> <expr> <Plug>GitGutterPrevHunk &diff ? '[c' : ":\<C-U>execute v:count1 . 'GitGutterPrevHunk'\<CR>"
 
+xnoremap <silent> <Plug>GitGutterStageHunk   :GitGutterStageHunk<CR>
 nnoremap <silent> <Plug>GitGutterStageHunk   :GitGutterStageHunk<CR>
 nnoremap <silent> <Plug>GitGutterUndoHunk    :GitGutterUndoHunk<CR>
 nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
@@ -186,11 +195,12 @@ nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
 " }}}
 
 function! s:on_bufenter()
+  call gitgutter#setup_maps()
+
   if exists('t:gitgutter_didtabenter') && t:gitgutter_didtabenter
     let t:gitgutter_didtabenter = 0
     call gitgutter#all(!g:gitgutter_terminal_reports_focus)
   else
-    call gitgutter#init_buffer(bufnr(''))
     call gitgutter#process_buffer(bufnr(''), !g:gitgutter_terminal_reports_focus)
   endif
 endfunction
@@ -215,6 +225,11 @@ augroup gitgutter
   autocmd ShellCmdPost * call gitgutter#all(1)
   autocmd BufLeave term://* call gitgutter#all(1)
 
+  autocmd BufWritePost fugitive://*//0/* call gitgutter#all(1)
+
+  autocmd BufFilePre  * GitGutterBufferDisable
+  autocmd BufFilePost * GitGutterBufferEnable
+
   " Handle all buffers when focus is gained, but only after it was lost.
   " FocusGained gets triggered on startup with Neovim at least already.
   " Therefore this tracks also if it was lost before.
diff --git a/sources_non_forked/vim-gitgutter/test/test b/sources_non_forked/vim-gitgutter/test/test
index 4daf052f..cffe9273 100644
--- a/sources_non_forked/vim-gitgutter/test/test
+++ b/sources_non_forked/vim-gitgutter/test/test
@@ -10,7 +10,7 @@ $VIM -u NONE -U NONE -N                      \
   --cmd 'source ../plugin/gitgutter.vim'     \
   -S runner.vim                              \
   test_*.vim                                 \
-  $*
+  "$@"
 
 cat messages.log
 
diff --git a/sources_non_forked/vim-gitgutter/test/test_gitgutter.vim b/sources_non_forked/vim-gitgutter/test/test_gitgutter.vim
index 855eca3d..10ad56ab 100644
--- a/sources_non_forked/vim-gitgutter/test/test_gitgutter.vim
+++ b/sources_non_forked/vim-gitgutter/test/test_gitgutter.vim
@@ -6,21 +6,27 @@ let s:bufnr       = bufnr('')
 " Helpers
 "
 
-function s:signs(filename)
-  redir => signs
-    silent execute 'sign place'
-  redir END
+" Ignores unexpected keys.
+"
+" expected - list of signs
+function s:assert_signs(expected, filename)
+  if empty(a:expected)
+    call assert_equal(a:expected, [])
+    return
+  endif
 
-  let signs = split(signs, '\n')
+  let expected_keys = keys(a:expected[0])
+  let actual = sign_getplaced(a:filename, {'group': 'gitgutter'})[0].signs
 
-  " filter out signs for this test file
-  " assumes a:filename's signs are last set listed
-  let i = index(signs, 'Signs for '.a:filename.':')
-  let signs = (i > -1 ? signs[i+1:] : [])
+  for sign in actual
+    for k in keys(sign)
+      if index(expected_keys, k) == -1
+        call remove(sign, k)
+      endif
+    endfor
+  endfor
 
-  call map(signs, {_, v -> substitute(v, '    ', '', '')})
-
-  return signs
+  call assert_equal(a:expected, actual)
 endfunction
 
 function s:git_diff()
@@ -71,8 +77,8 @@ function Test_add_lines()
   normal ggo*
   call s:trigger_gitgutter()
 
-  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded', 'group': 'gitgutter', 'priority': 10}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -83,8 +89,8 @@ function Test_add_lines_fish()
   normal ggo*
   call s:trigger_gitgutter()
 
-  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]
+  call s:assert_signs(expected, 'fixture.txt')
 
   let &shell = _shell
 endfunction
@@ -94,8 +100,8 @@ function Test_modify_lines()
   normal ggi*
   call s:trigger_gitgutter()
 
-  let expected = ["line=1  id=3000  name=GitGutterLineModified"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 1, 'name': 'GitGutterLineModified'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -103,8 +109,8 @@ function Test_remove_lines()
   execute '5d'
   call s:trigger_gitgutter()
 
-  let expected = ["line=4  id=3000  name=GitGutterLineRemoved"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 4, 'name': 'GitGutterLineRemoved'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -112,8 +118,20 @@ function Test_remove_first_lines()
   execute '1d'
   call s:trigger_gitgutter()
 
-  let expected = ["line=1  id=3000  name=GitGutterLineRemovedFirstLine"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]
+  call s:assert_signs(expected, 'fixture.txt')
+endfunction
+
+
+function Test_priority()
+  let g:gitgutter_sign_priority = 5
+
+  execute '1d'
+  call s:trigger_gitgutter()
+
+  call s:assert_signs([{'priority': 5}], 'fixture.txt')
+
+  let g:gitgutter_sign_priority = 10
 endfunction
 
 
@@ -122,8 +140,8 @@ function Test_overlapping_hunks()
   execute '1d'
   call s:trigger_gitgutter()
 
-  let expected = ["line=1  id=3000  name=GitGutterLineRemovedAboveAndBelow"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedAboveAndBelow'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -132,8 +150,8 @@ function Test_edit_file_with_same_name_as_a_branch()
   call system('git checkout -b fixture.txt')
   call s:trigger_gitgutter()
 
-  let expected = ["line=5  id=3000  name=GitGutterLineModified"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 5, 'name': 'GitGutterLineModified'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -144,8 +162,8 @@ function Test_file_added_to_git()
   normal ihello
   call s:trigger_gitgutter()
 
-  let expected = ["line=1  id=3000  name=GitGutterLineAdded"]
-  call assert_equal(expected, s:signs('fileAddedToGit.tmp'))
+  let expected = [{'lnum': 1, 'name': 'GitGutterLineAdded'}]
+  call s:assert_signs(expected, 'fileAddedToGit.tmp')
 endfunction
 
 
@@ -156,10 +174,10 @@ function Test_filename_with_equals()
   call s:trigger_gitgutter()
 
   let expected = [
-        \ 'line=1  id=3000  name=GitGutterLineAdded',
-        \ 'line=2  id=3001  name=GitGutterLineAdded'
+        \ {'lnum': 1, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 2, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('=fixture=.txt'))
+  call s:assert_signs(expected, '=fixture=.txt')
 endfunction
 
 
@@ -170,10 +188,10 @@ function Test_filename_with_square_brackets()
   call s:trigger_gitgutter()
 
   let expected = [
-        \ 'line=1  id=3000  name=GitGutterLineAdded',
-        \ 'line=2  id=3001  name=GitGutterLineAdded'
+        \ {'lnum': 1, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 2, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('fix[tu]re.txt'))
+  call s:assert_signs(expected, 'fix[tu]re.txt')
 endfunction
 
 
@@ -184,10 +202,10 @@ function Test_filename_leading_dash()
   call s:trigger_gitgutter()
 
   let expected = [
-        \ 'line=1  id=3000  name=GitGutterLineAdded',
-        \ 'line=2  id=3001  name=GitGutterLineAdded'
+        \ {'lnum': 1, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 2, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('-fixture.txt'))
+  call s:assert_signs(expected, '-fixture.txt')
 endfunction
 
 
@@ -198,10 +216,10 @@ function Test_filename_umlaut()
   call s:trigger_gitgutter()
 
   let expected = [
-        \ 'line=1  id=3000  name=GitGutterLineAdded',
-        \ 'line=2  id=3001  name=GitGutterLineAdded'
+        \ {'lnum': 1, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 2, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('fixtüre.txt'))
+  call s:assert_signs(expected, 'fixtüre.txt')
 endfunction
 
 
@@ -213,8 +231,8 @@ function Test_follow_symlink()
   6d
   call s:trigger_gitgutter()
 
-  let expected = ['line=5  id=3000  name=GitGutterLineRemoved']
-  call assert_equal(expected, s:signs('symlink'))
+  let expected = [{'lnum': 5, 'name': 'GitGutterLineRemoved'}]
+  call s:assert_signs(expected, 'symlink')
 endfunction
 
 
@@ -255,7 +273,7 @@ endfunction
 
 
 function Test_no_modifications()
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
 endfunction
 
 
@@ -265,8 +283,8 @@ function Test_orphaned_signs()
   6d
   call s:trigger_gitgutter()
 
-  let expected = ['line=6  id=3001  name=GitGutterLineAdded']
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 6, 'name': 'GitGutterLineAdded'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -275,7 +293,7 @@ function Test_untracked_file_outside_repo()
   call system('touch '.tmp)
   execute 'edit '.tmp
 
-  call assert_equal([], s:signs(tmp))
+  call s:assert_signs([], tmp)
 endfunction
 
 
@@ -286,7 +304,7 @@ function Test_untracked_file_within_repo()
   normal ggo*
   call s:trigger_gitgutter()
 
-  call assert_equal([], s:signs(tmp))
+  call s:assert_signs([], tmp)
   call assert_equal(-2, b:gitgutter.path)
 
   call system('rm '.tmp)
@@ -300,23 +318,23 @@ function Test_untracked_file_square_brackets_within_repo()
   normal ggo*
   call s:trigger_gitgutter()
 
-  call assert_equal([], s:signs(tmp))
+  call s:assert_signs([], tmp)
 
   call system('rm '.tmp)
 endfunction
 
 
 function Test_hunk_outside_noop()
-  normal 5G
+  5
   GitGutterStageHunk
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
   call assert_equal([], s:git_diff())
   call assert_equal([], s:git_diff_staged())
 
   GitGutterUndoHunk
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
   call assert_equal([], s:git_diff())
   call assert_equal([], s:git_diff_staged())
 endfunction
@@ -332,7 +350,7 @@ function Test_hunk_stage()
   call assert_equal('foo', &shell)
   let &shell = _shell
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
 
   " Buffer is unsaved
   let expected = [
@@ -372,11 +390,11 @@ function Test_hunk_stage_nearby_hunk()
   GitGutterStageHunk
 
   let expected = [
-        \ 'line=3  id=3000  name=GitGutterLineAdded',
-        \ 'line=4  id=3001  name=GitGutterLineAdded',
-        \ 'line=5  id=3002  name=GitGutterLineAdded'
+        \ {'lnum': 3, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 4, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 5, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  call s:assert_signs(expected, 'fixture.txt')
 
   " Buffer is unsaved
   let expected = [
@@ -417,6 +435,203 @@ function Test_hunk_stage_nearby_hunk()
 endfunction
 
 
+function Test_hunk_stage_partial_visual_added()
+  call append(5, ['A','B','C','D'])
+  execute "normal 7GVj:GitGutterStageHunk\<CR>"
+
+  let expected = [
+        \ {'lnum': 6, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 9, 'name': 'GitGutterLineAdded'},
+        \ ]
+  call s:assert_signs(expected, 'fixture.txt')
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index 8a7026e..f5c6aff 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -6,2 +5,0 @@ e',
+        \ '-B',
+        \ '-C',
+        \ ]
+  call assert_equal(expected, s:git_diff())
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index f5c6aff..8a7026e 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5,0 +6,2 @@ e',
+        \ '+B',
+        \ '+C',
+        \ ]
+  call assert_equal(expected, s:git_diff_staged())
+endfunction
+
+
+function Test_hunk_stage_partial_cmd_added()
+  call append(5, ['A','B','C','D'])
+  6
+  7,8GitGutterStageHunk
+
+  let expected = [
+        \ {'lnum': 6, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 9, 'name': 'GitGutterLineAdded'},
+        \ ]
+  call s:assert_signs(expected, 'fixture.txt')
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index 8a7026e..f5c6aff 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -6,2 +5,0 @@ e',
+        \ '-B',
+        \ '-C',
+        \ ]
+  call assert_equal(expected, s:git_diff())
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index f5c6aff..8a7026e 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5,0 +6,2 @@ e',
+        \ '+B',
+        \ '+C',
+        \ ]
+  call assert_equal(expected, s:git_diff_staged())
+endfunction
+
+
+function Test_hunk_stage_partial_preview_added()
+  call append(5, ['A','B','C','D'])
+  6
+  GitGutterPreviewHunk
+  wincmd P
+
+  " remove C and A so we stage B and D
+  3delete
+  1delete
+
+  GitGutterStageHunk
+  write
+
+  let expected = [
+        \ {'lnum': 6, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 8, 'name': 'GitGutterLineAdded'},
+        \ ]
+  call s:assert_signs(expected, 'fixture.txt')
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index 975852f..3dd23a3 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5,0 +6 @@ e',
+        \ '+A',
+        \ '@@ -6,0 +8 @@ B',
+        \ '+C',
+        \ ]
+  call assert_equal(expected, s:git_diff())
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index f5c6aff..975852f 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5,0 +6,2 @@ e',
+        \ '+B',
+        \ '+D',
+        \ ]
+  call assert_equal(expected, s:git_diff_staged())
+endfunction
+
+
+function Test_hunk_stage_preview_write()
+  call append(5, ['A','B','C','D'])
+  6
+  GitGutterPreviewHunk
+  wincmd P
+
+  " preview window
+  call feedkeys(":w\<CR>", 'tx')
+  " original window
+  write
+
+  call s:assert_signs([], 'fixture.txt')
+
+  call assert_equal([], s:git_diff())
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index f5c6aff..3dd23a3 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5,0 +6,4 @@ e',
+        \ '+A',
+        \ '+B',
+        \ '+C',
+        \ '+D',
+        \ ]
+  call assert_equal(expected, s:git_diff_staged())
+endfunction
+
+
+function Test_hunk_stage_partial_preview_added_removed()
+  4,5delete
+  call append(3, ['A','B','C','D'])
+  4
+  GitGutterPreviewHunk
+  wincmd P
+
+  " -d
+  " -e
+  " +A
+  " +B
+  " +C
+  " +D
+
+  " remove D and d so they do not get staged
+  6delete
+  1delete
+
+  GitGutterStageHunk
+  write
+
+  let expected = [
+        \ {'lnum': 3, 'name': 'GitGutterLineRemoved'},
+        \ {'lnum': 7, 'name': 'GitGutterLineAdded'},
+        \ ]
+  call s:assert_signs(expected, 'fixture.txt')
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index 9a19589..e63fb0a 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -4 +3,0 @@ c',
+        \ '-d',
+        \ '@@ -7,0 +7 @@ C',
+        \ '+D',
+        \ ]
+  call assert_equal(expected, s:git_diff())
+
+  let expected = [
+        \ 'diff --git a/fixture.txt b/fixture.txt',
+        \ 'index f5c6aff..9a19589 100644',
+        \ '--- a/fixture.txt',
+        \ '+++ b/fixture.txt',
+        \ '@@ -5 +5,3 @@ d',
+        \ '-e',
+        \ '+A',
+        \ '+B',
+        \ '+C',
+        \ ]
+  call assert_equal(expected, s:git_diff_staged())
+endfunction
+
+
 function Test_hunk_undo()
   let _shell = &shell
   set shell=foo
@@ -427,7 +642,7 @@ function Test_hunk_undo()
   call assert_equal('foo', &shell)
   let &shell = _shell
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
   call assert_equal([], s:git_diff())
   call assert_equal([], s:git_diff_staged())
 endfunction
@@ -442,11 +657,11 @@ function Test_undo_nearby_hunk()
   call s:trigger_gitgutter()
 
   let expected = [
-        \ 'line=3  id=3000  name=GitGutterLineAdded',
-        \ 'line=4  id=3001  name=GitGutterLineAdded',
-        \ 'line=5  id=3002  name=GitGutterLineAdded'
+        \ {'lnum': 3, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 4, 'name': 'GitGutterLineAdded'},
+        \ {'lnum': 5, 'name': 'GitGutterLineAdded'}
         \ ]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  call s:assert_signs(expected, 'fixture.txt')
 
   call assert_equal([], s:git_diff())
 
@@ -485,10 +700,8 @@ function Test_overlapping_hunk_op()
   GitGutterUndoHunk
   call s:trigger_gitgutter()
 
-  let expected = [
-        \ 'line=2  id=3000  name=GitGutterLineRemoved',
-        \ ]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 2, 'name': 'GitGutterLineRemoved'}]
+  call s:assert_signs(expected, 'fixture.txt')
 
   " Undo lower
 
@@ -499,10 +712,8 @@ function Test_overlapping_hunk_op()
   GitGutterUndoHunk
   call s:trigger_gitgutter()
 
-  let expected = [
-        \ 'line=1  id=3000  name=GitGutterLineRemovedFirstLine',
-        \ ]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]
+  call s:assert_signs(expected, 'fixture.txt')
 endfunction
 
 
@@ -512,8 +723,8 @@ function Test_write_option()
   normal ggo*
   call s:trigger_gitgutter()
 
-  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
-  call assert_equal(expected, s:signs('fixture.txt'))
+  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]
+  call s:assert_signs(expected, 'fixture.txt')
 
   set write
 endfunction
@@ -525,7 +736,7 @@ function Test_inner_text_object()
   normal dic
   call s:trigger_gitgutter()
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
   call assert_equal(readfile('fixture.txt'), getline(1,'$'))
 
   " Excludes trailing lines
@@ -543,7 +754,7 @@ function Test_around_text_object()
   normal dac
   call s:trigger_gitgutter()
 
-  call assert_equal([], s:signs('fixture.txt'))
+  call s:assert_signs([], 'fixture.txt')
   call assert_equal(readfile('fixture.txt'), getline(1,'$'))
 
   " Includes trailing lines
@@ -646,7 +857,7 @@ function Test_encoding()
 
   call s:trigger_gitgutter()
 
-  call assert_equal([], s:signs('cp932.txt'))
+  call s:assert_signs([], 'cp932.txt')
 endfunction
 
 
@@ -656,7 +867,7 @@ function Test_empty_file()
   edit empty.txt
 
   call s:trigger_gitgutter()
-  call assert_equal([], s:signs('empty.txt'))
+  call s:assert_signs([], 'empty.txt')
 
 
   " File consisting only of a newline
@@ -664,7 +875,7 @@ function Test_empty_file()
   edit newline.txt
 
   call s:trigger_gitgutter()
-  call assert_equal([], s:signs('newline.txt'))
+  call s:assert_signs([], 'newline.txt')
 
 
   " 1 line file without newline
@@ -674,7 +885,7 @@ function Test_empty_file()
   edit! oneline.txt
 
   call s:trigger_gitgutter()
-  call assert_equal([], s:signs('oneline.txt'))
+  call s:assert_signs([], 'oneline.txt')
 
   set eol fixeol
 endfunction
diff --git a/sources_non_forked/vim-go/.github/FUNDING.yml b/sources_non_forked/vim-go/.github/FUNDING.yml
new file mode 100644
index 00000000..060026ef
--- /dev/null
+++ b/sources_non_forked/vim-go/.github/FUNDING.yml
@@ -0,0 +1 @@
+patreon: bhcleek
diff --git a/sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md b/sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md
index b01238f0..7d584256 100644
--- a/sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md
+++ b/sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md
@@ -6,10 +6,8 @@ If possible, please provide clear steps for reproducing the problem.
 
 ### What did you expect to happen?
 
-
 ### What happened instead?
 
-
 ### Configuration (**MUST** fill this out):
 
 #### vim-go version:
@@ -20,10 +18,13 @@ If possible, please provide clear steps for reproducing the problem.
 </pre></details>
 
 #### Vim version (first three lines from `:version`):
+<!-- :version -->
 
-####  Go version (`go version`):
+#### Go version (`go version`):
+<!-- go version -->
 
 #### Go environment
 <details><summary><code>go env</code> Output:</summary><br><pre>
+<!-- go env -->
 
 </pre></details>
diff --git a/sources_non_forked/vim-go/CHANGELOG.md b/sources_non_forked/vim-go/CHANGELOG.md
index 53c72cfd..bb027f7c 100644
--- a/sources_non_forked/vim-go/CHANGELOG.md
+++ b/sources_non_forked/vim-go/CHANGELOG.md
@@ -1,5 +1,9 @@
 ## unplanned
 
+BACKWARDS INCOMPATABILITIES:
+* `g:go_metalinter_disabled` has been removed.
+  [[GH-2375]](https://github.com/fatih/vim-go/pull/2117)
+
 IMPROVEMENTS:
 * Add a new option, `g:go_code_completion_enabled`, to control whether omnifunc
   is set.
@@ -8,6 +12,53 @@ IMPROVEMENTS:
   [[GH-2261]](https://github.com/fatih/vim-go/pull/2261)
 * Allow debugging of packages outside of GOPATH without a go.mod file.
   [[GH-2269]](https://github.com/fatih/vim-go/pull/2269)
+* Show which example failed when Example tests fail
+  [[GH-2277]](https://github.com/fatih/vim-go/pull/2277)
+* Show function signature and return types in preview window when autocompleting functions and methods.
+  [[GH-2289]](https://github.com/fatih/vim-go/pull/2289)
+* Improve the user experience when using null modules.
+  [[GH-2300]](https://github.com/fatih/vim-go/pull/2300)
+* Modify `:GoReportGitHubIssue` to include vim-go configuration values
+  [[GH-2323]](https://github.com/fatih/vim-go/pull/2323)
+* Respect `g:go_info_mode='gopls'` in go#complete#GetInfo.
+  [[GH-2313]](https://github.com/fatih/vim-go/pull/2313)
+* Allow `:GoLint`, `:GoErrCheck`, and `:GoDebug` to work in null modules.
+  [[GH-2335]](https://github.com/fatih/vim-go/pull/2335)
+* Change default value for `g:go_info_mode` and `g:go_def_mode` to `'gopls'`.
+  [[GH-2329]](https://github.com/fatih/vim-go/pull/2329)
+* Add a new option, `g:go_doc_popup_window` to optionally use a popup window
+  for godoc in Vim 8.1.1513 and later.
+  [[GH-2347]](https://github.com/fatih/vim-go/pull/2347)
+* Add `:GoAddWorkspace` function to support multiple workspaces with gopls.
+  [[GH-2356]](https://github.com/fatih/vim-go/pull/2356)
+* Install gopls from its stable package.
+  [[GH-2360]](https://github.com/fatih/vim-go/pull/2360)
+* Disambiguate progress message when initializing gopls.
+  [[GH-2369]](https://github.com/fatih/vim-go/pull/2369)
+* Calculate LSP position correctly when on a line that contains multi-byte
+  characters before the position.
+  [[GH-2389]](https://github.com/fatih/vim-go/pull/2389)
+* Calculate Vim position correctly from LSP text position.
+  [[GH-2395]](https://github.com/fatih/vim-go/pull/2395)
+* Use the statusline to display gopls initialization status messages and only
+  echo the statuses when `g:go_echo_command_info` is set.
+  [[GH-2422]](https://github.com/fatih/vim-go/pull/2422)
+* Send configuration to gopls so that build tags will be considered and hover
+  content won't have documentation.
+  [[GH-2429]](https://github.com/fatih/vim-go/pull/2429)
+* Add a new option, `g:go_term_close_on_exit`, to control whether jobs run in a
+  terminal window will close the terminal window when the job exits.
+  [[GH-2409]](https://github.com/fatih/vim-go/pull/2409)
+* Allow `g:go_template_file` and `g:go_template_test_files` to reside outside
+  of vim-go's template directory.
+  [[GH-2434]](https://github.com/fatih/vim-go/pull/2434)
+* Add a new command, `:GoLSPDebugBrowser`, to open a browser to gopls debugging
+  view.
+  [[GH-2436]](https://github.com/fatih/vim-go/pull/2436)
+* Restart gopls automatically when it is updated via `:GoUpdateBinaries`.
+  [[GH-2453]](https://github.com/fatih/vim-go/pull/2453)
+* Reset `'more'` while installing binaries to avoid unnecessary more prompts.
+  [[GH-2457]](https://github.com/fatih/vim-go/pull/2457)
 
 BUG FIXES:
 * display info about function and function types whose parameters are
@@ -26,6 +77,44 @@ BUG FIXES:
   [[GH-2268]](https://github.com/fatih/vim-go/pull/2268)
 * Set the anchor for method documentation correctly.
   [[GH-2276]](https://github.com/fatih/vim-go/pull/2276)
+* Respect the LSP information for determining where candidate matches start.
+  [[GH-2291]](https://github.com/fatih/vim-go/pull/2291)
+* Restore environment variables with backslashes correctly.
+  [[GH-2292]](https://github.com/fatih/vim-go/pull/2292)
+* Modify handling of gopls output for `:GoInfo` to ensure the value will be
+  displayed.
+  [[GH-2311]](https://github.com/fatih/vim-go/pull/2311)
+* Run `:GoLint` successfully in null modules.
+  [[GH-2318]](https://github.com/fatih/vim-go/pull/2318)
+* Ensure actions on save work in new buffers that have not yet been persisted to disk.
+  [[GH-2319]](https://github.com/fatih/vim-go/pull/2319)
+* Restore population of information in `:GoReportGitHubIssue`.
+  [[GH-2312]](https://github.com/fatih/vim-go/pull/2312)
+* Do not jump back to the originating window when jumping to definitions with
+  `g:go_def_mode='gopls'`.
+  [[GH-2327]](https://github.com/fatih/vim-go/pull/2327)
+* Fix getting information about a valid identifier for which gopls returns no
+  information (e.g. calling `:GoInfo` on a package identifier).
+  [[GH-2339]](https://github.com/fatih/vim-go/pull/2339)
+* Fix tab completion of package names on the cmdline in null modules.
+  [[GH-2342]](https://github.com/fatih/vim-go/pull/2342)
+* Display identifier info correctly when the identifier has no godoc.
+  [[GH-2373]](https://github.com/fatih/vim-go/pull/2373)
+* Fix false positives when saving a buffer and `g:go_metalinter_command` is
+  `golangci-lint`.
+  [[GH-2367]](https://github.com/fatih/vim-go/pull/2367)
+* Fix `:GoDebugRestart`.
+  [[GH-2390]](https://github.com/fatih/vim-go/pull/2390)
+* Do not execute tests twice in terminal mode.
+  [[GH-2397]](https://github.com/fatih/vim-go/pull/2397)
+* Do not open a new buffer in Neovim when there are compilation errors and
+  terminal mode is enabled.
+  [[GH-2401]](https://github.com/fatih/vim-go/pull/2401)
+* Fix error due to typo in implementation of `:GoAddWorkspace`.
+  [[GH-2415]](https://github.com/fatih/vim-go/pull/2401)
+* Do not format the file automatically when `g:go_format_autosave` is set and
+  the file being written is not the current file.
+  [[GH-2442]](https://github.com/fatih/vim-go/pull/2401)
 
 ## 1.20 - (April 22, 2019)
 
diff --git a/sources_non_forked/vim-go/README.md b/sources_non_forked/vim-go/README.md
index c47c8f35..877f9646 100644
--- a/sources_non_forked/vim-go/README.md
+++ b/sources_non_forked/vim-go/README.md
@@ -68,7 +68,16 @@ Depending on your installation method, you may have to generate the plugin's
 [`help tags`](http://vimhelp.appspot.com/helphelp.txt.html#%3Ahelptags)
 manually (e.g. `:helptags ALL`).
 
-We also have an [official vim-go tutorial](https://github.com/fatih/vim-go-tutorial).
+We also have an [official vim-go tutorial](https://github.com/fatih/vim-go/wiki).
+
+## FAQ and troubleshooting
+
+The FAQ and troubleshooting tips are in the documentation and can be quickly
+accessed using `:help go-troubleshooting`. If you believe you've found a bug or
+shortcoming in vim-go that is neither addressed by help nor in [existing
+issues](https://github.com/fatih/vim-go/issues), please open an issue with
+clear reproduction steps. `:GoReportGitHubIssue` can be used pre-populate a lot
+of the information needed when creating a new issue.
 
 ## License
 
diff --git a/sources_non_forked/vim-go/autoload/go/auto.vim b/sources_non_forked/vim-go/autoload/go/auto.vim
index 11748585..620df1cf 100644
--- a/sources_non_forked/vim-go/autoload/go/auto.vim
+++ b/sources_non_forked/vim-go/autoload/go/auto.vim
@@ -33,7 +33,7 @@ function! go#auto#echo_go_info()
 endfunction
 
 function! go#auto#auto_type_info()
-  if !go#config#AutoTypeInfo() || !filereadable(expand('%:p'))
+  if !go#config#AutoTypeInfo() || !isdirectory(expand('%:p:h'))
     return
   endif
 
@@ -42,7 +42,7 @@ function! go#auto#auto_type_info()
 endfunction
 
 function! go#auto#auto_sameids()
-  if !go#config#AutoSameids() || !filereadable(expand('%:p'))
+  if !go#config#AutoSameids() || !isdirectory(expand('%:p:h'))
     return
   endif
 
@@ -51,7 +51,7 @@ function! go#auto#auto_sameids()
 endfunction
 
 function! go#auto#fmt_autosave()
-  if !go#config#FmtAutosave() || !filereadable(expand('%:p'))
+  if !(go#config#FmtAutosave() && isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
     return
   endif
 
@@ -60,7 +60,7 @@ function! go#auto#fmt_autosave()
 endfunction
 
 function! go#auto#metalinter_autosave()
-  if !go#config#MetalinterAutosave() || !filereadable(expand('%:p'))
+  if !go#config#MetalinterAutosave() || !isdirectory(expand('%:p:h'))
     return
   endif
 
@@ -69,7 +69,7 @@ function! go#auto#metalinter_autosave()
 endfunction
 
 function! go#auto#modfmt_autosave()
-  if !go#config#ModFmtAutosave() || !filereadable(expand('%:p'))
+  if !(go#config#ModFmtAutosave() && isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
     return
   endif
 
@@ -78,7 +78,7 @@ function! go#auto#modfmt_autosave()
 endfunction
 
 function! go#auto#asmfmt_autosave()
-  if !go#config#AsmfmtAutosave() || !filereadable(expand('%:p'))
+  if !(go#config#AsmfmtAutosave() && isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
     return
   endif
 
diff --git a/sources_non_forked/vim-go/autoload/go/cmd.vim b/sources_non_forked/vim-go/autoload/go/cmd.vim
index fdf22990..95e6fd31 100644
--- a/sources_non_forked/vim-go/autoload/go/cmd.vim
+++ b/sources_non_forked/vim-go/autoload/go/cmd.vim
@@ -9,8 +9,8 @@ function! go#cmd#autowrite() abort
     for l:nr in range(0, bufnr('$'))
       if buflisted(l:nr) && getbufvar(l:nr, '&modified')
         " Sleep one second to make sure people see the message. Otherwise it is
-        " often immediacy overwritten by the async messages (which also don't
-        " invoke the "hit ENTER" prompt).
+        " often immediately overwritten by the async messages (which also
+        " doesn't invoke the "hit ENTER" prompt).
         call go#util#EchoWarning('[No write since last change]')
         sleep 1
         return
diff --git a/sources_non_forked/vim-go/autoload/go/complete.vim b/sources_non_forked/vim-go/autoload/go/complete.vim
index 072153ea..869cf71b 100644
--- a/sources_non_forked/vim-go/autoload/go/complete.vim
+++ b/sources_non_forked/vim-go/autoload/go/complete.vim
@@ -79,7 +79,12 @@ endfunction
 " go#complete#GoInfo returns the description of the identifier under the
 " cursor.
 function! go#complete#GetInfo() abort
-  return s:sync_info(0)
+  let l:mode = go#config#InfoMode()
+  if l:mode == 'gopls' && go#util#has_job()
+    return go#lsp#GetInfo()
+  else
+    return s:sync_info(0)
+  endif
 endfunction
 
 function! go#complete#Info(showstatus) abort
@@ -216,6 +221,7 @@ function! s:info_complete(echo, result) abort
 endfunction
 
 function! s:trim_bracket(val) abort
+  echom a:val
   let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '')
   return a:val
 endfunction
@@ -240,37 +246,44 @@ function! go#complete#GocodeComplete(findstart, base) abort
   else
     let s = getline(".")[col('.') - 1]
     if s =~ '[(){}\{\}]'
-      return map(copy(s:completions[1]), 's:trim_bracket(v:val)')
+      return map(copy(s:completions), 's:trim_bracket(v:val)')
     endif
     return s:completions
   endif
 endfunction
 
 function! go#complete#Complete(findstart, base) abort
-  let l:state = {'done': 0, 'matches': []}
+  let l:state = {'done': 0, 'matches': [], 'start': -1}
 
-  function! s:handler(state, matches) abort dict
+  function! s:handler(state, start, matches) abort dict
+    let a:state.start = a:start
     let a:state.matches = a:matches
     let a:state.done = 1
   endfunction
 
   "findstart = 1 when we need to get the start of the match
   if a:findstart == 1
-    call go#lsp#Completion(expand('%:p'), line('.'), col('.'), funcref('s:handler', [l:state]))
+    let [l:line, l:col] = getpos('.')[1:2]
+    let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
+    let l:completion = go#lsp#Completion(expand('%:p'), l:line, l:col, funcref('s:handler', [l:state]))
+    if l:completion
+      return -3
+    endif
 
     while !l:state.done
       sleep 10m
     endwhile
 
-    let s:completions = l:state.matches
-
     if len(l:state.matches) == 0
       " no matches. cancel and leave completion mode.
       call go#util#EchoInfo("no matches")
       return -3
     endif
 
-    return col('.')
+    let s:completions = l:state.matches
+
+    return go#lsp#lsp#PositionOf(getline(l:line+1), l:state.start-1)
+
   else "findstart = 0 when we need to return the list of completions
     return s:completions
   endif
diff --git a/sources_non_forked/vim-go/autoload/go/complete_test.vim b/sources_non_forked/vim-go/autoload/go/complete_test.vim
index 43971421..1c9a091f 100644
--- a/sources_non_forked/vim-go/autoload/go/complete_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/complete_test.vim
@@ -2,23 +2,33 @@
 let s:cpo_save = &cpo
 set cpo&vim
 
-func! Test_GetInfo()
+func! Test_GetInfo_gocode()
+    let g:go_info_mode = 'gocode'
+    call s:getinfo()
+    unlet g:go_info_mode
+endfunction
+
+func! Test_GetInfo_guru()
+    let g:go_info_mode = 'guru'
+    call s:getinfo()
+    unlet g:go_info_mode
+endfunction
+
+func! Test_GetInfo_gopls()
+    let g:go_info_mode = 'gopls'
+    call s:getinfo()
+    unlet g:go_info_mode
+endfunction
+
+func! s:getinfo()
     let l:filename = 'complete/complete.go'
     let l:tmp = gotest#load_fixture(l:filename)
 
     call cursor(8, 3)
 
-    let g:go_info_mode = 'gocode'
     let expected = 'func Example(s string)'
     let actual = go#complete#GetInfo()
     call assert_equal(expected, actual)
-
-    let g:go_info_mode = 'guru'
-    call go#config#InfoMode()
-    let actual = go#complete#GetInfo()
-    call assert_equal(expected, actual)
-
-    unlet g:go_info_mode
 endfunction
 
 " restore Vi compatibility settings
diff --git a/sources_non_forked/vim-go/autoload/go/config.vim b/sources_non_forked/vim-go/autoload/go/config.vim
index b325c29e..5c035693 100644
--- a/sources_non_forked/vim-go/autoload/go/config.vim
+++ b/sources_non_forked/vim-go/autoload/go/config.vim
@@ -21,10 +21,12 @@ endfunction
 function! go#config#SetBuildTags(value) abort
   if a:value is ''
     silent! unlet g:go_build_tags
+    call go#lsp#ResetWorkspaceDirectories()
     return
   endif
 
   let g:go_build_tags = a:value
+  call go#lsp#ResetWorkspaceDirectories()
 endfunction
 
 function! go#config#TestTimeout() abort
@@ -47,6 +49,14 @@ function! go#config#TermMode() abort
   return get(g:, 'go_term_mode', 'vsplit')
 endfunction
 
+function! go#config#TermCloseOnExit() abort
+  return get(g:, 'go_term_close_on_exit', 1)
+endfunction
+
+function! go#config#SetTermCloseOnExit(value) abort
+  let g:go_term_close_on_exit = a:value
+endfunction
+
 function! go#config#TermEnabled() abort
   return has('nvim') && get(g:, 'go_term_enabled', 0)
 endfunction
@@ -114,7 +124,7 @@ function! go#config#ListAutoclose() abort
 endfunction
 
 function! go#config#InfoMode() abort
-  return get(g:, 'go_info_mode', 'gocode')
+  return get(g:, 'go_info_mode', 'gopls')
 endfunction
 
 function! go#config#GuruScope() abort
@@ -174,12 +184,15 @@ function! go#config#DocUrl() abort
   return godoc_url
 endfunction
 
+function! go#config#DocPopupWindow() abort
+  return get(g:, 'go_doc_popup_window', 0)
+endfunction
 function! go#config#DefReuseBuffer() abort
   return get(g:, 'go_def_reuse_buffer', 0)
 endfunction
 
 function! go#config#DefMode() abort
-  return get(g:, 'go_def_mode', 'guru')
+  return get(g:, 'go_def_mode', 'gopls')
 endfunction
 
 function! go#config#DeclsIncludes() abort
@@ -268,10 +281,6 @@ function! go#config#MetalinterEnabled() abort
   return get(g:, "go_metalinter_enabled", default_enabled)
 endfunction
 
-function! go#config#MetalinterDisabled() abort
-  return get(g:, "go_metalinter_disabled", [])
-endfunction
-
 function! go#config#GolintBin() abort
   return get(g:, "go_golint_bin", "golint")
 endfunction
diff --git a/sources_non_forked/vim-go/autoload/go/debug.vim b/sources_non_forked/vim-go/autoload/go/debug.vim
index e2d0b9fa..bb14cf0a 100644
--- a/sources_non_forked/vim-go/autoload/go/debug.vim
+++ b/sources_non_forked/vim-go/autoload/go/debug.vim
@@ -576,7 +576,7 @@ function! go#debug#Start(is_test, ...) abort
     return s:state['job']
   endif
 
-  let s:start_args = a:000
+  let s:start_args = [a:is_test] + a:000
 
   if go#util#HasDebug('debugger-state')
     call go#config#SetDebugDiag(s:state)
@@ -595,10 +595,23 @@ function! go#debug#Start(is_test, ...) abort
 
     " append the package when it's given.
     if len(a:000) > 0
-      let l:pkgname = go#package#FromPath(a:1)
-      if l:pkgname is -1
-        call go#util#EchoError('could not determine package name')
-        return
+      let l:pkgname = a:1
+      if l:pkgname[0] == '.'
+        let l:pkgabspath = fnamemodify(l:pkgname, ':p')
+
+        let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
+        let l:dir = getcwd()
+        execute l:cd fnameescape(expand('%:p:h'))
+
+        try
+          let l:pkgname = go#package#FromPath(l:pkgabspath)
+          if type(l:pkgname) == type(0)
+            call go#util#EchoError('could not determine package name')
+            return
+          endif
+        finally
+          execute l:cd fnameescape(l:dir)
+        endtry
       endif
 
       let l:cmd += [l:pkgname]
diff --git a/sources_non_forked/vim-go/autoload/go/debug_test.vim b/sources_non_forked/vim-go/autoload/go/debug_test.vim
index f5572e51..b9aeb2a8 100644
--- a/sources_non_forked/vim-go/autoload/go/debug_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/debug_test.vim
@@ -10,6 +10,10 @@ function! Test_GoDebugStart_RelativePackage() abort
   call s:debug('./debug/debugmain')
 endfunction
 
+function! Test_GoDebugStart_RelativePackage_NullModule() abort
+  call s:debug('./debug/debugmain', 1)
+endfunction
+
 function! Test_GoDebugStart_Package() abort
   call s:debug('debug/debugmain')
 endfunction
@@ -52,14 +56,22 @@ function! Test_GoDebugStart_Errors() abort
   endtry
 endfunction
 
+" s:debug takes 2 optional arguments. The first is a package to debug. The
+" second is a flag to indicate whether to reset GOPATH after
+" gotest#load_fixture is called in order to test behavior outside of GOPATH.
 function! s:debug(...) abort
   if !go#util#has_job()
     return
   endif
 
   try
+    let $oldgopath = $GOPATH
     let l:tmp = gotest#load_fixture('debug/debugmain/debugmain.go')
 
+    if a:0 > 1 && a:2 == 1
+      let $GOPATH = $oldgopath
+    endif
+
     call go#debug#Breakpoint(6)
 
     call assert_false(exists(':GoDebugStop'))
diff --git a/sources_non_forked/vim-go/autoload/go/def.vim b/sources_non_forked/vim-go/autoload/go/def.vim
index 5fa11414..becd7bb5 100644
--- a/sources_non_forked/vim-go/autoload/go/def.vim
+++ b/sources_non_forked/vim-go/autoload/go/def.vim
@@ -6,7 +6,7 @@ let s:go_stack = []
 let s:go_stack_level = 0
 
 function! go#def#Jump(mode, type) abort
-  let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
+  let l:fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
 
   " so guru right now is slow for some people. previously we were using
   " godef which also has it's own quirks. But this issue come up so many
@@ -66,7 +66,7 @@ function! go#def#Jump(mode, type) abort
       let [l:out, l:err] = go#util#ExecInDir(l:cmd)
     endif
   elseif bin_name == 'gopls'
-    let [l:line, l:col] = getpos('.')[1:2]
+    let [l:line, l:col] = go#lsp#lsp#Position()
     " delegate to gopls, with an empty job object and an exit status of 0
     " (they're irrelevant for gopls).
     if a:type
diff --git a/sources_non_forked/vim-go/autoload/go/def_test.vim b/sources_non_forked/vim-go/autoload/go/def_test.vim
index a054471c..6a855417 100644
--- a/sources_non_forked/vim-go/autoload/go/def_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/def_test.vim
@@ -2,19 +2,21 @@
 let s:cpo_save = &cpo
 set cpo&vim
 
+scriptencoding utf-8
+
 func! Test_jump_to_declaration_guru() abort
   try
     let l:filename = 'def/jump.go'
-    let lnum = 5
-    let col = 6
+    let l:lnum = 5
+    let l:col = 6
     let l:tmp = gotest#load_fixture(l:filename)
 
-    let guru_out = printf("%s:%d:%d: defined here as func main", filename, lnum, col)
-    call go#def#jump_to_declaration(guru_out, "", 'guru')
+    let l:guru_out = printf("%s:%d:%d: defined here as func main", l:filename, l:lnum, l:col)
+    call go#def#jump_to_declaration(l:guru_out, "", 'guru')
 
-    call assert_equal(filename, bufname("%"))
-    call assert_equal(lnum, getcurpos()[1])
-    call assert_equal(col, getcurpos()[2])
+    call assert_equal(l:filename, bufname("%"))
+    call assert_equal(l:lnum, getcurpos()[1])
+    call assert_equal(l:col, getcurpos()[2])
   finally
     call delete(l:tmp, 'rf')
   endtry
@@ -22,17 +24,17 @@ endfunc
 
 func! Test_jump_to_declaration_godef() abort
   try
-    let filename = 'def/jump.go'
-    let lnum = 5
-    let col = 6
+    let l:filename = 'def/jump.go'
+    let l:lnum = 5
+    let l:col = 6
     let l:tmp = gotest#load_fixture(l:filename)
 
-    let godef_out = printf("%s:%d:%d\ndefined here as func main", filename, lnum, col)
+    let l:godef_out = printf("%s:%d:%d\ndefined here as func main", l:filename, l:lnum, l:col)
     call go#def#jump_to_declaration(godef_out, "", 'godef')
 
-    call assert_equal(filename, bufname("%"))
-    call assert_equal(lnum, getcurpos()[1])
-    call assert_equal(col, getcurpos()[2])
+    call assert_equal(l:filename, bufname("%"))
+    call assert_equal(l:lnum, getcurpos()[1])
+    call assert_equal(l:col, getcurpos()[2])
   finally
     call delete(l:tmp, 'rf')
   endtry
@@ -40,33 +42,180 @@ endfunc
 
 func! Test_Jump_leaves_lists() abort
   try
-    let filename = 'def/jump.go'
+    let l:filename = 'def/jump.go'
     let l:tmp = gotest#load_fixture(l:filename)
 
-    let expected = [{'lnum': 10, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'quux'}]
+    let l:expected = [{'lnum': 10, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'quux'}]
 
-    call setloclist(winnr(), copy(expected), 'r' )
-    call setqflist(copy(expected), 'r' )
+    call setloclist(winnr(), copy(l:expected), 'r' )
+    call setqflist(copy(l:expected), 'r' )
 
     let l:bufnr = bufnr('%')
     call cursor(6, 7)
+   
+    if !go#util#has_job()
+      let g:go_def_mode='godef'
+    endif
     call go#def#Jump('', 0)
 
-    let start = reltime()
-    while bufnr('%') == l:bufnr && reltimefloat(reltime(start)) < 10
+    if !go#util#has_job()
+      unlet g:go_def_mode
+    endif
+
+    let l:start = reltime()
+    while bufnr('%') == l:bufnr && reltimefloat(reltime(l:start)) < 10
       sleep 100m
     endwhile
 
-    let actual = getloclist(winnr())
-    call gotest#assert_quickfix(actual, expected)
+    let l:actual = getloclist(winnr())
+    call gotest#assert_quickfix(l:actual, l:expected)
 
-    let actual = getqflist()
-    call gotest#assert_quickfix(actual, expected)
+    let l:actual = getqflist()
+    call gotest#assert_quickfix(l:actual, l:expected)
   finally
     call delete(l:tmp, 'rf')
   endtry
 endfunc
 
+func! Test_DefJump_gopls_simple_first() abort
+  if !go#util#has_job()
+    return
+  endif
+
+  try
+    let g:go_def_mode = 'gopls'
+
+    let l:tmp = gotest#write_file('simple/firstposition/firstposition.go', [
+          \ 'package firstposition',
+          \ '',
+          \ 'func Example() {',
+          \ "\tid := " . '"foo"',
+          \ "\tprintln(" . '"id:", id)',
+          \ '}',
+          \ ] )
+
+    let l:expected = [0, 4, 2, 0]
+
+    call assert_notequal(l:expected, getpos('.'))
+
+    call go#def#Jump('', 0)
+
+    let l:start = reltime()
+    while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
+      sleep 100m
+    endwhile
+
+    call assert_equal(l:expected, getpos('.'))
+  finally
+    call delete(l:tmp, 'rf')
+    unlet g:go_def_mode
+  endtry
+endfunc
+
+func! Test_DefJump_gopls_simple_last() abort
+  if !go#util#has_job()
+    return
+  endif
+
+  try
+    let g:go_def_mode = 'gopls'
+
+    let l:tmp = gotest#write_file('simple/lastposition/lastposition.go', [
+          \ 'package lastposition',
+          \ '',
+          \ 'func Example() {',
+          \ "\tid := " . '"foo"',
+          \ "\tprintln(" . '"id:", id)',
+          \ '}',
+          \ ] )
+
+    let l:expected = [0, 4, 2, 0]
+
+    call assert_notequal(l:expected, getpos('.'))
+
+    call go#def#Jump('', 0)
+
+    let l:start = reltime()
+    while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
+      sleep 100m
+    endwhile
+
+    call assert_equal(l:expected, getpos('.'))
+  finally
+    call delete(l:tmp, 'rf')
+    unlet g:go_def_mode
+  endtry
+endfunc
+
+func! Test_DefJump_gopls_MultipleCodeUnit_first() abort
+  if !go#util#has_job()
+    return
+  endif
+
+  try
+    let g:go_def_mode = 'gopls'
+
+    let l:tmp = gotest#write_file('multiplecodeunit/firstposition/firstposition.go', [
+          \ 'package firstposition',
+          \ '',
+          \ 'func Example() {',
+          \ "\t𐐀, id := " . '"foo", "bar"',
+          \ "\tprintln(" . '"(𐐀, id):", 𐐀, id)',
+          \ '}',
+          \ ] )
+
+    let l:expected = [0, 4, 8, 0]
+    call assert_notequal(l:expected, getpos('.'))
+
+    call go#def#Jump('', 0)
+
+    let l:start = reltime()
+    while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
+      sleep 100m
+    endwhile
+
+    call assert_equal(l:expected, getpos('.'))
+  finally
+    call delete(l:tmp, 'rf')
+    unlet g:go_def_mode
+  endtry
+endfunc
+
+
+func! Test_DefJump_gopls_MultipleCodeUnit_last() abort
+  if !go#util#has_job()
+    return
+  endif
+
+  try
+    let g:go_def_mode = 'gopls'
+
+    let l:tmp = gotest#write_file('multiplecodeunit/lastposition/lastposition.go', [
+          \ 'package lastposition',
+          \ '',
+          \ 'func Example() {',
+          \ "\t𐐀, id := " . '"foo", "bar"',
+          \ "\tprintln(" . '"(𐐀, id):", 𐐀, id)',
+          \ '}',
+          \ ] )
+
+    let l:expected = [0, 4, 8, 0]
+    call assert_notequal(l:expected, getpos('.'))
+
+    call go#def#Jump('', 0)
+
+    let l:start = reltime()
+    while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
+      sleep 100m
+    endwhile
+
+    call assert_equal(l:expected, getpos('.'))
+  finally
+    call delete(l:tmp, 'rf')
+    unlet g:go_def_mode
+  endtry
+endfunc
+
 " restore Vi compatibility settings
 let &cpo = s:cpo_save
 unlet s:cpo_save
diff --git a/sources_non_forked/vim-go/autoload/go/doc.vim b/sources_non_forked/vim-go/autoload/go/doc.vim
index 3960a1be..cf2493ea 100644
--- a/sources_non_forked/vim-go/autoload/go/doc.vim
+++ b/sources_non_forked/vim-go/autoload/go/doc.vim
@@ -76,6 +76,18 @@ function! go#doc#Open(newmode, mode, ...) abort
 endfunction
 
 function! s:GodocView(newposition, position, content) abort
+  " popup window
+  if go#config#DocPopupWindow() && exists('*popup_atcursor') && exists('*popup_clear')
+    call popup_clear()
+
+    call popup_atcursor(split(a:content, '\n'), {
+          \ 'padding': [1, 1, 1, 1],
+          \ 'borderchars': ['-','|','-','|','+','+','+','+'],
+          \ "border": [1, 1, 1, 1],
+          \ })
+    return
+  endif
+
   " reuse existing buffer window if it exists otherwise create a new one
   let is_visible = bufexists(s:buf_nr) && bufwinnr(s:buf_nr) != -1
   if !bufexists(s:buf_nr)
diff --git a/sources_non_forked/vim-go/autoload/go/issue.vim b/sources_non_forked/vim-go/autoload/go/issue.vim
index 65db9d80..c76df7f4 100644
--- a/sources_non_forked/vim-go/autoload/go/issue.vim
+++ b/sources_non_forked/vim-go/autoload/go/issue.vim
@@ -18,20 +18,30 @@ function! s:issuebody() abort
   for l in lines
     let body = add(body, l)
 
-    if l =~ '^\* Vim version'
+    if l =~ '^<!-- :version'
       redir => out
         silent version
       redir END
       let body = extend(body, split(out, "\n")[0:2])
-    elseif l =~ '^\* Go version'
+    elseif l =~ '^<!-- go version -->'
       let [out, err] = go#util#Exec(['go', 'version'])
       let body = add(body, substitute(l:out, rtrimpat, '', ''))
-    elseif l =~ '^\* Go environment'
+    elseif l =~ '^<!-- go env -->'
       let [out, err] = go#util#Exec(['go', 'env'])
       let body = add(body, substitute(l:out, rtrimpat, '', ''))
     endif
   endfor
 
+  let body = add(body, "#### vim-go configuration:\n<details><summary>vim-go configuration</summary><br><pre>")
+
+  for k in keys(g:)
+    if k =~ '^go_'
+      let body = add(body, 'g:' . k . ' = ' . string(get(g:, k)))
+    endif
+  endfor
+
+  let body = add(body, '</pre></details>')
+
   return join(body, "\n")
 endfunction
 
diff --git a/sources_non_forked/vim-go/autoload/go/lint.vim b/sources_non_forked/vim-go/autoload/go/lint.vim
index d56f3da8..322cc674 100644
--- a/sources_non_forked/vim-go/autoload/go/lint.vim
+++ b/sources_non_forked/vim-go/autoload/go/lint.vim
@@ -22,10 +22,6 @@ function! go#lint#Gometa(bang, autosave, ...) abort
     for linter in linters
       let cmd += ["--enable=".linter]
     endfor
-
-    for linter in go#config#MetalinterDisabled()
-      let cmd += ["--disable=".linter]
-    endfor
   else
     " the user wants something else, let us use it.
     let cmd = split(go#config#MetalinterCommand(), " ")
@@ -44,7 +40,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
       endif
       let cmd += include
     elseif l:metalinter == "golangci-lint"
-      let goargs[0] = expand('%:p')
+      let goargs[0] = expand('%:p:h')
     endif
   endif
 
@@ -88,7 +84,13 @@ function! go#lint#Gometa(bang, autosave, ...) abort
   else
     let l:winid = win_getid(winnr())
     " Parse and populate our location list
-    call go#list#ParseFormat(l:listtype, errformat, split(out, "\n"), 'GoMetaLinter')
+
+    let l:messages = split(out, "\n")
+
+    if a:autosave
+      call s:metalinterautosavecomplete(fnamemodify(expand('%:p'), ":."), 0, 1, l:messages)
+    endif
+    call go#list#ParseFormat(l:listtype, errformat, l:messages, 'GoMetaLinter')
 
     let errors = go#list#Get(l:listtype)
     call go#list#Window(l:listtype, len(errors))
@@ -105,7 +107,7 @@ endfunction
 " the location list
 function! go#lint#Golint(bang, ...) abort
   if a:0 == 0
-    let [l:out, l:err] = go#util#Exec([go#config#GolintBin(), go#package#ImportPath()])
+    let [l:out, l:err] = go#util#Exec([go#config#GolintBin(), expand('%:p:h')])
   else
     let [l:out, l:err] = go#util#Exec([go#config#GolintBin()] + a:000)
   endif
@@ -141,7 +143,7 @@ function! go#lint#Vet(bang, ...) abort
   if a:0 == 0
     let [l:out, l:err] = go#util#Exec(['go', 'vet', go#package#ImportPath()])
   else
-    let [l:out, l:err] = go#util#Exec(['go', 'tool', 'vet'] + a:000)
+    let [l:out, l:err] = go#util#ExecInDir(['go', 'tool', 'vet'] + a:000)
   endif
 
   let l:listtype = go#list#Type("GoVet")
@@ -230,6 +232,7 @@ function! s:lint_job(args, bang, autosave)
 
   if a:autosave
     let l:opts.for = "GoMetaLinterAutoSave"
+    let l:opts.complete = funcref('s:metalinterautosavecomplete', [expand('%:p:t')])
   endif
 
   " autowrite is not enabled for jobs
@@ -279,6 +282,21 @@ function! s:golangcilintcmd(bin_path)
   return cmd
 endfunction
 
+function! s:metalinterautosavecomplete(filepath, job, exit_code, messages)
+  if len(a:messages) == 0
+    return
+  endif
+
+  let l:file = expand('%:p:t')
+  let l:idx = len(a:messages) - 1
+  while l:idx >= 0
+    if a:messages[l:idx] !~# '^' . a:filepath . ':'
+      call remove(a:messages, l:idx)
+    endif
+    let l:idx -= 1
+  endwhile
+endfunction
+
 " restore Vi compatibility settings
 let &cpo = s:cpo_save
 unlet s:cpo_save
diff --git a/sources_non_forked/vim-go/autoload/go/lint_test.vim b/sources_non_forked/vim-go/autoload/go/lint_test.vim
index dccc138a..e75b0595 100644
--- a/sources_non_forked/vim-go/autoload/go/lint_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/lint_test.vim
@@ -3,7 +3,7 @@ let s:cpo_save = &cpo
 set cpo&vim
 
 func! Test_Gometa() abort
-  call s:gometa('gometaliner')
+  call s:gometa('gometalinter')
 endfunc
 
 func! Test_GometaGolangciLint() abort
@@ -11,14 +11,19 @@ func! Test_GometaGolangciLint() abort
 endfunc
 
 func! s:gometa(metalinter) abort
-  let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
+  let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
   silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
 
   try
-    let g:go_metalinter_comand = a:metalinter
+    let g:go_metalinter_command = a:metalinter
     let expected = [
           \ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingFooDoc should have comment or be unexported (golint)'}
         \ ]
+    if a:metalinter == 'golangci-lint'
+      let expected = [
+            \ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function `MissingFooDoc` should have comment or be unexported (golint)'}
+          \ ]
+    endif
 
     " clear the quickfix lists
     call setqflist([], 'r')
@@ -36,48 +41,11 @@ func! s:gometa(metalinter) abort
 
     call gotest#assert_quickfix(actual, expected)
   finally
+      call call(RestoreGOPATH, [])
       unlet g:go_metalinter_enabled
   endtry
 endfunc
 
-func! Test_GometaWithDisabled() abort
-  call s:gometawithdisabled('gometalinter')
-endfunc
-
-func! Test_GometaWithDisabledGolangciLint() abort
-  call s:gometawithdisabled('golangci-lint')
-endfunc
-
-func! s:gometawithdisabled(metalinter) abort
-  let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
-  silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
-
-  try
-    let g:go_metalinter_comand = a:metalinter
-    let expected = [
-          \ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingFooDoc should have comment or be unexported (golint)'}
-        \ ]
-
-    " clear the quickfix lists
-    call setqflist([], 'r')
-
-    let g:go_metalinter_disabled = ['vet']
-
-    call go#lint#Gometa(0, 0, $GOPATH . '/src/foo')
-
-    let actual = getqflist()
-    let start = reltime()
-    while len(actual) == 0 && reltimefloat(reltime(start)) < 10
-      sleep 100m
-      let actual = getqflist()
-    endwhile
-
-    call gotest#assert_quickfix(actual, expected)
-  finally
-    unlet g:go_metalinter_disabled
-  endtry
-endfunc
-
 func! Test_GometaAutoSave() abort
   call s:gometaautosave('gometalinter')
 endfunc
@@ -87,14 +55,19 @@ func! Test_GometaAutoSaveGolangciLint() abort
 endfunc
 
 func! s:gometaautosave(metalinter) abort
-  let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
+  let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')
   silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
 
   try
-    let g:go_metalinter_comand = a:metalinter
+    let g:go_metalinter_command = a:metalinter
     let expected = [
           \ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported (golint)'}
         \ ]
+    if a:metalinter == 'golangci-lint'
+      let expected = [
+            \ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function `MissingDoc` should have comment or be unexported (golint)'}
+          \ ]
+    endif
 
     let winnr = winnr()
 
@@ -114,18 +87,50 @@ func! s:gometaautosave(metalinter) abort
 
     call gotest#assert_quickfix(actual, expected)
   finally
+    call call(RestoreGOPATH, [])
     unlet g:go_metalinter_autosave_enabled
   endtry
 endfunc
 
 func! Test_Vet() abort
-  let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
-  silent exe 'e ' . $GOPATH . '/src/vet/vet.go'
+  let l:tmp = gotest#load_fixture('lint/src/vet/vet.go')
+
+  try
+
+    let expected = [
+          \ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '',
+          \ 'text': 'Printf format %d has arg str of wrong type string'}
+        \ ]
+
+    let winnr = winnr()
+
+    " clear the location lists
+    call setqflist([], 'r')
+
+    call go#lint#Vet(1)
+
+    let actual = getqflist()
+    let start = reltime()
+    while len(actual) == 0 && reltimefloat(reltime(start)) < 10
+      sleep 100m
+      let actual = getqflist()
+    endwhile
+
+    call gotest#assert_quickfix(actual, expected)
+  finally
+    call delete(l:tmp, 'rf')
+  endtry
+endfunc
+
+func! Test_Lint_GOPATH() abort
+  let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')
+
+  silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
   compiler go
 
   let expected = [
-        \ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '',
-        \ 'text': 'Printf format %d has arg str of wrong type string'}
+          \ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported'},
+          \ {'lnum': 5, 'bufnr': 6, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function AlsoMissingDoc should have comment or be unexported'}
       \ ]
 
   let winnr = winnr()
@@ -133,7 +138,35 @@ func! Test_Vet() abort
   " clear the location lists
   call setqflist([], 'r')
 
-  call go#lint#Vet(1)
+  call go#lint#Golint(1)
+
+  let actual = getqflist()
+  let start = reltime()
+  while len(actual) == 0 && reltimefloat(reltime(start)) < 10
+    sleep 100m
+    let actual = getqflist()
+  endwhile
+
+  call gotest#assert_quickfix(actual, expected)
+
+  call call(RestoreGOPATH, [])
+endfunc
+
+func! Test_Lint_NullModule() abort
+  silent exe 'e ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint/src/lint/lint.go'
+  compiler go
+
+  let expected = [
+          \ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported'},
+          \ {'lnum': 5, 'bufnr': 6, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function AlsoMissingDoc should have comment or be unexported'}
+      \ ]
+
+  let winnr = winnr()
+
+  " clear the location lists
+  call setqflist([], 'r')
+
+  call go#lint#Golint(1)
 
   let actual = getqflist()
   let start = reltime()
diff --git a/sources_non_forked/vim-go/autoload/go/lsp.vim b/sources_non_forked/vim-go/autoload/go/lsp.vim
index 47205759..bb41a7d8 100644
--- a/sources_non_forked/vim-go/autoload/go/lsp.vim
+++ b/sources_non_forked/vim-go/autoload/go/lsp.vim
@@ -7,7 +7,7 @@ scriptencoding utf-8
 let s:lspfactory = {}
 
 function! s:lspfactory.get() dict abort
-  if !has_key(self, 'current') || empty(self.current)
+  if empty(get(self, 'current', {})) || empty(get(self.current, 'job', {}))
     let self.current = s:newlsp()
   endif
 
@@ -22,9 +22,16 @@ endfunction
 
 function! s:newlsp() abort
   if !go#util#has_job()
-    " TODO(bc): start the server in the background using a shell that waits for the right output before returning.
-    call go#util#EchoError('This feature requires either Vim 8.0.0087 or newer with +job or Neovim.')
-    return
+    let l:oldshortmess=&shortmess
+    if has('nvim')
+      set shortmess-=F
+    endif
+    call go#util#EchoWarning('Features that rely on gopls will not work without either Vim 8.0.0087 or newer with +job or Neovim')
+    " Sleep one second to make sure people see the message. Otherwise it is
+    " often immediately overwritten by an async message.
+    sleep 1
+    let &shortmess=l:oldshortmess
+    return {'sendMessage': funcref('s:noop')}
   endif
 
   " job is the job used to talk to the backing instance of gopls.
@@ -47,6 +54,8 @@ function! s:newlsp() abort
         \ 'last_request_id': 0,
         \ 'buf': '',
         \ 'handlers': {},
+        \ 'workspaceDirectories': [],
+        \ 'wd' : '',
         \ }
 
   function! l:lsp.readMessage(data) dict abort
@@ -75,19 +84,17 @@ function! s:newlsp() abort
       endif
 
       " get the start of the rest
-      let l:rest_start_idx = l:body_start_idx + str2nr(l:length_match[1])
+      let l:next_start_idx = l:body_start_idx + str2nr(l:length_match[1])
 
-      if len(l:rest) < l:rest_start_idx
+      if len(l:rest) < l:next_start_idx
         " incomplete response body
         break
       endif
 
-      if go#util#HasDebug('lsp')
-        let g:go_lsp_log = add(go#config#LspLog(), "<-\n" . l:rest[:l:rest_start_idx - 1])
-      endif
+      call s:debug('received', l:rest[:l:next_start_idx - 1])
 
-      let l:body = l:rest[l:body_start_idx : l:rest_start_idx - 1]
-      let l:rest = l:rest[l:rest_start_idx :]
+      let l:body = l:rest[l:body_start_idx : l:next_start_idx - 1]
+      let l:rest = l:rest[l:next_start_idx :]
 
       try
         " add the json body to the list.
@@ -105,46 +112,99 @@ function! s:newlsp() abort
   function! l:lsp.handleMessage(ch, data) dict abort
       let self.buf .= a:data
 
-      let [self.buf, l:responses] = self.readMessage(self.buf)
+      let [self.buf, l:messages] = self.readMessage(self.buf)
 
-      " TODO(bc): handle notifications (e.g. window/showMessage).
-
-      for l:response in l:responses
-        if has_key(l:response, 'id') && has_key(self.handlers, l:response.id)
-          try
-            let l:handler = self.handlers[l:response.id]
-
-            let l:winid = win_getid(winnr())
-            " Always set the active window to the window that was active when
-            " the request was sent. Among other things, this makes sure that
-            " the correct window's location list will be populated when the
-            " list type is 'location' and the user has moved windows since
-            " sending the reques.
-            call win_gotoid(l:handler.winid)
-
-            if has_key(l:response, 'error')
-              call l:handler.requestComplete(0)
-              if has_key(l:handler, 'error')
-                call call(l:handler.error, [l:response.error.message])
-              else
-                call go#util#EchoError(l:response.error.message)
-              endif
-              call win_gotoid(l:winid)
-              return
-            endif
-            call l:handler.requestComplete(1)
-            call call(l:handler.handleResult, [l:response.result])
-            call win_gotoid(l:winid)
-          finally
-            call remove(self.handlers, l:response.id)
-          endtry
+      for l:message in l:messages
+        if has_key(l:message, 'method')
+          if has_key(l:message, 'id')
+            call self.handleRequest(l:message)
+          else
+            call self.handleNotification(l:message)
+          endif
+        elseif has_key(l:message, 'result') || has_key(l:message, 'error')
+          call self.handleResponse(l:message)
         endif
       endfor
   endfunction
 
+  function! l:lsp.handleRequest(req) dict abort
+    if a:req.method == 'workspace/workspaceFolders'
+      let l:resp = go#lsp#message#WorkspaceFoldersResult(self.workspaceDirectories)
+    elseif a:req.method == 'workspace/configuration' && has_key(a:req, 'params') && has_key(a:req.params, 'items')
+      let l:resp = go#lsp#message#ConfigurationResult(a:req.params.items)
+    elseif a:req.method == 'client/registerCapability' && has_key(a:req, 'params') && has_key(a:req.params, 'registrations')
+      let l:resp = v:null
+    else
+      return
+    endif
+
+    if get(self, 'exited', 0)
+      return
+    endif
+
+    let l:msg = self.newResponse(a:req.id, l:resp)
+    call self.write(l:msg)
+  endfunction
+
+  function! l:lsp.handleNotification(req) dict abort
+      " TODO(bc): handle notifications (e.g. window/showMessage).
+  endfunction
+
+  function! l:lsp.handleResponse(resp) dict abort
+    if has_key(a:resp, 'id') && has_key(self.handlers, a:resp.id)
+      try
+        let l:handler = self.handlers[a:resp.id]
+
+        let l:winid = win_getid(winnr())
+        " Always set the active window to the window that was active when
+        " the request was sent. Among other things, this makes sure that
+        " the correct window's location list will be populated when the
+        " list type is 'location' and the user has moved windows since
+        " sending the request.
+        call win_gotoid(l:handler.winid)
+
+        if has_key(a:resp, 'error')
+          call l:handler.requestComplete(0)
+          if has_key(l:handler, 'error')
+            call call(l:handler.error, [a:resp.error.message])
+          else
+            call go#util#EchoError(a:resp.error.message)
+          endif
+          call win_gotoid(l:winid)
+          return
+        endif
+        call l:handler.requestComplete(1)
+
+        let l:winidBeforeHandler = l:handler.winid
+        call call(l:handler.handleResult, [a:resp.result])
+
+        " change the window back to the window that was active when
+        " starting to handle the message _only_ if the handler didn't
+        " update the winid, so that handlers can set the winid if needed
+        " (e.g. :GoDef).
+        if l:handler.winid == l:winidBeforeHandler
+          call win_gotoid(l:winid)
+        endif
+      finally
+        call remove(self.handlers, a:resp.id)
+      endtry
+    endif
+  endfunction
+
   function! l:lsp.handleInitializeResult(result) dict abort
+    if go#config#EchoCommandInfo()
+      call go#util#EchoProgress("initialized gopls")
+    endif
+    let status = {
+          \ 'desc': '',
+          \ 'type': 'gopls',
+          \ 'state': 'initialized',
+        \ }
+    call go#statusline#Update(self.wd, status)
+
     let self.ready = 1
-    " TODO(bc): send initialized message to the server?
+    let  l:msg = self.newMessage(go#lsp#message#Initialized())
+    call self.write(l:msg)
 
     " send messages queued while waiting for ready.
     for l:item in self.queue
@@ -157,22 +217,34 @@ function! s:newlsp() abort
 
   function! l:lsp.sendMessage(data, handler) dict abort
     if !self.last_request_id
-      " TODO(bc): run a server per module and one per GOPATH? (may need to
-      " keep track of servers by rootUri).
       let l:wd = go#util#ModuleRoot()
       if l:wd == -1
         call go#util#EchoError('could not determine appropriate working directory for gopls')
-        return
+        return -1
       endif
 
       if l:wd == ''
         let l:wd = getcwd()
       endif
+      let self.wd = l:wd
 
+      if go#config#EchoCommandInfo()
+        call go#util#EchoProgress("initializing gopls")
+      endif
+
+      let l:status = {
+            \ 'desc': '',
+            \ 'type': 'gopls',
+            \ 'state': 'initializing',
+          \ }
+      call go#statusline#Update(l:wd, l:status)
+
+      let self.workspaceDirectories = add(self.workspaceDirectories, l:wd)
       let l:msg = self.newMessage(go#lsp#message#Initialize(l:wd))
 
       let l:state = s:newHandlerState('')
       let l:state.handleResult = funcref('self.handleInitializeResult', [], l:self)
+
       let self.handlers[l:msg.id] = l:state
 
       call l:state.start()
@@ -199,7 +271,7 @@ function! s:newlsp() abort
     let l:msg = {
           \ 'method': a:data.method,
           \ 'jsonrpc': '2.0',
-          \ }
+        \ }
 
     if !a:data.notification
       let self.last_request_id += 1
@@ -213,13 +285,21 @@ function! s:newlsp() abort
     return l:msg
   endfunction
 
-  function! l:lsp.write(msg) dict abort
-      let l:body = json_encode(a:msg)
-      let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
+  function l:lsp.newResponse(id, result) dict abort
+    let l:msg = {
+          \ 'jsonrpc': '2.0',
+          \ 'id': a:id,
+          \ 'result': a:result,
+        \ }
 
-    if go#util#HasDebug('lsp')
-      let g:go_lsp_log = add(go#config#LspLog(), "->\n" . l:data)
-    endif
+    return l:msg
+  endfunction
+
+  function! l:lsp.write(msg) dict abort
+    let l:body = json_encode(a:msg)
+    let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
+
+    call s:debug('sent', l:data)
 
     if has('nvim')
       call chansend(self.job, l:data)
@@ -229,19 +309,39 @@ function! s:newlsp() abort
     call ch_sendraw(self.job, l:data)
   endfunction
 
-  function! l:lsp.exit_cb(job, exit_status) dict abort
+  function! l:lsp.exit_cb(job, exit_status) dict
+    let self.exited = 1
+    if !get(self, 'restarting', 0)
+      return
+    endif
+
+    let l:queue = self.queue
+
+    let l:workspaces = self.workspaceDirectories
+
     call s:lspfactory.reset()
+    let l:lsp = s:lspfactory.get()
+
+    " restore workspaces
+    call call('go#lsp#AddWorkspaceDirectory', l:workspaces)
+    " * send DidOpen messages for all buffers that have b:did_lsp_open set
+    " TODO(bc): check modifiable and filetype, too?
+    bufdo if get(b:, 'go_lsp_did_open', 0) | if &modified | call go#lsp#DidOpen(expand('%:p')) | else | call go#lsp#DidChange(expand('%:p')) | endif | endif
+    let l:lsp.queue = extend(l:lsp.queue, l:queue)
+    return
   endfunction
-  " explicitly bind close_cb to state so that within it, self will always refer
 
   function! l:lsp.close_cb(ch) dict abort
-    " TODO(bc): does anything need to be done here?
+    " TODO(bc): remove the buffer variables that indicate that gopls has been
+    " informed that the file is open
   endfunction
 
   function! l:lsp.err_cb(ch, msg) dict abort
-    if go#util#HasDebug('lsp')
-      let g:go_lsp_log = add(go#config#LspLog(), "<-stderr\n" .  a:msg)
+    if a:msg =~ '^\tPort = \d\+$' && !get(self, 'debugport', 0)
+      let self.debugport = substitute(a:msg, '^\tPort = \(\d\+\).*$', '\1', '')
     endif
+
+    call s:debug('stderr', a:msg)
   endfunction
 
   " explicitly bind callbacks to l:lsp so that within it, self will always refer
@@ -263,11 +363,13 @@ function! s:newlsp() abort
     return
   endif
 
-  " TODO(bc): output a message indicating which directory lsp is going to
-  " start in.
-  let l:lsp.job = go#job#Start([l:bin_path], l:opts)
+  let l:cmd = [l:bin_path]
+  if go#util#HasDebug('lsp')
+    let l:cmd = extend(l:cmd, ['-debug', 'localhost:0'])
+  endif
+
+  let l:lsp.job = go#job#Start(l:cmd, l:opts)
 
-  " TODO(bc): send the initialize message now?
   return l:lsp
 endfunction
 
@@ -327,16 +429,17 @@ function! s:requestComplete(ok) abort dict
 endfunction
 
 function! s:start() abort dict
-  if self.statustype != ''
-    let status = {
-          \ 'desc': 'current status',
-          \ 'type': self.statustype,
-          \ 'state': "started",
-          \ }
-
-    call go#statusline#Update(self.jobdir, status)
-  endif
   let self.started_at = reltime()
+  if self.statustype == ''
+    return
+  endif
+  let status = {
+        \ 'desc': 'current status',
+        \ 'type': self.statustype,
+        \ 'state': "started",
+        \ }
+
+  call go#statusline#Update(self.jobdir, status)
 endfunction
 
 " go#lsp#Definition calls gopls to get the definition of the identifier at
@@ -351,13 +454,13 @@ function! go#lsp#Definition(fname, line, col, handler) abort
   let l:state = s:newHandlerState('definition')
   let l:state.handleResult = funcref('s:definitionHandler', [function(a:handler, [], l:state)], l:state)
   let l:msg = go#lsp#message#Definition(fnamemodify(a:fname, ':p'), a:line, a:col)
-  call l:lsp.sendMessage(l:msg, l:state)
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! s:definitionHandler(next, msg) abort dict
   " gopls returns a []Location; just take the first one.
   let l:msg = a:msg[0]
-  let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, l:msg.range.start.character+1, 'lsp does not supply a description')]]
+  let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]]
   call call(a:next, l:args)
 endfunction
 
@@ -373,13 +476,13 @@ function! go#lsp#TypeDef(fname, line, col, handler) abort
   let l:state = s:newHandlerState('type definition')
   let l:msg = go#lsp#message#TypeDefinition(fnamemodify(a:fname, ':p'), a:line, a:col)
   let l:state.handleResult = funcref('s:typeDefinitionHandler', [function(a:handler, [], l:state)], l:state)
-  call l:lsp.sendMessage(l:msg, l:state)
+  return  l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! s:typeDefinitionHandler(next, msg) abort dict
   " gopls returns a []Location; just take the first one.
   let l:msg = a:msg[0]
-  let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, l:msg.range.start.character+1, 'lsp does not supply a description')]]
+  let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]]
   call call(a:next, l:args)
 endfunction
 
@@ -396,9 +499,13 @@ function! go#lsp#DidOpen(fname) abort
   let l:msg = go#lsp#message#DidOpen(fnamemodify(a:fname, ':p'), join(go#util#GetLines(), "\n") . "\n")
   let l:state = s:newHandlerState('')
   let l:state.handleResult = funcref('s:noop')
-  call l:lsp.sendMessage(l:msg, l:state)
 
+  " TODO(bc): setting a buffer level variable here assumes that a:fname is the
+  " current buffer. Change to a:fname first before setting it and then change
+  " back to active buffer.
   let b:go_lsp_did_open = 1
+
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! go#lsp#DidChange(fname) abort
@@ -409,17 +516,17 @@ function! go#lsp#DidChange(fname) abort
     return
   endif
 
-  call go#lsp#DidOpen(a:fname)
-
   if !filereadable(a:fname)
     return
   endif
 
+  call go#lsp#DidOpen(a:fname)
+
   let l:lsp = s:lspfactory.get()
   let l:msg = go#lsp#message#DidChange(fnamemodify(a:fname, ':p'), join(go#util#GetLines(), "\n") . "\n")
   let l:state = s:newHandlerState('')
   let l:state.handleResult = funcref('s:noop')
-  call l:lsp.sendMessage(l:msg, l:state)
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! go#lsp#DidClose(fname) abort
@@ -435,9 +542,12 @@ function! go#lsp#DidClose(fname) abort
   let l:msg = go#lsp#message#DidClose(fnamemodify(a:fname, ':p'))
   let l:state = s:newHandlerState('')
   let l:state.handleResult = funcref('s:noop')
-  call l:lsp.sendMessage(l:msg, l:state)
-
+  " TODO(bc): setting a buffer level variable here assumes that a:fname is the
+  " current buffer. Change to a:fname first before setting it and then change
+  " back to active buffer.
   let b:go_lsp_did_open = 0
+
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! go#lsp#Completion(fname, line, col, handler) abort
@@ -448,16 +558,33 @@ function! go#lsp#Completion(fname, line, col, handler) abort
   let l:state = s:newHandlerState('completion')
   let l:state.handleResult = funcref('s:completionHandler', [function(a:handler, [], l:state)], l:state)
   let l:state.error = funcref('s:completionErrorHandler', [function(a:handler, [], l:state)], l:state)
-  call l:lsp.sendMessage(l:msg, l:state)
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! s:completionHandler(next, msg) abort dict
   " gopls returns a CompletionList.
   let l:matches = []
+  let l:start = -1
+
   for l:item in a:msg.items
+    let l:start = l:item.textEdit.range.start.character
+
     let l:match = {'abbr': l:item.label, 'word': l:item.textEdit.newText, 'info': '', 'kind': go#lsp#completionitemkind#Vim(l:item.kind)}
     if has_key(l:item, 'detail')
-        let l:match.info = l:item.detail
+        let l:match.menu = l:item.detail
+        if go#lsp#completionitemkind#IsFunction(l:item.kind) || go#lsp#completionitemkind#IsMethod(l:item.kind)
+          let l:match.info = printf('%s %s', l:item.label, l:item.detail)
+
+          " The detail provided by gopls hasn't always provided the the full
+          " signature including the return value. The label used to be the
+          " function signature and the detail was the return value. Handle
+          " that case for backward compatibility. This can be removed in the
+          " future once it's likely that the majority of users are on a recent
+          " version of gopls.
+          if l:item.detail !~ '^func'
+            let l:match.info = printf('func %s %s', l:item.label, l:item.detail)
+          endif
+        endif
     endif
 
     if has_key(l:item, 'documentation')
@@ -466,12 +593,12 @@ function! s:completionHandler(next, msg) abort dict
 
     let l:matches = add(l:matches, l:match)
   endfor
-  let l:args = [l:matches]
+  let l:args = [l:start, l:matches]
   call call(a:next, l:args)
 endfunction
 
 function! s:completionErrorHandler(next, error) abort dict
-  call call(a:next, [[]])
+  call call(a:next, [-1, []])
 endfunction
 
 function! go#lsp#Hover(fname, line, col, handler) abort
@@ -482,7 +609,7 @@ function! go#lsp#Hover(fname, line, col, handler) abort
   let l:state = s:newHandlerState('')
   let l:state.handleResult = funcref('s:hoverHandler', [function(a:handler, [], l:state)], l:state)
   let l:state.error = funcref('s:noop')
-  call l:lsp.sendMessage(l:msg, l:state)
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
 function! s:hoverHandler(next, msg) abort dict
@@ -499,7 +626,7 @@ endfunction
 
 function! go#lsp#Info(showstatus)
   let l:fname = expand('%:p')
-  let [l:line, l:col] = getpos('.')[1:2]
+  let [l:line, l:col] = go#lsp#lsp#Position()
 
   call go#lsp#DidChange(l:fname)
 
@@ -511,10 +638,29 @@ function! go#lsp#Info(showstatus)
     let l:state = s:newHandlerState('')
   endif
 
-  let l:state.handleResult = funcref('s:infoDefinitionHandler', [function('s:info', []), a:showstatus], l:state)
+  let l:state.handleResult = funcref('s:infoDefinitionHandler', [function('s:info', [1], l:state), a:showstatus], l:state)
+  let l:state.error = funcref('s:noop')
+  let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
+  return l:lsp.sendMessage(l:msg, l:state)
+endfunction
+
+function! go#lsp#GetInfo()
+  let l:fname = expand('%:p')
+  let [l:line, l:col] = go#lsp#lsp#Position()
+
+  call go#lsp#DidChange(l:fname)
+
+  let l:lsp = s:lspfactory.get()
+
+  let l:state = s:newHandlerState('')
+
+  let l:info = go#promise#New(function('s:info', [0], l:state), 10000, '')
+
+  let l:state.handleResult = funcref('s:infoDefinitionHandler', [l:info.wrapper, 0], l:state)
   let l:state.error = funcref('s:noop')
   let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
   call l:lsp.sendMessage(l:msg, l:state)
+  return l:info.await()
 endfunction
 
 function! s:infoDefinitionHandler(next, showstatus, msg) abort dict
@@ -522,8 +668,8 @@ function! s:infoDefinitionHandler(next, showstatus, msg) abort dict
   let l:msg = a:msg[0]
 
   let l:fname = go#path#FromURI(l:msg.uri)
-  let l:line = l:msg.range.start.line+1
-  let l:col = l:msg.range.start.character+1
+  let l:line = l:msg.range.start.line
+  let l:col = l:msg.range.start.character
 
   let l:lsp = s:lspfactory.get()
   let l:msg = go#lsp#message#Hover(l:fname, l:line, l:col)
@@ -534,18 +680,166 @@ function! s:infoDefinitionHandler(next, showstatus, msg) abort dict
     let l:state = s:newHandlerState('')
   endif
 
-  let l:state.handleResult = funcref('s:hoverHandler', [function('s:info', [], l:state)], l:state)
+  let l:state.handleResult = funcref('s:hoverHandler', [a:next], l:state)
   let l:state.error = funcref('s:noop')
-  call l:lsp.sendMessage(l:msg, l:state)
+  return l:lsp.sendMessage(l:msg, l:state)
 endfunction
 
-function! s:info(content) abort dict
+function! s:info(show, content) abort dict
+  let l:content = s:infoFromHoverContent(a:content)
+
+  if a:show
+    call go#util#ShowInfo(l:content)
+  endif
+
+  return l:content
+endfunction
+
+function! s:infoFromHoverContent(content) abort
+  if len(a:content) < 1
+    return ''
+  endif
+
   let l:content = a:content[0]
+
   " strip off the method set and fields of structs and interfaces.
-  if l:content =~# '^type [^ ]\+ \(struct\|interface\)'
+  if l:content =~# '^\(type \)\?[^ ]\+ \(struct\|interface\)'
     let l:content = substitute(l:content, '{.*', '', '')
   endif
-  call go#util#ShowInfo(l:content)
+
+  return l:content
+endfunction
+
+function! go#lsp#AddWorkspaceDirectory(...) abort
+  if a:0 == 0
+    return
+  endif
+
+  call go#lsp#CleanWorkspaces()
+
+  let l:workspaces = []
+  for l:dir in a:000
+    let l:dir = fnamemodify(l:dir, ':p')
+    if !isdirectory(l:dir)
+      continue
+    endif
+
+    let l:workspaces = add(l:workspaces, l:dir)
+  endfor
+
+  let l:lsp = s:lspfactory.get()
+  let l:state = s:newHandlerState('')
+  let l:state.handleResult = funcref('s:noop')
+  let l:lsp.workspaceDirectories = extend(l:lsp.workspaceDirectories, l:workspaces)
+  let l:msg = go#lsp#message#ChangeWorkspaceFolders(l:workspaces, [])
+  call l:lsp.sendMessage(l:msg, l:state)
+
+  return 0
+endfunction
+
+function! go#lsp#CleanWorkspaces() abort
+  let l:workspaces = []
+
+  let l:lsp = s:lspfactory.get()
+
+  let l:i = 0
+  let l:missing = []
+  for l:dir in l:lsp.workspaceDirectories
+    if !isdirectory(l:dir)
+      let l:dir = add(l:missing, l:dir)
+      call remove(l:lsp.workspaceDirectories, l:i)
+      continue
+    endif
+    let l:i += 1
+  endfor
+
+  let l:state = s:newHandlerState('')
+  let l:state.handleResult = funcref('s:noop')
+  let l:msg = go#lsp#message#ChangeWorkspaceFolders([], l:missing)
+  call l:lsp.sendMessage(l:msg, l:state)
+
+  return 0
+endfunction
+
+" go#lsp#ResetWorkspaceDiretories removes and then re-adds all workspace
+" folders to cause gopls to send configuration requests for all of them again.
+" This is useful, for instance, when build tags have been added and gopls
+" needs to use them.
+function! go#lsp#ResetWorkspaceDirectories() abort
+  call go#lsp#CleanWorkspaces()
+
+  let l:lsp = s:lspfactory.get()
+
+  let l:state = s:newHandlerState('')
+  let l:state.handleResult = funcref('s:noop')
+  let l:msg = go#lsp#message#ChangeWorkspaceFolders(l:lsp.workspaceDirectories, l:lsp.workspaceDirectories)
+  call l:lsp.sendMessage(l:msg, l:state)
+
+  return 0
+endfunction
+
+function! go#lsp#DebugBrowser() abort
+  let l:lsp = s:lspfactory.get()
+  let l:port = get(l:lsp, 'debugport', 0)
+  if !l:port
+    call go#util#EchoError("gopls was not started with debugging enabled. See :help g:go_debug.")
+    return
+  endif
+
+  call go#util#OpenBrowser(printf('http://localhost:%d', l:port))
+endfunction
+
+function! go#lsp#Restart() abort
+  if !go#util#has_job() || len(s:lspfactory) == 0 || !has_key(s:lspfactory, 'current')
+    return
+  endif
+
+  let l:lsp = s:lspfactory.get()
+
+  let l:lsp.restarting = 1
+
+  let l:state = s:newHandlerState('exit')
+
+  let l:msg = go#lsp#message#Shutdown()
+  let l:state.handleResult = funcref('s:noop')
+  let l:retval = l:lsp.sendMessage(l:msg, l:state)
+
+  let l:msg = go#lsp#message#Exit()
+  let l:retval = l:lsp.sendMessage(l:msg, l:state)
+
+  return l:retval
+endfunction
+
+function! s:debug(event, data) abort
+  if !go#util#HasDebug('lsp')
+    return
+  endif
+
+  let l:winid = win_getid()
+
+  let l:name = '__GOLSP_LOG__'
+  let l:log_winid = bufwinid(l:name)
+  if l:log_winid == -1
+    silent keepalt botright 10new
+    silent file `='__GOLSP_LOG__'`
+    setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
+    setlocal filetype=golsplog
+  else
+    call win_gotoid(l:log_winid)
+  endif
+
+  try
+    setlocal modifiable
+    if getline(1) == ''
+      call setline('$', printf('%s: %s', a:event, a:data))
+    else
+      call append('$', printf('%s: %s', a:event, a:data))
+    endif
+    normal! G
+    setlocal nomodifiable
+  finally
+    call win_gotoid(l:winid)
+  endtry
 endfunction
 
 " restore Vi compatibility settings
diff --git a/sources_non_forked/vim-go/autoload/go/lsp/completionitemkind.vim b/sources_non_forked/vim-go/autoload/go/lsp/completionitemkind.vim
index 37c00a88..0202bd26 100644
--- a/sources_non_forked/vim-go/autoload/go/lsp/completionitemkind.vim
+++ b/sources_non_forked/vim-go/autoload/go/lsp/completionitemkind.vim
@@ -28,7 +28,7 @@ let s:Event = 23
 let s:Operator = 24
 let s:TypeParameter = 25
 
-function! go#lsp#completionitemkind#Vim(kind)
+function! go#lsp#completionitemkind#Vim(kind) abort
   if a:kind == s:Method || a:kind == s:Function || a:kind == s:Constructor
     return 'f'
   elseif a:kind == s:Variable || a:kind == s:Constant
@@ -40,6 +40,22 @@ function! go#lsp#completionitemkind#Vim(kind)
   endif
 endfunction
 
+function! go#lsp#completionitemkind#IsFunction(kind) abort
+  if a:kind == s:Function
+    return 1
+  endif
+
+  return 0
+endfunction
+
+function! go#lsp#completionitemkind#IsMethod(kind) abort
+  if a:kind == s:Method
+    return 1
+  endif
+
+  return 0
+endfunction
+
 " restore Vi compatibility settings
 let &cpo = s:cpo_save
 unlet s:cpo_save
diff --git a/sources_non_forked/vim-go/autoload/go/lsp/lsp.vim b/sources_non_forked/vim-go/autoload/go/lsp/lsp.vim
new file mode 100644
index 00000000..56a2da4c
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/lsp/lsp.vim
@@ -0,0 +1,58 @@
+" don't spam the user when Vim is started in Vi compatibility mode
+let s:cpo_save = &cpo
+set cpo&vim
+
+" go#lsp#lsp#Position returns the LSP text position. If no arguments are
+" provided, the cursor position is assumed. Otherwise, there should be two
+" arguments: the line and the column.
+function! go#lsp#lsp#Position(...)
+  if a:0 < 2
+    let [l:line, l:col] = getpos('.')[1:2]
+  else
+    let l:line = a:1
+    let l:col = a:2
+  endif
+  let l:content = getline(l:line)
+
+  " LSP uses 0-based lines.
+  return [l:line - 1, s:character(l:line, l:col-1)]
+endfunction
+
+function! s:strlen(str) abort
+  let l:runes = split(a:str, '\zs')
+  return len(l:runes) + len(filter(l:runes, 'char2nr(v:val)>=0x10000'))
+endfunction
+
+function! s:character(line, col) abort
+  return s:strlen(getline(a:line)[:col([a:line, a:col - 1])])
+endfunction
+
+" go#lsp#PositionOf returns len(content[0:units]) where units is utf-16 code
+" units. This is mostly useful for converting LSP text position to vim
+" position.
+function! go#lsp#lsp#PositionOf(content, units) abort
+  if a:units == 0
+    return 1
+  endif
+
+  let l:remaining = a:units
+  let l:str = ""
+  for l:rune in split(a:content, '\zs')
+    if l:remaining < 0
+      break
+    endif
+    let l:remaining -= 1
+    if char2nr(l:rune) >= 0x10000
+      let l:remaining -= 1
+    endif
+    let l:str = l:str . l:rune
+  endfor
+
+  return len(l:str)
+endfunction
+
+" restore Vi compatibility settings
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim b/sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim
new file mode 100644
index 00000000..24a2a747
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim
@@ -0,0 +1,32 @@
+" don't spam the user when Vim is started in Vi compatibility mode
+let s:cpo_save = &cpo
+set cpo&vim
+
+scriptencoding utf-8
+
+function! Test_PositionOf_Simple()
+  let l:actual = go#lsp#lsp#PositionOf("just ascii", 3)
+  call assert_equal(4, l:actual)
+endfunc
+
+
+function! Test_PositionOf_MultiByte()
+  " ⌘ is U+2318, which encodes to three bytes in utf-8 and 1 code unit in
+  " utf-16.
+  let l:actual = go#lsp#lsp#PositionOf("⌘⌘ foo", 3)
+  call assert_equal(8, l:actual)
+endfunc
+
+function! Test_PositionOf_MultipleCodeUnit()
+    " 𐐀 is U+10400, which encodes to 4 bytes in utf-8 and 2 code units in
+    " utf-16.
+    let l:actual = go#lsp#lsp#PositionOf("𐐀 bar", 3)
+    call assert_equal(6, l:actual)
+endfunction
+
+
+" restore Vi compatibility settings
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/autoload/go/lsp/message.vim b/sources_non_forked/vim-go/autoload/go/lsp/message.vim
index 63981854..318a3d8d 100644
--- a/sources_non_forked/vim-go/autoload/go/lsp/message.vim
+++ b/sources_non_forked/vim-go/autoload/go/lsp/message.vim
@@ -10,17 +10,50 @@ function! go#lsp#message#Initialize(wd) abort
             \ 'processId': getpid(),
             \ 'rootUri': go#path#ToURI(a:wd),
             \ 'capabilities': {
-              \ 'workspace': {},
+              \ 'workspace': {
+                \ 'workspaceFolders': v:true,
+                \ 'didChangeConfiguration': {
+                  \ 'dynamicRegistration': v:true,
+                \ },
+                \ 'configuration': v:true,
+              \ },
               \ 'textDocument': {
                 \ 'hover': {
                   \ 'contentFormat': ['plaintext'],
                 \ },
               \ }
-            \ }
+            \ },
+            \ 'workspaceFolders': [s:workspaceFolder(0, a:wd)],
           \ }
        \ }
 endfunction
 
+function! go#lsp#message#Initialized() abort
+  return {
+          \ 'notification': 1,
+          \ 'method': 'initialized',
+          \ 'params': {},
+       \ }
+endfunction
+
+function! go#lsp#message#Shutdown() abort
+  return {
+          \ 'notification': 0,
+          \ 'method': 'shutdown',
+       \ }
+endfunction
+
+function! go#lsp#message#Exit() abort
+  return {
+          \ 'notification': 1,
+          \ 'method': 'exit',
+       \ }
+endfunction
+
+function! go#lsp#message#WorkspaceFoldersResult(dirs) abort
+  return map(copy(a:dirs), function('s:workspaceFolder', []))
+endfunction
+
 function! go#lsp#message#Definition(file, line, col) abort
   return {
           \ 'notification': 0,
@@ -116,8 +149,49 @@ function! go#lsp#message#Hover(file, line, col) abort
        \ }
 endfunction
 
+function! go#lsp#message#ChangeWorkspaceFolders(add, remove) abort
+  let l:addDirs = map(copy(a:add), function('s:workspaceFolder', []))
+  let l:removeDirs = map(copy(a:add), function('s:workspaceFolder', []))
+
+  return {
+          \ 'notification': 1,
+          \ 'method': 'workspace/didChangeWorkspaceFolders',
+          \ 'params': {
+          \   'event': {
+          \     'removed': l:removeDirs,
+          \     'added': l:addDirs,
+          \     },
+          \ }
+       \ }
+
+endfunction
+
+function! go#lsp#message#ConfigurationResult(items) abort
+  let l:result = []
+
+  " results must be in the same order as the items
+  for l:item in a:items
+    let l:config = {
+          \ 'buildFlags': [],
+          \ 'hoverKind': 'NoDocumentation',
+          \ }
+    let l:buildtags = go#config#BuildTags()
+    if buildtags isnot ''
+      let l:config.buildFlags = extend(l:config.buildFlags, ['-tags', go#config#BuildTags()])
+    endif
+
+    let l:result = add(l:result, l:config)
+  endfor
+
+  return l:result
+endfunction
+
+function s:workspaceFolder(key, val) abort
+  return {'uri': go#path#ToURI(a:val), 'name': a:val}
+endfunction
+
 function! s:position(line, col) abort
-  return {'line': a:line - 1, 'character': a:col-1}
+  return {'line': a:line, 'character': a:col}
 endfunction
 
 " restore Vi compatibility settings
diff --git a/sources_non_forked/vim-go/autoload/go/lsp_test.vim b/sources_non_forked/vim-go/autoload/go/lsp_test.vim
new file mode 100644
index 00000000..b475bdb4
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/lsp_test.vim
@@ -0,0 +1,49 @@
+" don't spam the user when Vim is started in Vi compatibility mode
+let s:cpo_save = &cpo
+set cpo&vim
+
+scriptencoding utf-8
+
+function! Test_GetSimpleTextPosition()
+    call s:getinfo('lsp text position should align with cursor position after ascii only', 'ascii')
+endfunction
+
+function! Test_GetMultiByteTextPosition()
+    call s:getinfo('lsp text position should align with cursor position after two place of interest symbols ⌘⌘', 'multi-byte')
+endfunction
+
+function! Test_GetMultipleCodeUnitTextPosition()
+    call s:getinfo('lsp text position should align with cursor position after Deseret Capital Letter Long I 𐐀', 'multi-code-units')
+endfunction
+
+function! s:getinfo(str, name)
+  if !go#util#has_job()
+    return
+  endif
+
+  try
+    let g:go_info_mode = 'gopls'
+
+    let l:tmp = gotest#write_file(a:name . '/position/position.go', [
+          \ 'package position',
+          \ '',
+          \ 'func Example() {',
+          \ "\tid := " . '"foo"',
+          \ "\tprintln(" .'"' . a:str . '", id)',
+          \ '}',
+          \ ] )
+
+    let l:expected = 'var id string'
+    let l:actual = go#lsp#GetInfo()
+    call assert_equal(l:expected, l:actual)
+  finally
+    "call delete(l:tmp, 'rf')
+    unlet g:go_info_mode
+  endtry
+endfunction
+
+" restore Vi compatibility settings
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/autoload/go/mod.vim b/sources_non_forked/vim-go/autoload/go/mod.vim
index ab36d0b5..6a7a456d 100644
--- a/sources_non_forked/vim-go/autoload/go/mod.vim
+++ b/sources_non_forked/vim-go/autoload/go/mod.vim
@@ -8,10 +8,14 @@ function! go#mod#Format() abort
   " go mod only exists in `v1.11`
   if empty(s:go_major_version)
     let tokens = matchlist(go#util#Exec(['go', 'version']), '\d\+.\(\d\+\)\(\.\d\+\)\? ')
-    let s:go_major_version = str2nr(tokens[1])
+    if len(tokens) > 0
+      let s:go_major_version = str2nr(tokens[1])
+    else
+      let s:go_major_version = ""
+    endif
   endif
 
-  if s:go_major_version < "11" 
+  if !empty(s:go_major_version) && s:go_major_version < "11"
     call go#util#EchoError("Go v1.11 is required to format go.mod file")
     return
   endif
diff --git a/sources_non_forked/vim-go/autoload/go/package.vim b/sources_non_forked/vim-go/autoload/go/package.vim
index 796f62d7..21b2d166 100644
--- a/sources_non_forked/vim-go/autoload/go/package.vim
+++ b/sources_non_forked/vim-go/autoload/go/package.vim
@@ -82,6 +82,10 @@ function! s:vendordirs() abort
     if l:err != 0
       return []
     endif
+    if empty(l:root)
+      return []
+    endif
+
     let l:root = split(l:root, '\n')[0] . go#util#PathSep() . 'src'
 
     let [l:dir, l:err] = go#util#ExecInDir(['go', 'list', '-f', '{{.Dir}}'])
@@ -111,57 +115,77 @@ function! s:vendordirs() abort
 endfunction
 
 let s:import_paths = {}
-" ImportPath returns the import path of the package for current buffer.
+" ImportPath returns the import path of the package for current buffer. It
+" returns -1 if the import path cannot be determined.
 function! go#package#ImportPath() abort
-  let dir = expand("%:p:h")
+  let l:dir = expand("%:p:h")
   if has_key(s:import_paths, dir)
-    return s:import_paths[dir]
+    return s:import_paths[l:dir]
   endif
 
-  let [l:out, l:err] = go#util#ExecInDir(['go', 'list'])
-  if l:err != 0
+  let l:importpath = go#package#FromPath(l:dir)
+  if type(l:importpath) == type(0)
     return -1
   endif
 
-  let l:importpath = split(out, '\n')[0]
-
-  " go list returns '_CURRENTDIRECTORY' if the directory is not inside GOPATH.
-  " Check it and retun an error if that is the case
-  if l:importpath[0] ==# '_'
-    return -1
-  endif
-
-  let s:import_paths[dir] = l:importpath
+  let s:import_paths[l:dir] = l:importpath
 
   return l:importpath
 endfunction
 
-
 " go#package#FromPath returns the import path of arg. -1 is returned when arg
 " does not specify a package. -2 is returned when arg is a relative path
-" outside of GOPATH and not in a module.
+" outside of GOPATH, not in a module, and not below the current working
+" directory. A relative path is returned when in a null module at or below the
+" current working directory..
 function! go#package#FromPath(arg) abort
   let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
   let l:dir = getcwd()
 
-  let l:path = a:arg
+  let l:path = fnamemodify(a:arg, ':p')
   if !isdirectory(l:path)
     let l:path = fnamemodify(l:path, ':h')
   endif
 
   execute l:cd fnameescape(l:path)
-  let [l:out, l:err] = go#util#Exec(['go', 'list'])
-  execute l:cd fnameescape(l:dir)
-  if l:err != 0
-    return -1
-  endif
+  try
+    if glob("*.go") == ""
+      " There's no Go code in this directory. We might be in a module directory
+      " which doesn't have any code at this level. To avoid `go list` making a
+      " bunch of HTTP requests to fetch dependencies, short-circuit `go list`
+      " and return -1 immediately.
+      if !empty(s:module())
+        return -1
+      endif
+    endif
+    let [l:out, l:err] = go#util#Exec(['go', 'list'])
+    if l:err != 0
+      return -1
+    endif
 
-  let l:importpath = split(l:out, '\n')[0]
+    let l:importpath = split(l:out, '\n')[0]
+  finally
+    execute l:cd fnameescape(l:dir)
+  endtry
 
-  " go list returns '_CURRENTDIRECTORY' if the directory is neither in GOPATH
-  " nor in a module. Check it and retun an error if that is the case
+  " go list returns '_CURRENTDIRECTORY' if the directory is in a null module
+  " (i.e. neither in GOPATH nor in a module). Return a relative import path
+  " if possible or an error if that is the case.
   if l:importpath[0] ==# '_'
-    return -2
+    let l:relativeimportpath = fnamemodify(l:importpath[1:], ':.')
+    if go#util#IsWin()
+      let l:relativeimportpath = substitute(l:relativeimportpath, '\\', '/', 'g')
+    endif
+
+    if l:relativeimportpath == l:importpath[1:]
+      return '.'
+    endif
+
+    if l:relativeimportpath[0] == '/'
+      return -2
+    endif
+
+    let l:importpath= printf('./%s', l:relativeimportpath)
   endif
 
   return l:importpath
diff --git a/sources_non_forked/vim-go/autoload/go/promise.vim b/sources_non_forked/vim-go/autoload/go/promise.vim
new file mode 100644
index 00000000..76c2f7c3
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/promise.vim
@@ -0,0 +1,50 @@
+" don't spam the user when Vim is started in Vi compatibility mode
+let s:cpo_save = &cpo
+set cpo&vim
+
+scriptencoding utf-8
+
+" New returns a promise. A promise's primary purpose is to make async jobs
+" synchronous by awaiting fn.
+"
+" A promise is a dictionary with two keys:
+"   'wrapper':
+"     A function that wraps fn. It can be used in place of fn.
+"   'await':
+"     A function that waits for wrapper to be called and returns the value
+"     returned by fn. Returns default if timeout expires.
+function! go#promise#New(fn, timeout, default) abort
+  let l:state = {}
+
+  " explicitly bind to state so that within l:promise's methods, self will
+  " always refer to state. See :help Partial for more information.
+  return {
+        \ 'wrapper': function('s:wrapper', [a:fn], l:state),
+        \ 'await': function('s:await', [a:timeout, a:default], l:state),
+  \ }
+endfunction
+
+function! s:wrapper(fn, ...) dict
+  let self.retval = call(a:fn, a:000)
+  return self.retval
+endfunction
+
+function! s:await(timeout, default) dict
+  let l:timer = timer_start(a:timeout, function('s:setretval', [a:default], self))
+  while !has_key(self, 'retval')
+    sleep 50m
+  endwhile
+  call timer_stop(l:timer)
+
+  return self.retval
+endfunction
+
+function! s:setretval(val, timer) dict
+  let self.retval = a:val
+endfunction
+
+" restore Vi compatibility settings
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/autoload/go/promise_test.vim b/sources_non_forked/vim-go/autoload/go/promise_test.vim
new file mode 100644
index 00000000..f4473fe6
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/promise_test.vim
@@ -0,0 +1,41 @@
+" don't spam the user when Vim is started in Vi compatibility mode
+let s:cpo_save = &cpo
+set cpo&vim
+
+func! Test_PromiseNew() abort
+	let l:sut = go#promise#New(function('s:work', []), 100, -1)
+	call assert_true(has_key(l:sut, 'wrapper'))
+	call assert_true(has_key(l:sut, 'await'))
+endfunc
+
+func! Test_PromiseAwait() abort
+	let l:expected = 1
+	let l:default = -1
+	let l:sut = go#promise#New(function('s:work', [l:expected]), 100, l:default)
+
+	call timer_start(10, l:sut.wrapper)
+
+	let l:actual = call(l:sut.await, [])
+	call assert_equal(l:expected, l:actual)
+endfunc
+
+func! Test_PromiseAwait_Timeout() abort
+	let l:desired = 1
+	let l:expected = -1
+	let l:sut = go#promise#New(function('s:work', [l:desired]), 10, l:expected)
+
+	call timer_start(100, l:sut.wrapper)
+
+	let l:actual = call(l:sut.await, [])
+	call assert_equal(l:expected, l:actual)
+endfunc
+
+func! s:work(val, timer)
+	return a:val
+endfunc
+
+" restore Vi compatibility settings
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/autoload/go/statusline.vim b/sources_non_forked/vim-go/autoload/go/statusline.vim
index f0ec5cd0..9779d763 100644
--- a/sources_non_forked/vim-go/autoload/go/statusline.vim
+++ b/sources_non_forked/vim-go/autoload/go/statusline.vim
@@ -27,9 +27,8 @@ let s:last_status = ""
 " if not it returns an empty string. This function should be plugged directly
 " into the statusline.
 function! go#statusline#Show() abort
-  " lazy initialiation of the cleaner
+  " lazy initialization of the cleaner
   if !s:timer_id
-    " clean every 60 seconds all statuses
     let interval = go#config#StatuslineDuration()
     let s:timer_id = timer_start(interval, function('go#statusline#Clear'), {'repeat': -1})
   endif
@@ -57,9 +56,9 @@ function! go#statusline#Show() abort
 
   " only update highlight if status has changed.
   if status_text != s:last_status
-    if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass"
+    if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass" || status.state =~ 'initialized'
       hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22 guibg=#5fd700 guifg=#005f00
-    elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling"
+    elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling" || status.state =~ 'initializing'
       hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88 guibg=#ff8700 guifg=#870000
     elseif status.state =~ "failed"
       hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52 guibg=#ff0000 guifg=#5f0000
@@ -83,10 +82,11 @@ function! go#statusline#Update(status_dir, status) abort
   " before we stop the timer, check if we have any previous jobs to be cleaned
   " up. Otherwise every job will reset the timer when this function is called
   " and thus old jobs will never be cleaned
-  call go#statusline#Clear(0)
+  call s:clear()
 
   " also reset the timer, so the user has time to see it in the statusline.
-  " Setting the timer_id to 0 will trigger a new cleaner routine.
+  " Setting the timer_id to 0 will cause a new timer to be created the next
+  " time the go#statusline#Show() is called.
   call timer_stop(s:timer_id)
   let s:timer_id = 0
 endfunction
@@ -94,6 +94,10 @@ endfunction
 " Clear clears all currently stored statusline data. The timer_id argument is
 " just a placeholder so we can pass it to a timer_start() function if needed.
 function! go#statusline#Clear(timer_id) abort
+  call s:clear()
+endfunction
+
+function! s:clear()
   for [status_dir, status] in items(s:statuses)
     let elapsed_time = reltimestr(reltime(status.created_at))
     " strip whitespace
diff --git a/sources_non_forked/vim-go/autoload/go/template.vim b/sources_non_forked/vim-go/autoload/go/template.vim
index 3f5e5381..404047ae 100644
--- a/sources_non_forked/vim-go/autoload/go/template.vim
+++ b/sources_non_forked/vim-go/autoload/go/template.vim
@@ -24,8 +24,13 @@ function! go#template#create() abort
       else
         let l:template_file = go#config#TemplateFile()
       endif
-      let l:template_path = go#util#Join(l:root_dir, "templates", l:template_file)
-      silent exe 'keepalt 0r ' . fnameescape(l:template_path)
+      " If template_file is an absolute path, use it as-is. This is to support
+      " overrides pointing to templates outside of the vim-go plugin dir
+      if fnamemodify(l:template_file, ':p') != l:template_file
+        let l:template_file = go#util#Join(l:root_dir, "templates", l:template_file)
+      endif
+
+      silent exe 'keepalt 0r ' . fnameescape(l:template_file)
     endif
   else
     let l:content = printf("package %s", l:package_name)
diff --git a/sources_non_forked/vim-go/autoload/go/term.vim b/sources_non_forked/vim-go/autoload/go/term.vim
index d7a463eb..9352be5d 100644
--- a/sources_non_forked/vim-go/autoload/go/term.vim
+++ b/sources_non_forked/vim-go/autoload/go/term.vim
@@ -96,6 +96,13 @@ function! s:on_stdout(job_id, data, event) dict abort
 endfunction
 
 function! s:on_exit(job_id, exit_status, event) dict abort
+  " change to directory where test were run. if we do not do this
+  " the quickfix items will have the incorrect paths. 
+  " see: https://github.com/fatih/vim-go/issues/2400
+  let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+  let l:dir = getcwd()
+  execute l:cd . fnameescape(expand("%:p:h"))
+
   let l:winid = win_getid(winnr())
   call win_gotoid(self.winid)
   let l:listtype = go#list#Type("_term")
@@ -130,8 +137,10 @@ function! s:on_exit(job_id, exit_status, event) dict abort
   endif
 
   " close terminal; we don't need it anymore
-  call win_gotoid(self.termwinid)
-  close!
+  if go#config#TermCloseOnExit()
+    call win_gotoid(self.termwinid)
+    close!
+  endif
 
   if self.bang
     call win_gotoid(l:winid)
@@ -140,6 +149,21 @@ function! s:on_exit(job_id, exit_status, event) dict abort
 
   call win_gotoid(self.winid)
   call go#list#JumpToFirst(l:listtype)
+
+  " change back to original working directory 
+  execute l:cd l:dir
+endfunction
+
+function! go#term#ToggleCloseOnExit() abort
+  if go#config#TermCloseOnExit()
+    call go#config#SetTermCloseOnExit(0)
+    call go#util#EchoProgress("term close on exit disabled")
+    return
+  endif
+
+  call go#config#SetTermCloseOnExit(1)
+  call go#util#EchoProgress("term close on exit enabled")
+  return
 endfunction
 
 " restore Vi compatibility settings
diff --git a/sources_non_forked/vim-go/autoload/go/term_test.vim b/sources_non_forked/vim-go/autoload/go/term_test.vim
index 40f0a52a..0d5d1d94 100644
--- a/sources_non_forked/vim-go/autoload/go/term_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/term_test.vim
@@ -22,6 +22,7 @@ func! Test_GoTermNewMode()
     call assert_equal(actual, l:expected)
 
   finally
+    sleep 50m
     call delete(l:tmp, 'rf')
   endtry
 endfunc
@@ -46,6 +47,7 @@ func! Test_GoTermNewMode_SplitRight()
     call assert_equal(actual, l:expected)
 
   finally
+    sleep 50m
     call delete(l:tmp, 'rf')
     set nosplitright
   endtry
diff --git a/sources_non_forked/vim-go/autoload/go/test-fixtures/test/src/example/example_test.go b/sources_non_forked/vim-go/autoload/go/test-fixtures/test/src/example/example_test.go
new file mode 100644
index 00000000..bdcc2e10
--- /dev/null
+++ b/sources_non_forked/vim-go/autoload/go/test-fixtures/test/src/example/example_test.go
@@ -0,0 +1,10 @@
+package main
+
+import (
+	"fmt"
+)
+
+func ExampleHelloWorld() {
+	fmt.Println("Hello, World")
+	// Output: What's shakin
+}
diff --git a/sources_non_forked/vim-go/autoload/go/test.vim b/sources_non_forked/vim-go/autoload/go/test.vim
index f33d7d94..ff15c8da 100644
--- a/sources_non_forked/vim-go/autoload/go/test.vim
+++ b/sources_non_forked/vim-go/autoload/go/test.vim
@@ -32,6 +32,7 @@ function! go#test#Test(bang, compile, ...) abort
 
   if go#config#TermEnabled()
     call go#term#new(a:bang, ["go"] + args, s:errorformat())
+    return
   endif
 
   if go#util#has_job()
@@ -166,9 +167,17 @@ function! s:errorformat() abort
   let format .= ",%-G" . indent . "%#--- PASS: %.%#"
 
   " Match failure lines.
-  "
+
+  " Example failures start with '--- FAIL: ', followed by the example name
+  " followed by a space , followed by the duration of the example in
+  " parantheses. They aren't nested, though, so don't check for indentation.
+  " The errors from them also aren't indented and don't report file location
+  " or line numbers, so those won't show up. This will at least let the user
+  " know which example failed, though.
+  let format .= ',%G--- FAIL: %\\%(Example%\\)%\\@=%m (%.%#)'
+
   " Test failures start with '--- FAIL: ', followed by the test name followed
-  " by a space the duration of the test in parentheses
+  " by a space, followed by the duration of the test in parentheses.
   "
   " e.g.:
   "   '--- FAIL: TestSomething (0.00s)'
diff --git a/sources_non_forked/vim-go/autoload/go/test_test.vim b/sources_non_forked/vim-go/autoload/go/test_test.vim
index 28d7993c..322abed6 100644
--- a/sources_non_forked/vim-go/autoload/go/test_test.vim
+++ b/sources_non_forked/vim-go/autoload/go/test_test.vim
@@ -66,9 +66,9 @@ endfunc
 func! Test_GoTestShowName() abort
   let expected = [
         \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'TestHelloWorld'},
-        \ {'lnum': 6, 'bufnr': 7, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'so long'},
+        \ {'lnum': 6, 'bufnr': 8, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'so long'},
         \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'TestHelloWorld/sub'},
-        \ {'lnum': 9, 'bufnr': 7, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'thanks for all the fish'},
+        \ {'lnum': 9, 'bufnr': 8, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'thanks for all the fish'},
       \ ]
 
   let g:go_test_show_name=1
@@ -78,20 +78,27 @@ endfunc
 
 func! Test_GoTestVet() abort
   let expected = [
-        \ {'lnum': 6, 'bufnr': 10, 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Errorf format %v reads arg #1, but call has 0 args'},
+        \ {'lnum': 6, 'bufnr': 11, 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Errorf format %v reads arg #1, but call has 0 args'},
       \ ]
   call s:test('veterror/veterror.go', expected)
 endfunc
 
 func! Test_GoTestTestCompilerError() abort
   let expected = [
-        \ {'lnum': 10, 'bufnr': 8, 'col': 16, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'cannot use r (type struct {}) as type io.Reader in argument to ioutil.ReadAll:'},
+        \ {'lnum': 10, 'bufnr': 9, 'col': 16, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'cannot use r (type struct {}) as type io.Reader in argument to ioutil.ReadAll:'},
         \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'struct {} does not implement io.Reader (missing Read method)'}
       \ ]
 
   call s:test('testcompilerror/testcompilerror_test.go', expected)
 endfunc
 
+func! Test_GoTestExample() abort
+  let expected = [
+        \ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'ExampleHelloWorld'}
+      \ ]
+  call s:test('example/example_test.go', expected)
+endfunc
+
 func! s:test(file, expected, ...) abort
   let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/test'
   silent exe 'e ' . $GOPATH . '/src/' . a:file
diff --git a/sources_non_forked/vim-go/autoload/go/tool.vim b/sources_non_forked/vim-go/autoload/go/tool.vim
index fdeaaf12..41380abd 100644
--- a/sources_non_forked/vim-go/autoload/go/tool.vim
+++ b/sources_non_forked/vim-go/autoload/go/tool.vim
@@ -115,7 +115,15 @@ endfunction
 
 function! go#tool#DescribeBalloon()
   let l:fname = fnamemodify(bufname(v:beval_bufnr), ':p')
-  call go#lsp#Hover(l:fname, v:beval_lnum, v:beval_col, funcref('s:balloon', []))
+
+  let l:winid = win_getid()
+
+  call win_gotoid(bufwinid(v:beval_bufnr))
+
+  let [l:line, l:col] = go#lsp#lsp#Position(v:beval_lnum, v:beval_col)
+  call go#lsp#Hover(l:fname, l:line, l:col, funcref('s:balloon', []))
+
+  call win_gotoid(l:winid)
   return ''
 endfunction
 
diff --git a/sources_non_forked/vim-go/autoload/go/util.vim b/sources_non_forked/vim-go/autoload/go/util.vim
index 965f1e8b..15324220 100644
--- a/sources_non_forked/vim-go/autoload/go/util.vim
+++ b/sources_non_forked/vim-go/autoload/go/util.vim
@@ -36,15 +36,9 @@ function! go#util#Join(...) abort
 endfunction
 
 " IsWin returns 1 if current OS is Windows or 0 otherwise
+" Note that has('win32') is always 1 when has('win64') is 1, so has('win32') is enough.
 function! go#util#IsWin() abort
-  let win = ['win16', 'win32', 'win64', 'win95']
-  for w in win
-    if (has(w))
-      return 1
-    endif
-  endfor
-
-  return 0
+  return has('win32')
 endfunction
 
 " IsMac returns 1 if current OS is macOS or 0 otherwise.
@@ -468,7 +462,7 @@ function! go#util#tempdir(prefix) abort
   endif
 
   " Not great randomness, but "good enough" for our purpose here.
-  let l:rnd = sha256(printf('%s%s', localtime(), fnamemodify(bufname(''), ":p")))
+  let l:rnd = sha256(printf('%s%s', reltimestr(reltime()), fnamemodify(bufname(''), ":p")))
   let l:tmp = printf("%s/%s%s", l:dir, a:prefix, l:rnd)
   call mkdir(l:tmp, 'p', 0700)
   return l:tmp
@@ -557,7 +551,9 @@ function! go#util#SetEnv(name, value) abort
     let l:remove = 1
   endif
 
-  call execute('let $' . a:name . ' = "' . a:value . '"')
+  " wrap the value in single quotes so that it will work on windows when there
+  " are backslashes present in the value (e.g. $PATH).
+  call execute('let $' . a:name . " = '" . a:value . "'")
 
   if l:remove
     function! s:remove(name) abort
diff --git a/sources_non_forked/vim-go/autoload/gotest.vim b/sources_non_forked/vim-go/autoload/gotest.vim
index e010d52b..7fae8152 100644
--- a/sources_non_forked/vim-go/autoload/gotest.vim
+++ b/sources_non_forked/vim-go/autoload/gotest.vim
@@ -12,6 +12,9 @@ set cpo&vim
 " The full path to the created directory is returned, it is the caller's
 " responsibility to clean that up!
 fun! gotest#write_file(path, contents) abort
+  if go#util#has_job()
+    call go#lsp#CleanWorkspaces()
+  endif
   let l:dir = go#util#tempdir("vim-go-test/testrun/")
   let $GOPATH .= ':' . l:dir
   let l:full_path = l:dir . '/src/' . a:path
@@ -19,15 +22,23 @@ fun! gotest#write_file(path, contents) abort
   call mkdir(fnamemodify(l:full_path, ':h'), 'p')
   call writefile(a:contents, l:full_path)
   exe 'cd ' . l:dir . '/src'
+
+  if go#util#has_job()
+    call go#lsp#AddWorkspaceDirectory(fnamemodify(l:full_path, ':p:h'))
+  endif
+
   silent exe 'e! ' . a:path
 
   " Set cursor.
   let l:lnum = 1
   for l:line in a:contents
-    let l:m = match(l:line, "\x1f")
+    let l:m = stridx(l:line, "\x1f")
     if l:m > -1
-      call setpos('.', [0, l:lnum, l:m, 0])
+      let l:byte = line2byte(l:lnum) + l:m
+      exe 'goto '. l:byte
       call setline('.', substitute(getline('.'), "\x1f", '', ''))
+      silent noautocmd w!
+
       break
     endif
 
@@ -42,6 +53,9 @@ endfun
 " The file will be copied to a new GOPATH-compliant temporary directory and
 " loaded as the current buffer.
 fun! gotest#load_fixture(path) abort
+  if go#util#has_job()
+    call go#lsp#CleanWorkspaces()
+  endif
   let l:dir = go#util#tempdir("vim-go-test/testrun/")
   let $GOPATH .= ':' . l:dir
   let l:full_path = l:dir . '/src/' . a:path
@@ -51,6 +65,9 @@ fun! gotest#load_fixture(path) abort
   silent exe 'noautocmd e ' . a:path
   silent exe printf('read %s/test-fixtures/%s', g:vim_go_root, a:path)
   silent noautocmd w!
+  if go#util#has_job()
+    call go#lsp#AddWorkspaceDirectory(fnamemodify(l:full_path, ':p:h'))
+  endif
 
   return l:dir
 endfun
diff --git a/sources_non_forked/vim-go/doc/vim-go.txt b/sources_non_forked/vim-go/doc/vim-go.txt
index 8715995e..4100b176 100644
--- a/sources_non_forked/vim-go/doc/vim-go.txt
+++ b/sources_non_forked/vim-go/doc/vim-go.txt
@@ -94,26 +94,26 @@ For Pathogen or Vim |packages|, just clone the repo. For other plugin managers
 you may also need to add the lines to your vimrc to execute the plugin
 manager's install command.
 
-*  Vim 8 |packages|
->
+*  Vim 8 |packages| >
+
     git clone https://github.com/fatih/vim-go.git \
       ~/.vim/pack/plugins/start/vim-go
-
+<
 *  https://github.com/tpope/vim-pathogen >
 
     git clone https://github.com/fatih/vim-go.git ~/.vim/bundle/vim-go
 <
 *  https://github.com/junegunn/vim-plug >
 
-    Plug 'fatih/vim-go'
-
+    Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
+<
 *  https://github.com/Shougo/neobundle.vim >
 
     NeoBundle 'fatih/vim-go'
 <
 *  https://github.com/gmarik/vundle >
 
-    Plugin 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
+    Plugin 'fatih/vim-go'
 <
 *  Manual (not recommended) >
 
@@ -376,8 +376,8 @@ CTRL-t
 :GoInfo
     Show type information about the identifier under the cursor. For example
     putting it above a function call is going to show the full function
-    signature. By default it uses `gocode` to get the type informations. To
-    change the underlying tool from `gocode` to another tool, see
+    signature. By default it uses `gopls` to get the type informations. To
+    change the underlying tool from `gopls` to another tool, see
     |'g:go_info_mode'|.
 
 
@@ -536,7 +536,7 @@ CTRL-t
 
 
                                                                 *:GoGuruScope*
-:GoGuruScope [pattern] [pattern2] ... [patternN]
+:GoGuruScope [pattern] ...
 
     Changes the custom |'g:go_guru_scope'| setting and overrides it with the
     given package patterns. The custom scope is cleared (unset) if `""` is
@@ -906,6 +906,16 @@ CTRL-t
     tries to preserve cursor position and avoids replacing the buffer with
     stderr output.
 
+                                                            *:GoAddWorkspace*
+:GoAddWorkspace [dir] ...
+
+    Add directories to the `gopls` workspace.
+
+                                                         *:GoLSPDebugBrowser*
+:GoLSPDebugBrowser
+
+    Open a browser to see gopls debugging information.
+
 ==============================================================================
 MAPPINGS                                                        *go-mappings*
 
@@ -1204,6 +1214,14 @@ balloonexpr`.
 ==============================================================================
 SETTINGS                                                        *go-settings*
 
+                                                     *'g:go_version_warning'*
+
+Enable warning when using an unsupported version of Vim. By default it is
+enabled.
+>
+  let g:go_version_warning = 1
+<
+
                                               *'g:go_code_completion_enabled'*
 
 Enable code completion with |'omnifunc'|. By default it is enabled.
@@ -1228,9 +1246,9 @@ set to 10 seconds . >
 <
                                                  *'g:go_play_browser_command'*
 
-Browser to use for |:GoPlay| or |:GoDocBrowser|. The url must be added with
-`%URL%`, and it's advisable to include `&` to make sure the shell returns. For
-example:
+Browser to use for |:GoPlay|, |:GoDocBrowser|, and |:GoLSPDebugBrowser|. The
+url must be added with `%URL%`, and it's advisable to include `&` to make sure
+the shell returns. For example:
 >
   let g:go_play_browser_command = 'firefox-developer %URL% &'
 <
@@ -1259,11 +1277,11 @@ updated. By default it's disabled. The delay can be configured with the
                                                             *'g:go_info_mode'*
 
 Use this option to define the command to be used for |:GoInfo|. By default
-`gocode` is being used as it's the fastest option. But one might also use
-`gopls` or `guru` as they cover more cases and are more accurate.  Current
-valid options are: `[gocode, guru, gopls]` >
-
-  let g:go_info_mode = 'gocode'
+`gopls` is used, because it is the fastest and is known to be highly accurate.
+One might also use `guru` for its accuracy or `gocode` for its performance.
+Valid options are `gocode`, `gopls`, and `guru`.
+>
+  let g:go_info_mode = 'gopls'
 <
                                                          *'g:go_auto_sameids'*
 
@@ -1375,10 +1393,11 @@ a private internal service. Default is 'https://godoc.org'.
                                                              *'g:go_def_mode'*
 
 Use this option to define the command to be used for |:GoDef|. By default
-`guru` is being used as it covers all edge cases. But one might also use
-`godef` as it's faster. Current valid options are: `[guru, godef, gopls]` >
-
-  let g:go_def_mode = 'guru'
+`gopls` is used, because it is the fastest. One might also use `guru` for its
+accuracy or `godef` for its performance. Valid options are `godef`, `gopls`,
+and `guru`.
+>
+  let g:go_def_mode = 'gopls'
 <
                                                   *'g:go_def_mapping_enabled'*
 
@@ -1621,6 +1640,13 @@ according to |'g:go_term_mode'|, otherwise it will run them in the background
 just like `:GoBuild`. By default it is disabled.
 >
   let g:go_term_enabled = 0
+<
+                                                   *'g:go_term_close_on_exit'*
+
+This option is Neovim only. If set to 1 it closes the terminal after the
+command run in it exits. By default it is enabled.
+>
+  let g:go_term_close_on_exit = 1
 <
                                                        *'g:go_alternate_mode'*
 
@@ -1676,7 +1702,8 @@ Specifies whether `gocode` should use a different socket type. By default
 When a new Go file is created, vim-go automatically fills the buffer content
 with a Go code template. By default, the templates under the `templates`
 folder are used.  This can be changed with the |'g:go_template_file'| and
-|'g:go_template_test_file'| settings.
+|'g:go_template_test_file'| settings to either use a different file in the
+same `templates` folder, or to use a file stored elsewhere.
 
 If the new file is created in an already prepopulated package (with other Go
 files), in this case a Go code template with only the Go package declaration
@@ -1691,17 +1718,23 @@ By default it is enabled.
 <
                                                         *'g:go_template_file'*
 
-Specifies the file under the `templates` folder that is used if a new Go file
-is created. Checkout |'g:go_template_autocreate'| for more info. By default
-the `hello_world.go` file is used.
+Specifies either the file under the `templates` folder that is used if a new
+Go file is created. Checkout |'g:go_template_autocreate'| for more info. By
+default the `hello_world.go` file is used.
+
+This variable can be set to an absolute path, so the template files don't have
+to be stored inside the vim-go directory structure. Useful when you want to
+use different templates for different projects.
 >
   let g:go_template_file = "hello_world.go"
 <
                                                    *'g:go_template_test_file'*
 
-Specifies the file under the `templates` folder that is used if a new Go test
-file is created. Checkout |'g:go_template_autocreate'| for more info. By
-default the `hello_world_test.go` file is used.
+Like with |'g:go_template_file'|, this specifies the file to use for test
+tempaltes. The template file should be under the `templates` folder,
+alternatively absolute paths can be used, too. Checkout
+|'g:go_template_autocreate'| for more info. By default, the
+`hello_world_test.go` file is used.
 >
   let g:go_template_test_file = "hello_world_test.go"
 <
@@ -1788,7 +1821,10 @@ Currently accepted values:
   debugger-state     Expose debugger state in 'g:go_debug_diag'.
   debugger-commands  Echo communication between vim-go and `dlv`; requests and
                      responses are recorded in `g:go_debug_commands`.
-  lsp                Record lsp requests and responses in g:go_lsp_log.
+  lsp                Echo communication between vim-go and `gopls`. All
+                     communication is shown in a dedicated window. When
+                     enabled before gopls is started, |:GoLSPDebugBrowser| can
+                     be used to open a browser window to help debug gopls.
 >
       let g:go_debug = []
 <
@@ -2027,8 +2063,7 @@ rest of the commands and mappings become available after starting debug mode.
       * Make the `:GoDebug*` commands and `(go-debug-*)` mappings available.
 
     The directory of the current buffer is used if [pkg] is empty. Any other
-    arguments will be passed to the program. When [pkg] is relative, it will
-    be interpreted relative to the directory of the current buffer.
+    arguments will be passed to the program.
 
     Use |:GoDebugStop| to stop `dlv` and exit debugging mode.
 
@@ -2183,6 +2218,22 @@ Highlight the current line and breakpoints in the debugger.
 ==============================================================================
 FAQ TROUBLESHOOTING                                     *go-troubleshooting*
 
+How do I troubleshoot problems?~
+
+One of the best ways to understand what vim-go is doing and the output from
+the tools to which it delegates is to use leverage the features described in
+|'g:go_debug'|.
+
+Completion and other functions that use `gopls` don't work~
+
+Vim-go is heavily reliant on `gopls` for completion and other functionality.
+Many of the features that use `gopls` (e.g. completion, jumping to
+definitions, showing identifier information, et al.) can be configured to
+delegate to other tools. e.g.  completion via |'omnifunc'|, |'g:go_info_mode'|
+and |'g:go_def_mode'| can be set to use other tools for now (though some of
+the alternatives to `gopls` are effectively at their end of life and support
+for them from within vim-go may be removed soon).
+
 I get "Unknown function: go#config#..." error when I open a Go file.~
 
 This often happens to vim-polyglot users when new config options are added to
diff --git a/sources_non_forked/vim-go/ftplugin/go/commands.vim b/sources_non_forked/vim-go/ftplugin/go/commands.vim
index 726b944c..716b49da 100644
--- a/sources_non_forked/vim-go/ftplugin/go/commands.vim
+++ b/sources_non_forked/vim-go/ftplugin/go/commands.vim
@@ -116,4 +116,11 @@ command! -nargs=0 GoReportGitHubIssue call go#issue#New()
 " -- iferr
 command! -nargs=0 GoIfErr call go#iferr#Generate()
 
+" -- lsp
+command! -nargs=+ -complete=dir GoAddWorkspace call go#lsp#AddWorkspaceDirectory(<f-args>)
+command! -nargs=0 GoLSPDebugBrowser call go#lsp#DebugBrowser()
+
+" -- term
+command! GoToggleTermCloseOnExit call go#term#ToggleCloseOnExit()
+
 " vim: sw=2 ts=2 et
diff --git a/sources_non_forked/vim-go/gosnippets/UltiSnips/go.snippets b/sources_non_forked/vim-go/gosnippets/UltiSnips/go.snippets
index 0a9b7ae4..3acf9cf3 100644
--- a/sources_non_forked/vim-go/gosnippets/UltiSnips/go.snippets
+++ b/sources_non_forked/vim-go/gosnippets/UltiSnips/go.snippets
@@ -151,7 +151,7 @@ if err := ${1:condition}; err != nil {
 endsnippet
 
 # error snippet
-snippet errn "Error return " !b
+snippet errn "Error return" !b
 if err != nil {
 	return err
 }
@@ -326,7 +326,7 @@ endsnippet
 # struct
 snippet st "type T struct { ... }"
 type ${1:Type} struct {
-${0}
+	${0}
 }
 endsnippet
 
diff --git a/sources_non_forked/vim-go/plugin/go.vim b/sources_non_forked/vim-go/plugin/go.vim
index 7b3832d3..0546f499 100644
--- a/sources_non_forked/vim-go/plugin/go.vim
+++ b/sources_non_forked/vim-go/plugin/go.vim
@@ -20,19 +20,19 @@ function! s:checkVersion() abort
   let l:unsupported = 0
   if go#config#VersionWarning() != 0
     if has('nvim')
-      let l:unsupported = !has('nvim-0.3.1')
+      let l:unsupported = !has('nvim-0.3.2')
     else
       let l:unsupported = (v:version < 704 || (v:version == 704 && !has('patch2009')))
     endif
 
     if l:unsupported == 1
       echohl Error
-      echom "vim-go requires Vim 7.4.2009 or Neovim 0.3.1, but you're using an older version."
+      echom "vim-go requires Vim 7.4.2009 or Neovim 0.3.2, but you're using an older version."
       echom "Please update your Vim for the best vim-go experience."
       echom "If you really want to continue you can set this to make the error go away:"
       echom "    let g:go_version_warning = 0"
       echom "Note that some features may error out or behave incorrectly."
-      echom "Please do not report bugs unless you're using Vim 7.4.2009 or newer or Neovim 0.3.1."
+      echom "Please do not report bugs unless you're using Vim 7.4.2009 or newer or Neovim 0.3.2."
       echohl None
 
       " Make sure people see this.
@@ -56,7 +56,7 @@ let s:packages = {
       \ 'gogetdoc':      ['github.com/zmb3/gogetdoc'],
       \ 'goimports':     ['golang.org/x/tools/cmd/goimports'],
       \ 'golint':        ['golang.org/x/lint/golint'],
-      \ 'gopls':         ['golang.org/x/tools/cmd/gopls'],
+      \ 'gopls':         ['golang.org/x/tools/gopls@latest', {}, {'after': function('go#lsp#Restart', [])}],
       \ 'gometalinter':  ['github.com/alecthomas/gometalinter'],
       \ 'golangci-lint': ['github.com/golangci/golangci-lint/cmd/golangci-lint'],
       \ 'gomodifytags':  ['github.com/fatih/gomodifytags'],
@@ -104,9 +104,6 @@ function! s:GoInstallBinaries(updateBinaries, ...)
   " vim's executable path is looking in PATH so add our go_bin path to it
   let Restore_path = go#util#SetEnv('PATH', go_bin_path . go#util#PathListSep() . $PATH)
 
-  " GO111MODULE must be off to install golanci-lint and gometalinter
-  let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
-
   " when shellslash is set on MS-* systems, shellescape puts single quotes
   " around the output string. cmd on Windows does not handle single quotes
   " correctly. Unsetting shellslash forces shellescape to use double quotes
@@ -117,10 +114,7 @@ function! s:GoInstallBinaries(updateBinaries, ...)
     set noshellslash
   endif
 
-  let l:dl_cmd = ['go', 'get', '-v', '-d']
-  if get(g:, "go_get_update", 1) != 0
-    let l:dl_cmd += ['-u']
-  endif
+  let l:get_base_cmd = ['go', 'get', '-v']
 
   " Filter packages from arguments (if any).
   let l:packages = {}
@@ -142,51 +136,93 @@ function! s:GoInstallBinaries(updateBinaries, ...)
     let l:platform = 'windows'
   endif
 
-  for [binary, pkg] in items(l:packages)
-    let l:importPath = pkg[0]
+  let l:oldmore = &more
+  let &more = 0
 
-    let l:run_cmd = copy(l:dl_cmd)
-    if len(l:pkg) > 1 && get(l:pkg[1], l:platform, '') isnot ''
-      let l:run_cmd += get(l:pkg[1], l:platform, '')
-    endif
+  for [l:binary, l:pkg] in items(l:packages)
+    let l:importPath = l:pkg[0]
 
-    let bin_setting_name = "go_" . binary . "_bin"
+    " TODO(bc): how to support this with modules? Do we have to clone and then
+    " install manually? Probably not. I suspect that we can just use GOPATH
+    " mode and then do the legacy method.
+    let bin_setting_name = "go_" . l:binary . "_bin"
 
     if exists("g:{bin_setting_name}")
       let bin = g:{bin_setting_name}
     else
       if go#util#IsWin()
-        let bin = binary . '.exe'
+        let bin = l:binary . '.exe'
       else
-        let bin = binary
+        let bin = l:binary
       endif
     endif
 
     if !executable(bin) || a:updateBinaries == 1
       if a:updateBinaries == 1
-        echo "vim-go: Updating " . binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
+        echo "vim-go: Updating " . l:binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
       else
-        echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path
+        echo "vim-go: ". l:binary ." not found. Installing ". importPath . " to folder " . go_bin_path
       endif
 
-      " first download the binary
-      let [l:out, l:err] = go#util#Exec(l:run_cmd + [l:importPath])
-      if l:err
-        echom "Error downloading " . l:importPath . ": " . l:out
+      if l:importPath =~ "@"
+        let Restore_modules = go#util#SetEnv('GO111MODULE', 'on')
+        let l:tmpdir = go#util#tempdir('vim-go')
+        let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+        let l:dir = getcwd()
+        try
+          execute l:cd . fnameescape(l:tmpdir)
+          let l:get_cmd = copy(l:get_base_cmd)
+
+          " first download the binary
+          let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
+          if l:err
+            echom "Error installing " . l:importPath . ": " . l:out
+          endif
+
+          call call(Restore_modules, [])
+        finally
+          execute l:cd . fnameescape(l:dir)
+        endtry
+        call call(Restore_modules, [])
+      else
+        let l:get_cmd = copy(l:get_base_cmd)
+        let l:get_cmd += ['-d']
+        if get(g:, "go_get_update", 1) != 0
+          let l:get_cmd += ['-u']
+        endif
+
+        " GO111MODULE must be off to install gometalinter.
+        let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
+
+        " first download the binary
+        let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
+        if l:err
+          echom "Error downloading " . l:importPath . ": " . l:out
+        endif
+
+        " and then build and install it
+        let l:build_cmd = ['go', 'build', '-o', go_bin_path . go#util#PathSep() . bin, l:importPath]
+        if len(l:pkg) > 1 && get(l:pkg[1], l:platform, '') isnot ''
+          let l:build_cmd += get(l:pkg[1], l:platform, '')
+        endif
+
+        let [l:out, l:err] = go#util#Exec(l:build_cmd)
+        if l:err
+          echom "Error installing " . l:importPath . ": " . l:out
+        endif
+
+
+        call call(Restore_modules, [])
       endif
 
-      " and then build and install it
-      let l:build_cmd = ['go', 'build', '-o', go_bin_path . go#util#PathSep() . bin, l:importPath]
-      let [l:out, l:err] = go#util#Exec(l:build_cmd)
-      if l:err
-        echom "Error installing " . l:importPath . ": " . l:out
+      if len(l:pkg) > 2
+        call call(get(l:pkg[2], 'after', function('s:noop', [])), [])
       endif
     endif
   endfor
 
   " restore back!
   call call(Restore_path, [])
-  call call(Restore_modules, [])
 
   if resetshellslash
     set shellslash
@@ -197,6 +233,8 @@ function! s:GoInstallBinaries(updateBinaries, ...)
   else
     call go#util#EchoInfo('installing finished!')
   endif
+
+  let &more = l:oldmore
 endfunction
 
 " CheckBinaries checks if the necessary binaries to install the Go tool
diff --git a/sources_non_forked/vim-go/scripts/install-vim b/sources_non_forked/vim-go/scripts/install-vim
index 709fccaa..f383d371 100644
--- a/sources_non_forked/vim-go/scripts/install-vim
+++ b/sources_non_forked/vim-go/scripts/install-vim
@@ -30,7 +30,7 @@ case "$vim" in
 
   "nvim")
     # Use latest stable version.
-    tag="v0.3.1"
+    tag="v0.3.2"
     giturl="https://github.com/neovim/neovim"
     ;;
 
@@ -62,7 +62,7 @@ cd "$srcdir"
 if [ "$1" = "nvim" ]; then
 
   # TODO: Use macOS binaries on macOS
-  curl -Ls https://github.com/neovim/neovim/releases/download/nightly/nvim-linux64.tar.gz |
+  curl -Ls https://github.com/neovim/neovim/releases/download/$tag/nvim-linux64.tar.gz |
     tar xzf - -C /tmp/vim-go-test/
   mv /tmp/vim-go-test/nvim-linux64 /tmp/vim-go-test/nvim-install
   mkdir -p "$installdir/share/nvim/runtime/pack/vim-go/start"
diff --git a/sources_non_forked/vim-go/scripts/runtest.vim b/sources_non_forked/vim-go/scripts/runtest.vim
index 9d20b76a..168de9ca 100644
--- a/sources_non_forked/vim-go/scripts/runtest.vim
+++ b/sources_non_forked/vim-go/scripts/runtest.vim
@@ -64,6 +64,12 @@ for s:test in sort(s:tests)
   endif
   try
     exe 'call ' . s:test
+    " sleep to give events a chance to be processed. This is especially
+    " important for the LSP code to have a chance to run before Vim exits,  in
+    " order to avoid errors trying to write to the gopls channels since Vim
+    " would otherwise stop gopls before the event handlers were run and result
+    " in 'stream closed' errors when the events were run _after_ gopls exited.
+    sleep 50m
   catch
     let v:errors += [v:exception]
   endtry
@@ -76,17 +82,17 @@ for s:test in sort(s:tests)
   let s:elapsed_time = substitute(reltimestr(reltime(s:started)), '^\s*\(.\{-}\)\s*$', '\1', '')
   let s:done += 1
 
-  call s:logmessages()
-
   if len(v:errors) > 0
     let s:fail += 1
     call add(s:logs, printf("--- FAIL %s (%ss)", s:test[:-3], s:elapsed_time))
+    call s:logmessages()
     call extend(s:logs, map(v:errors, '"        ".  v:val'))
 
     " Reset so we can capture failures of the next test.
     let v:errors = []
   else
     if g:test_verbose is 1
+      call s:logmessages()
       call add(s:logs, printf("--- PASS %s (%ss)", s:test[:-3], s:elapsed_time))
     endif
   endif
diff --git a/sources_non_forked/vim-markdown/Makefile b/sources_non_forked/vim-markdown/Makefile
index c9d11550..0b287e26 100644
--- a/sources_non_forked/vim-markdown/Makefile
+++ b/sources_non_forked/vim-markdown/Makefile
@@ -66,6 +66,12 @@ doc: build/html2vimdoc build/vim-tools
 		    -e "s/^- '([^']{1,2})':.*/ \*vim-markdown-\1\*/" -e "# short command" \
 		    -e ":a" -e "s/^(.{1,78})$$/ \1/" -e "ta" -e "# align right" \
 		    -e "G" -e "# append the matched line after the command reference" \
+		    -e "}" \
+		    -e "/^- 'g:vim_markdown_[[:alnum:]_]*'$$/ {" \
+		    -e "h" -e "# save the matched line to the hold space" \
+		    -e "s/^- '([^']*)'$$/ \*\1\*/" -e "# make global variable reference" \
+		    -e ":g" -e "s/^(.{1,78})$$/ \1/" -e "tg" -e "# align right" \
+		    -e "G" -e "# append the matched line after the global variable reference" \
 		    -e "}" > doc/vim-markdown.txt && rm -f doc/tmp.md
 
 .PHONY: doc
diff --git a/sources_non_forked/vim-markdown/README.md b/sources_non_forked/vim-markdown/README.md
index b67917a7..fd3be687 100644
--- a/sources_non_forked/vim-markdown/README.md
+++ b/sources_non_forked/vim-markdown/README.md
@@ -88,154 +88,152 @@ Try `:help concealcursor` and `:help conceallevel` for details.
 
 ### Disable Folding
 
-Add the following line to your `.vimrc` to disable the folding configuration:
+-   `g:vim_markdown_folding_disabled`
 
-```vim
-let g:vim_markdown_folding_disabled = 1
-```
+    Add the following line to your `.vimrc` to disable the folding configuration:
 
-This option only controls Vim Markdown specific folding configuration.
+        let g:vim_markdown_folding_disabled = 1
 
-To enable/disable folding use Vim's standard folding configuration.
+    This option only controls Vim Markdown specific folding configuration.
 
-```vim
-set [no]foldenable
-```
+    To enable/disable folding use Vim's standard folding configuration.
+
+        set [no]foldenable
 
 ### Change fold style
 
-To fold in a style like [python-mode](https://github.com/klen/python-mode), add the following to your `.vimrc`:
+-   `g:vim_markdown_folding_style_pythonic`
 
-```vim
-let g:vim_markdown_folding_style_pythonic = 1
-```
+    To fold in a style like [python-mode](https://github.com/klen/python-mode), add the following to your `.vimrc`:
 
-Level 1 heading which is served as a document title is not folded.
-`g:vim_markdown_folding_level` setting is not active with this fold style.
+        let g:vim_markdown_folding_style_pythonic = 1
 
-To prevent foldtext from being set add the following to your `.vimrc`:
+    `g:vim_markdown_folding_level` setting (default 1) is set to `foldlevel`.
+    Thus level 1 heading which is served as a document title is expanded by default.
 
-```vim
-let g:vim_markdown_override_foldtext = 0
-```
+-   `g:vim_markdown_override_foldtext`
+
+    To prevent foldtext from being set add the following to your `.vimrc`:
+
+        let g:vim_markdown_override_foldtext = 0
 
 ### Set header folding level
 
-Folding level is a number between 1 and 6. By default, if not specified, it is set to 1.
+-   `g:vim_markdown_folding_level`
 
-```vim
-let g:vim_markdown_folding_level = 6
-```
+    Folding level is a number between 1 and 6. By default, if not specified, it is set to 1.
 
-Tip: it can be changed on the fly with:
+        let g:vim_markdown_folding_level = 6
 
-```vim
-:let g:vim_markdown_folding_level = 1
-:edit
-```
+    Tip: it can be changed on the fly with:
+
+        :let g:vim_markdown_folding_level = 1
+        :edit
 
 ### Disable Default Key Mappings
 
-Add the following line to your `.vimrc` to disable default key mappings:
+-   `g:vim_markdown_no_default_key_mappings`
 
-```vim
-let g:vim_markdown_no_default_key_mappings = 1
-```
+    Add the following line to your `.vimrc` to disable default key mappings:
 
-You can also map them by yourself with `<Plug>` mappings.
+        let g:vim_markdown_no_default_key_mappings = 1
+
+    You can also map them by yourself with `<Plug>` mappings.
 
 ### Enable TOC window auto-fit
 
-Allow for the TOC window to auto-fit when it's possible for it to shrink.
-It never increases its default size (half screen), it only shrinks.
+-   `g:vim_markdown_toc_autofit`
 
-```vim
-let g:vim_markdown_toc_autofit = 1
-```
+    Allow for the TOC window to auto-fit when it's possible for it to shrink.
+    It never increases its default size (half screen), it only shrinks.
+
+        let g:vim_markdown_toc_autofit = 1
 
 ### Text emphasis restriction to single-lines
 
-By default text emphasis works across multiple lines until a closing token is found. However, it's possible to restrict text emphasis to a single line (i.e., for it to be applied a closing token must be found on the same line). To do so:
+-   `g:vim_markdown_emphasis_multiline`
 
-```vim
-let g:vim_markdown_emphasis_multiline = 0
-```
+    By default text emphasis works across multiple lines until a closing token is found. However, it's possible to restrict text emphasis to a single line (i.e., for it to be applied a closing token must be found on the same line). To do so:
+
+        let g:vim_markdown_emphasis_multiline = 0
 
 ### Syntax Concealing
 
-Concealing is set for some syntax.
+-   `g:vim_markdown_conceal`
 
-For example, conceal `[link text](link url)` as just `link text`.
-Also, `_italic_` and `*italic*` will conceal to just _italic_.
-Similarly `__bold__`, `**bold**`, `___italic bold___`, and `***italic bold***`
-will conceal to just __bold__, **bold**, ___italic bold___, and ***italic bold*** respectively.
+    Concealing is set for some syntax.
 
-To enable conceal use Vim's standard conceal configuration.
+    For example, conceal `[link text](link url)` as just `link text`.
+    Also, `_italic_` and `*italic*` will conceal to just _italic_.
+    Similarly `__bold__`, `**bold**`, `___italic bold___`, and `***italic bold***`
+    will conceal to just __bold__, **bold**, ___italic bold___, and ***italic bold*** respectively.
 
-```vim
-set conceallevel=2
-```
+    To enable conceal use Vim's standard conceal configuration.
 
-To disable conceal regardless of `conceallevel` setting, add the following to your `.vimrc`:
+        set conceallevel=2
 
-```vim
-let g:vim_markdown_conceal = 0
-```
+    To disable conceal regardless of `conceallevel` setting, add the following to your `.vimrc`:
 
-To disable math conceal with LaTeX math syntax enabled, add the following to your `.vimrc`:
+        let g:vim_markdown_conceal = 0
 
-```vim
-let g:tex_conceal = ""
-let g:vim_markdown_math = 1
-```
+    To disable math conceal with LaTeX math syntax enabled, add the following to your `.vimrc`:
+
+        let g:tex_conceal = ""
+        let g:vim_markdown_math = 1
+
+-   `g:vim_markdown_conceal_code_blocks`
+
+    Disabling conceal for code fences requires an additional setting:
+
+        let g:vim_markdown_conceal_code_blocks = 0
 
 ### Fenced code block languages
 
-You can use filetype name as fenced code block languages for syntax highlighting.
-If you want to use different name from filetype, you can add it in your `.vimrc` like so:
+-   `g:vim_markdown_fenced_languages`
 
-```vim
-let g:vim_markdown_fenced_languages = ['csharp=cs']
-```
+    You can use filetype name as fenced code block languages for syntax highlighting.
+    If you want to use different name from filetype, you can add it in your `.vimrc` like so:
 
-This will cause the following to be highlighted using the `cs` filetype syntax.
+        let g:vim_markdown_fenced_languages = ['csharp=cs']
 
-    ```csharp
-    ...
-    ```
+    This will cause the following to be highlighted using the `cs` filetype syntax.
 
-Default is `['c++=cpp', 'viml=vim', 'bash=sh', 'ini=dosini']`.
+        ```csharp
+        ...
+        ```
+
+    Default is `['c++=cpp', 'viml=vim', 'bash=sh', 'ini=dosini']`.
 
 ### Follow named anchors
 
-This feature allows the `ge` command to follow named anchors in links of the form
-`file#anchor` or just `#anchor`, where file may omit the `.md` extension as
-usual. Two variables control its operation:
+-   `g:vim_markdown_follow_anchor`
 
-```vim
-let g:vim_markdown_follow_anchor = 1
-```
+    This feature allows the `ge` command to follow named anchors in links of the form
+    `file#anchor` or just `#anchor`, where file may omit the `.md` extension as
+    usual. Two variables control its operation:
 
-This tells vim-markdown whether to attempt to follow a named anchor in a link or
-not. When it is 1, and only if a link can be split in two parts by the pattern
-'#', then the first part is interpreted as the file and the second one as the
-named anchor. This also includes urls of the form `#anchor`, for which the first
-part is considered empty, meaning that the target file is the current one. After
-the file is opened, the anchor will be searched.
+        let g:vim_markdown_follow_anchor = 1
 
-Default is `0`.
+    This tells vim-markdown whether to attempt to follow a named anchor in a link or
+    not. When it is 1, and only if a link can be split in two parts by the pattern
+    '#', then the first part is interpreted as the file and the second one as the
+    named anchor. This also includes urls of the form `#anchor`, for which the first
+    part is considered empty, meaning that the target file is the current one. After
+    the file is opened, the anchor will be searched.
 
-```vim
-let g:vim_markdown_anchorexpr = "'<<'.v:anchor.'>>'"
-```
+    Default is `0`.
 
-This expression will be evaluated substituting `v:anchor` with a quoted string
-that contains the anchor to visit. The result of the evaluation will become the
-real anchor to search in the target file. This is useful in order to convert
-anchors of the form, say, `my-section-title` to searches of the form `My Section
-Title` or `<<my-section-title>>`.
+-   `g:vim_markdown_anchorexpr`
 
-Default is `''`.
+        let g:vim_markdown_anchorexpr = "'<<'.v:anchor.'>>'"
+
+    This expression will be evaluated substituting `v:anchor` with a quoted string
+    that contains the anchor to visit. The result of the evaluation will become the
+    real anchor to search in the target file. This is useful in order to convert
+    anchors of the form, say, `my-section-title` to searches of the form `My Section
+    Title` or `<<my-section-title>>`.
+
+    Default is `''`.
 
 ### Syntax extensions
 
@@ -243,119 +241,114 @@ The following options control which syntax extensions will be turned on. They ar
 
 #### LaTeX math
 
-Used as `$x^2$`, `$$x^2$$`, escapable as `\$x\$` and `\$\$x\$\$`.
+-   `g:vim_markdown_math`
 
-```vim
-let g:vim_markdown_math = 1
-```
+    Used as `$x^2$`, `$$x^2$$`, escapable as `\$x\$` and `\$\$x\$\$`.
+
+        let g:vim_markdown_math = 1
 
 #### YAML Front Matter
 
-Highlight YAML front matter as used by Jekyll or [Hugo](https://gohugo.io/content/front-matter/).
+-   `g:vim_markdown_frontmatter`
 
-```vim
-let g:vim_markdown_frontmatter = 1
-```
+    Highlight YAML front matter as used by Jekyll or [Hugo](https://gohugo.io/content/front-matter/).
+
+        let g:vim_markdown_frontmatter = 1
 
 #### TOML Front Matter
 
-Highlight TOML front matter as used by [Hugo](https://gohugo.io/content/front-matter/).
+-   `g:vim_markdown_toml_frontmatter`
 
-TOML syntax highlight requires [vim-toml](https://github.com/cespare/vim-toml).
+    Highlight TOML front matter as used by [Hugo](https://gohugo.io/content/front-matter/).
 
-```vim
-let g:vim_markdown_toml_frontmatter = 1
-```
+    TOML syntax highlight requires [vim-toml](https://github.com/cespare/vim-toml).
+
+        let g:vim_markdown_toml_frontmatter = 1
 
 #### JSON Front Matter
 
-Highlight JSON front matter as used by [Hugo](https://gohugo.io/content/front-matter/).
+-   `g:vim_markdown_json_frontmatter`
 
-JSON syntax highlight requires [vim-json](https://github.com/elzr/vim-json).
+    Highlight JSON front matter as used by [Hugo](https://gohugo.io/content/front-matter/).
 
-```vim
-let g:vim_markdown_json_frontmatter = 1
-```
+    JSON syntax highlight requires [vim-json](https://github.com/elzr/vim-json).
+
+        let g:vim_markdown_json_frontmatter = 1
 
 #### Strikethrough
 
-Strikethrough uses two tildes. `~~Scratch this.~~`
+-   `g:vim_markdown_strikethrough`
 
-```vim
-let g:vim_markdown_strikethrough = 1
-```
+    Strikethrough uses two tildes. `~~Scratch this.~~`
+
+        let g:vim_markdown_strikethrough = 1
 
 ### Adjust new list item indent
 
-You can adjust a new list indent. For example, you insert a single line like below:
+-   `g:vim_markdown_new_list_item_indent`
 
-```
-* item1
-```
+    You can adjust a new list indent. For example, you insert a single line like below:
 
-Then if you type `o` to insert new line in vim and type `* item2`, the result will be:
+        * item1
 
-```
-* item1
-    * item2
-```
+    Then if you type `o` to insert new line in vim and type `* item2`, the result will be:
 
-vim-markdown automatically insert the indent. By default, the number of spaces of indent is 4. If you'd like to change the number as 2, just write:
+        * item1
+            * item2
 
-```vim
-let g:vim_markdown_new_list_item_indent = 2
-```
+    vim-markdown automatically insert the indent. By default, the number of spaces of indent is 4. If you'd like to change the number as 2, just write:
+
+        let g:vim_markdown_new_list_item_indent = 2
 
 ### Do not require .md extensions for Markdown links
 
-If you want to have a link like this `[link text](link-url)` and follow it for editing in vim using the `ge` command, but have it open the file "link-url.md" instead of the file "link-url", then use this option:
+-   `g:vim_markdown_no_extensions_in_markdown`
 
-```vim
-let g:vim_markdown_no_extensions_in_markdown = 1
-```
-This is super useful for GitLab and GitHub wiki repositories.
+    If you want to have a link like this `[link text](link-url)` and follow it for editing in vim using the `ge` command, but have it open the file "link-url.md" instead of the file "link-url", then use this option:
 
-Normal behaviour would be that vim-markup required you to do this `[link text](link-url.md)`, but this is not how the Gitlab and GitHub wiki repositories work. So this option adds some consistency between the two. 
+        let g:vim_markdown_no_extensions_in_markdown = 1
+
+    This is super useful for GitLab and GitHub wiki repositories.
+
+    Normal behaviour would be that vim-markup required you to do this `[link text](link-url.md)`, but this is not how the Gitlab and GitHub wiki repositories work. So this option adds some consistency between the two.
 
 ### Auto-write when following link
 
-If you follow a link like this `[link text](link-url)` using the `ge` shortcut, this option will automatically save any edits you made before moving you:
+-   `g:vim_markdown_autowrite`
 
-```vim
-let g:vim_markdown_autowrite = 1
-```
+    If you follow a link like this `[link text](link-url)` using the `ge` shortcut, this option will automatically save any edits you made before moving you:
+
+        let g:vim_markdown_autowrite = 1
 
 ### Change default file extension
 
-If you would like to use a file extension other than `.md` you may do so using the `vim_markdown_auto_extension_ext` variable:
+-   `g:vim_markdown_auto_extension_ext`
 
-```vim
-let g:vim_markdown_auto_extension_ext = 'txt'
-```
+    If you would like to use a file extension other than `.md` you may do so using the `vim_markdown_auto_extension_ext` variable:
+
+        let g:vim_markdown_auto_extension_ext = 'txt'
 
 ### Do not automatically insert bulletpoints
 
-Automatically inserting bulletpoints can lead to problems when wrapping text
-(see issue #232 for details), so it can be disabled:
+-   `g:vim_markdown_auto_insert_bullets`
 
-```vim
-let g:vim_markdown_auto_insert_bullets = 0
-```
+    Automatically inserting bulletpoints can lead to problems when wrapping text
+    (see issue #232 for details), so it can be disabled:
 
-In that case, you probably also want to set the new list item indent to 0 as
-well, or you will have to remove an indent each time you add a new list item:
+        let g:vim_markdown_auto_insert_bullets = 0
 
-```vim
-let g:vim_markdown_new_list_item_indent = 0
-```
+    In that case, you probably also want to set the new list item indent to 0 as
+    well, or you will have to remove an indent each time you add a new list item:
+
+        let g:vim_markdown_new_list_item_indent = 0
 
 ### Change how to open new files
 
-By default when following a link the target file will be opened in your current buffer.  This behavior can change if you prefer using splits or tabs by using the `vim_markdown_edit_url_in` variable.  Possible values are `tab`, `vsplit`, `hsplit`, `current` opening in a new tab, vertical split, horizontal split, and current buffer respectively.  Defaults to current buffer if not set:
+-   `g:vim_markdown_edit_url_in`
 
-```vim
-let g:vim_markdown_edit_url_in = 'tab'
-```
+    By default when following a link the target file will be opened in your current buffer.  This behavior can change if you prefer using splits or tabs by using the `vim_markdown_edit_url_in` variable.  Possible values are `tab`, `vsplit`, `hsplit`, `current` opening in a new tab, vertical split, horizontal split, and current buffer respectively.  Defaults to current buffer if not set:
+
+        let g:vim_markdown_edit_url_in = 'tab'
 
 ## Mappings
 
diff --git a/sources_non_forked/vim-markdown/after/ftplugin/markdown.vim b/sources_non_forked/vim-markdown/after/ftplugin/markdown.vim
index 41dfd944..8be6ff91 100644
--- a/sources_non_forked/vim-markdown/after/ftplugin/markdown.vim
+++ b/sources_non_forked/vim-markdown/after/ftplugin/markdown.vim
@@ -1,3 +1,4 @@
+" vim: ts=4 sw=4:
 " folding for Markdown headers, both styles (atx- and setex-)
 " http://daringfireball.net/projects/markdown/syntax#header
 "
@@ -14,26 +15,36 @@ endfunction
 if get(g:, "vim_markdown_folding_style_pythonic", 0)
     function! Foldexpr_markdown(lnum)
         let l1 = getline(a:lnum)
-        " keep track of fenced code blocks
+        "~~~~~ keep track of fenced code blocks ~~~~~
+        "If we hit a code block fence
         if l1 =~ '````*' || l1 =~ '\~\~\~\~*'
+            " toggle the variable that says if we're in a code block
             if b:fenced_block == 0
                 let b:fenced_block = 1
             elseif b:fenced_block == 1
                 let b:fenced_block = 0
             endif
+        " else, if we're caring about front matter
         elseif g:vim_markdown_frontmatter == 1
+            " if we're in front matter and not on line 1
             if b:front_matter == 1 && a:lnum > 2
                 let l0 = getline(a:lnum-1)
+                " if the previous line fenced front matter
                 if l0 == '---'
+                    " we must not be in front matter
                     let b:front_matter = 0
                 endif
+            " else, if we're on line one
             elseif a:lnum == 1
+                " if we hit a front matter fence
                 if l1 == '---'
+                    " we're in the front matter
                     let b:front_matter = 1
                 endif
             endif
         endif
 
+        " if we're in a code block or front matter
         if b:fenced_block == 1 || b:front_matter == 1
             if a:lnum == 1
                 " fold any 'preamble'
@@ -45,17 +56,25 @@ if get(g:, "vim_markdown_folding_style_pythonic", 0)
         endif
 
         let l2 = getline(a:lnum+1)
+        " if the next line starts with two or more '='
+        " and is not code
         if l2 =~ '^==\+\s*' && !s:is_mkdCode(a:lnum+1)
             " next line is underlined (level 1)
             return '>0'
+        " else, if the nex line starts with two or more '-'
+        " and is not code
         elseif l2 =~ '^--\+\s*' && !s:is_mkdCode(a:lnum+1)
             " next line is underlined (level 2)
             return '>1'
         endif
 
+        "if we're on a non-code line starting with a pound sign
         if l1 =~ '^#' && !s:is_mkdCode(a:lnum)
-            " current line starts with hashes
-            return '>'.(matchend(l1, '^#\+') - 1)
+            " set the fold level to the number of hashes -1
+            " return '>'.(matchend(l1, '^#\+') - 1)
+            " set the fold level to the number of hashes
+            return '>'.(matchend(l1, '^#\+'))
+        " else, if we're on line 1
         elseif a:lnum == 1
             " fold any 'preamble'
             return '>1'
@@ -76,7 +95,7 @@ if get(g:, "vim_markdown_folding_style_pythonic", 0)
         let fillcharcount = windowwidth - len(line) - len(foldedlinecount) + 1
         return line . ' ' . repeat("-", fillcharcount) . ' ' . foldedlinecount
     endfunction
-else
+else " vim_markdown_folding_style_pythonic == 0
     function! Foldexpr_markdown(lnum)
         if (a:lnum == 1)
             let l0 = ''
@@ -152,15 +171,27 @@ let b:front_matter = 0
 let s:vim_markdown_folding_level = get(g:, "vim_markdown_folding_level", 1)
 
 function! s:MarkdownSetupFolding()
-  if !get(g:, "vim_markdown_folding_disabled", 0)
-      setlocal foldexpr=Foldexpr_markdown(v:lnum)
-      setlocal foldmethod=expr
-      if get(g:, "vim_markdown_folding_style_pythonic", 0) && get(g:, "vim_markdown_override_foldtext", 1)
-          setlocal foldtext=Foldtext_markdown()
-      endif
-  endif
+    if !get(g:, "vim_markdown_folding_disabled", 0)
+        if get(g:, "vim_markdown_folding_style_pythonic", 0)
+            if get(g:, "vim_markdown_override_foldtext", 1)
+                setlocal foldtext=Foldtext_markdown()
+            endif
+        endif
+        setlocal foldexpr=Foldexpr_markdown(v:lnum)
+        setlocal foldmethod=expr
+    endif
 endfunction
+
+function! s:MarkdownSetupFoldLevel()
+    if get(g:, "vim_markdown_folding_style_pythonic", 0)
+        " set default foldlevel
+        execute "setlocal foldlevel=".s:vim_markdown_folding_level
+    endif
+endfunction
+
+call s:MarkdownSetupFoldLevel()
 call s:MarkdownSetupFolding()
+
 augroup Mkd
     " These autocmds need to be kept in sync with the autocmds calling
     " s:MarkdownRefreshSyntax in ftplugin/markdown.vim.
diff --git a/sources_non_forked/vim-markdown/doc/vim-markdown.txt b/sources_non_forked/vim-markdown/doc/vim-markdown.txt
index 4e1c487e..4d731293 100644
--- a/sources_non_forked/vim-markdown/doc/vim-markdown.txt
+++ b/sources_non_forked/vim-markdown/doc/vim-markdown.txt
@@ -52,7 +52,7 @@ and extensions.
                                                     *vim-markdown-installation*
 Installation ~
 
-If you use Vundle [2], add the following line to your '~/.vimrc':
+If you use Vundle [2], add the following lines to your '~/.vimrc':
 >
   Plugin 'godlygeek/tabular'
   Plugin 'plasticboy/vim-markdown'
@@ -133,159 +133,195 @@ Options ~
 
 -------------------------------------------------------------------------------
                                                  *vim-markdown-disable-folding*
-                                              *g:vim_markdown_folding_disabled*
 Disable Folding ~
 
-Add the following line to your '.vimrc' to disable the folding configuration:
+                                              *g:vim_markdown_folding_disabled*
+- 'g:vim_markdown_folding_disabled'
+
+  Add the following line to your '.vimrc' to disable the folding
+  configuration:
 >
   let g:vim_markdown_folding_disabled = 1
 <
-This option only controls Vim Markdown specific folding configuration.
+  This option only controls Vim Markdown specific folding configuration.
 
-To enable/disable folding use Vim's standard folding configuration.
+  To enable/disable folding use Vim's standard folding configuration.
 >
   set [no]foldenable
 <
 -------------------------------------------------------------------------------
                                                *vim-markdown-change-fold-style*
-                                        *g:vim_markdown_folding_style_pythonic*
-                                             *g:vim_markdown_override_foldtext*
 Change fold style ~
 
-To fold in a style like python-mode [6], add the following to your '.vimrc':
+                                        *g:vim_markdown_folding_style_pythonic*
+- 'g:vim_markdown_folding_style_pythonic'
+
+  To fold in a style like python-mode [6], add the following to your
+  '.vimrc':
 >
   let g:vim_markdown_folding_style_pythonic = 1
 <
-Level 1 heading which is served as a document title is not folded.
-'g:vim_markdown_folding_level' setting is not active with this fold style.
+  'g:vim_markdown_folding_level' setting (default 1) is set to 'foldlevel'.
+  Thus level 1 heading which is served as a document title is expanded by
+  default.
 
-To prevent foldtext from being set add the following to your '.vimrc':
+                                             *g:vim_markdown_override_foldtext*
+- 'g:vim_markdown_override_foldtext'
+
+  To prevent foldtext from being set add the following to your '.vimrc':
 >
   let g:vim_markdown_override_foldtext = 0
 <
 -------------------------------------------------------------------------------
                                         *vim-markdown-set-header-folding-level*
-                                                 *g:vim_markdown_folding_level*
 Set header folding level ~
 
-Folding level is a number between 1 and 6. By default, if not specified, it is
-set to 1.
+                                                 *g:vim_markdown_folding_level*
+- 'g:vim_markdown_folding_level'
+
+  Folding level is a number between 1 and 6. By default, if not specified, it
+  is set to 1.
 >
   let g:vim_markdown_folding_level = 6
 <
-Tip: it can be changed on the fly with:
+  Tip: it can be changed on the fly with:
 >
   :let g:vim_markdown_folding_level = 1
   :edit
 <
 -------------------------------------------------------------------------------
                                     *vim-markdown-disable-default-key-mappings*
-                                       *g:vim_markdown_no_default_key_mappings*
 Disable Default Key Mappings ~
 
-Add the following line to your '.vimrc' to disable default key mappings:
+                                       *g:vim_markdown_no_default_key_mappings*
+- 'g:vim_markdown_no_default_key_mappings'
+
+  Add the following line to your '.vimrc' to disable default key mappings:
 >
   let g:vim_markdown_no_default_key_mappings = 1
 <
-You can also map them by yourself with '<Plug>' mappings.
+  You can also map them by yourself with '<Plug>' mappings.
 
 -------------------------------------------------------------------------------
                                       *vim-markdown-enable-toc-window-auto-fit*
-                                                   *g:vim_markdown_toc_autofit*
 Enable TOC window auto-fit ~
 
-Allow for the TOC window to auto-fit when it's possible for it to shrink. It
-never increases its default size (half screen), it only shrinks.
+                                                   *g:vim_markdown_toc_autofit*
+- 'g:vim_markdown_toc_autofit'
+
+  Allow for the TOC window to auto-fit when it's possible for it to shrink.
+  It never increases its default size (half screen), it only shrinks.
 >
   let g:vim_markdown_toc_autofit = 1
 <
 -------------------------------------------------------------------------------
                        *vim-markdown-text-emphasis-restriction-to-single-lines*
-                                            *g:vim_markdown_emphasis_multiline*
 Text emphasis restriction to single-lines ~
 
-By default text emphasis works across multiple lines until a closing token is
-found. However, it's possible to restrict text emphasis to a single line (i.e.,
-for it to be applied a closing token must be found on the same line). To do so:
+                                            *g:vim_markdown_emphasis_multiline*
+- 'g:vim_markdown_emphasis_multiline'
+
+  By default text emphasis works across multiple lines until a closing token
+  is found. However, it's possible to restrict text emphasis to a single line
+  (i.e., for it to be applied a closing token must be found on the same
+  line). To do so:
 >
   let g:vim_markdown_emphasis_multiline = 0
 <
 -------------------------------------------------------------------------------
                                                *vim-markdown-syntax-concealing*
-                                                       *g:vim_markdown_conceal*
 Syntax Concealing ~
 
-Concealing is set for some syntax.
+                                                       *g:vim_markdown_conceal*
+- 'g:vim_markdown_conceal'
 
-For example, conceal '[link text](link url)' as just 'link text'. Also,
-'_italic_' and '*italic*' will conceal to just _italic_. Similarly '__bold__',
-'**bold**', '___italic bold___', and '***italic bold***' will conceal to just
-**bold**, **bold**, **_italic bold_**, and **_italic bold_** respectively.
+  Concealing is set for some syntax.
 
-To enable conceal use Vim's standard conceal configuration.
+  For example, conceal '[link text](link url)' as just 'link text'. Also,
+  '_italic_' and '*italic*' will conceal to just _italic_. Similarly
+  '__bold__', '**bold**', '___italic bold___', and '***italic bold***' will
+  conceal to just **bold**, **bold**, **_italic bold_**, and **_italic
+  bold_** respectively.
+
+  To enable conceal use Vim's standard conceal configuration.
 >
   set conceallevel=2
 <
-To disable conceal regardless of 'conceallevel' setting, add the following to
-your '.vimrc':
+  To disable conceal regardless of 'conceallevel' setting, add the following
+  to your '.vimrc':
 >
   let g:vim_markdown_conceal = 0
 <
-To disable math conceal with LaTeX math syntax enabled, add the following to
-your '.vimrc':
+  To disable math conceal with LaTeX math syntax enabled, add the following
+  to your '.vimrc':
 >
   let g:tex_conceal = ""
   let g:vim_markdown_math = 1
+<
+                                           *g:vim_markdown_conceal_code_blocks*
+- 'g:vim_markdown_conceal_code_blocks'
+
+  Disabling conceal for code fences requires an additional setting:
+>
+  let g:vim_markdown_conceal_code_blocks = 0
 <
 -------------------------------------------------------------------------------
                                      *vim-markdown-fenced-code-block-languages*
-                                              *g:vim_markdown_fenced_languages*
 Fenced code block languages ~
 
-You can use filetype name as fenced code block languages for syntax
-highlighting. If you want to use different name from filetype, you can add it
-in your '.vimrc' like so:
+                                              *g:vim_markdown_fenced_languages*
+- 'g:vim_markdown_fenced_languages'
+
+  You can use filetype name as fenced code block languages for syntax
+  highlighting. If you want to use different name from filetype, you can add
+  it in your '.vimrc' like so:
 >
   let g:vim_markdown_fenced_languages = ['csharp=cs']
 <
-This will cause the following to be highlighted using the 'cs' filetype syntax.
+  This will cause the following to be highlighted using the 'cs' filetype
+  syntax.
 >
   ```csharp
   ...
   ```
 <
-Default is "['c++=cpp', 'viml=vim', 'bash=sh', 'ini=dosini']".
+  Default is "['c++=cpp', 'viml=vim', 'bash=sh', 'ini=dosini']".
 
 -------------------------------------------------------------------------------
                                             *vim-markdown-follow-named-anchors*
-                                                 *g:vim_markdown_follow_anchor*
-                                                    *g:vim_markdown_anchorexpr*
 Follow named anchors ~
 
-This feature allows the 'ge' command to follow named anchors in links of the
-form 'file#anchor' or just '#anchor', where file may omit the '.md' extension
-as usual. Two variables control its operation:
+                                                 *g:vim_markdown_follow_anchor*
+- 'g:vim_markdown_follow_anchor'
+
+  This feature allows the 'ge' command to follow named anchors in links of
+  the form 'file#anchor' or just '#anchor', where file may omit the '.md'
+  extension as usual. Two variables control its operation:
 >
   let g:vim_markdown_follow_anchor = 1
 <
-This tells vim-markdown whether to attempt to follow a named anchor in a link
-or not. When it is 1, and only if a link can be split in two parts by the
-pattern '#', then the first part is interpreted as the file and the second one
-as the named anchor. This also includes urls of the form '#anchor', for which
-the first part is considered empty, meaning that the target file is the current
-one. After the file is opened, the anchor will be searched.
+  This tells vim-markdown whether to attempt to follow a named anchor in a
+  link or not. When it is 1, and only if a link can be split in two parts by
+  the pattern '#', then the first part is interpreted as the file and the
+  second one as the named anchor. This also includes urls of the form
+  '#anchor', for which the first part is considered empty, meaning that the
+  target file is the current one. After the file is opened, the anchor will
+  be searched.
 
-Default is '0'.
+  Default is '0'.
+
+                                                    *g:vim_markdown_anchorexpr*
+- 'g:vim_markdown_anchorexpr'
 >
   let g:vim_markdown_anchorexpr = "'<<'.v:anchor.'>>'"
 <
-This expression will be evaluated substituting 'v:anchor' with a quoted string
-that contains the anchor to visit. The result of the evaluation will become the
-real anchor to search in the target file. This is useful in order to convert
-anchors of the form, say, 'my-section-title' to searches of the form 'My
-Section Title' or '<<my-section-title>>'.
+  This expression will be evaluated substituting 'v:anchor' with a quoted
+  string that contains the anchor to visit. The result of the evaluation will
+  become the real anchor to search in the target file. This is useful in
+  order to convert anchors of the form, say, 'my-section-title' to searches
+  of the form 'My Section Title' or '<<my-section-title>>'.
 
-Default is "''".
+  Default is "''".
 
 -------------------------------------------------------------------------------
                                                *vim-markdown-syntax-extensions*
@@ -296,136 +332,161 @@ are off by default.
 
 -------------------------------------------------------------------------------
                                                       *vim-markdown-latex-math*
-                                                          *g:vim_markdown_math*
 LaTeX math ~
 
-Used as '$x^2$', '$$x^2$$', escapable as '\$x\$' and '\$\$x\$\$'.
+                                                          *g:vim_markdown_math*
+- 'g:vim_markdown_math'
+
+  Used as '$x^2$', '$$x^2$$', escapable as '\$x\$' and '\$\$x\$\$'.
 >
   let g:vim_markdown_math = 1
 <
 -------------------------------------------------------------------------------
                                                *vim-markdown-yaml-front-matter*
-                                                   *g:vim_markdown_frontmatter*
 YAML Front Matter ~
 
-Highlight YAML front matter as used by Jekyll or Hugo [7].
+                                                   *g:vim_markdown_frontmatter*
+- 'g:vim_markdown_frontmatter'
+
+  Highlight YAML front matter as used by Jekyll or Hugo [7].
 >
   let g:vim_markdown_frontmatter = 1
 <
 -------------------------------------------------------------------------------
                                                *vim-markdown-toml-front-matter*
-                                              *g:vim_markdown_toml_frontmatter*
 TOML Front Matter ~
 
-Highlight TOML front matter as used by Hugo [7].
+                                              *g:vim_markdown_toml_frontmatter*
+- 'g:vim_markdown_toml_frontmatter'
 
-TOML syntax highlight requires vim-toml [8].
+  Highlight TOML front matter as used by Hugo [7].
+
+  TOML syntax highlight requires vim-toml [8].
 >
   let g:vim_markdown_toml_frontmatter = 1
 <
 -------------------------------------------------------------------------------
                                                *vim-markdown-json-front-matter*
-                                              *g:vim_markdown_json_frontmatter*
 JSON Front Matter ~
 
-Highlight JSON front matter as used by Hugo [7].
+                                              *g:vim_markdown_json_frontmatter*
+- 'g:vim_markdown_json_frontmatter'
 
-JSON syntax highlight requires vim-json [9].
+  Highlight JSON front matter as used by Hugo [7].
+
+  JSON syntax highlight requires vim-json [9].
 >
   let g:vim_markdown_json_frontmatter = 1
 <
 -------------------------------------------------------------------------------
                                                    *vim-markdown-strikethrough*
-                                                 *g:vim_markdown_strikethrough*
 Strikethrough ~
 
-Strikethrough uses two tildes. '~~Scratch this.~~'
+                                                 *g:vim_markdown_strikethrough*
+- 'g:vim_markdown_strikethrough'
+
+  Strikethrough uses two tildes. '~~Scratch this.~~'
 >
   let g:vim_markdown_strikethrough = 1
 <
 -------------------------------------------------------------------------------
                                      *vim-markdown-adjust-new-list-item-indent*
-                                          *g:vim_markdown_new_list_item_indent*
 Adjust new list item indent ~
 
-You can adjust a new list indent. For example, you insert a single line like
-below:
+                                          *g:vim_markdown_new_list_item_indent*
+- 'g:vim_markdown_new_list_item_indent'
+
+  You can adjust a new list indent. For example, you insert a single line
+  like below:
 >
   * item1
 <
-Then if you type 'o' to insert new line in vim and type '* item2', the result
-will be:
+  Then if you type 'o' to insert new line in vim and type '* item2', the
+  result will be:
 >
   * item1
       * item2
 <
-vim-markdown automatically insert the indent. By default, the number of spaces
-of indent is 4. If you'd like to change the number as 2, just write:
+  vim-markdown automatically insert the indent. By default, the number of
+  spaces of indent is 4. If you'd like to change the number as 2, just write:
 >
   let g:vim_markdown_new_list_item_indent = 2
 <
 -------------------------------------------------------------------------------
                 *vim-markdown-do-not-require-.md-extensions-for-markdown-links*
-                                     *g:vim_markdown_no_extensions_in_markdown*
 Do not require .md extensions for Markdown links ~
 
-If you want to have a link like this '[link text](link-url)' and follow it for
-editing in vim using the 'ge' command, but have it open the file "link-url.md"
-instead of the file "link-url", then use this option:
+                                     *g:vim_markdown_no_extensions_in_markdown*
+- 'g:vim_markdown_no_extensions_in_markdown'
+
+  If you want to have a link like this '[link text](link-url)' and follow it
+  for editing in vim using the 'ge' command, but have it open the file "link-
+  url.md" instead of the file "link-url", then use this option:
 >
   let g:vim_markdown_no_extensions_in_markdown = 1
 <
-This is super useful for GitLab and GitHub wiki repositories.
+  This is super useful for GitLab and GitHub wiki repositories.
 
-Normal behaviour would be that vim-markup required you to do this '[link text
-](link-url.md)', but this is not how the Gitlab and GitHub wiki repositories
-work. So this option adds some consistency between the two.
+  Normal behaviour would be that vim-markup required you to do this '[link
+  text](link-url.md)', but this is not how the Gitlab and GitHub wiki
+  repositories work. So this option adds some consistency between the two.
 
 -------------------------------------------------------------------------------
                                   *vim-markdown-auto-write-when-following-link*
-                                                     *g:vim_markdown_autowrite*
 Auto-write when following link ~
 
-If you follow a link like this '[link text](link-url)' using the 'ge' shortcut,
-this option will automatically save any edits you made before moving you:
+                                                     *g:vim_markdown_autowrite*
+- 'g:vim_markdown_autowrite'
+
+  If you follow a link like this '[link text](link-url)' using the 'ge'
+  shortcut, this option will automatically save any edits you made before
+  moving you:
 >
   let g:vim_markdown_autowrite = 1
 <
 -------------------------------------------------------------------------------
                                    *vim-markdown-change-default-file-extension*
-                                            *g:vim_markdown_auto_extension_ext*
 Change default file extension ~
 
-If you would like to use a file extension other than '.md' you may do so using
-the 'vim_markdown_auto_extension_ext' variable:
+                                            *g:vim_markdown_auto_extension_ext*
+- 'g:vim_markdown_auto_extension_ext'
+
+  If you would like to use a file extension other than '.md' you may do so
+  using the 'vim_markdown_auto_extension_ext' variable:
 >
   let g:vim_markdown_auto_extension_ext = 'txt'
 <
 -------------------------------------------------------------------------------
                         *vim-markdown-do-not-automatically-insert-bulletpoints*
-                                           *g:vim_markdown_auto_insert_bullets*
 Do not automatically insert bulletpoints ~
 
-Automatically inserting bulletpoints can lead to problems when wrapping text
-(see issue #232 for details), so it can be disabled:
+                                           *g:vim_markdown_auto_insert_bullets*
+- 'g:vim_markdown_auto_insert_bullets'
+
+  Automatically inserting bulletpoints can lead to problems when wrapping
+  text (see issue #232 for details), so it can be disabled:
 >
   let g:vim_markdown_auto_insert_bullets = 0
 <
-In that case, you probably also want to set the new list item indent to 0 as
-well, or you will have to remove an indent each time you add a new list item:
+  In that case, you probably also want to set the new list item indent to 0
+  as well, or you will have to remove an indent each time you add a new list
+  item:
 >
   let g:vim_markdown_new_list_item_indent = 0
 <
 -------------------------------------------------------------------------------
                                     *vim-markdown-change-how-to-open-new-files*
-                                                   *g:vim_markdown_edit_url_in*
 Change how to open new files ~
 
-By default when following a link the target file will be opened in your current
-buffer. This behavior can change if you prefer using splits or tabs by using
-the 'vim_markdown_edit_url_in' variable. Possible values are 'tab', 'vsplit',
-'hsplit', 'current' opening in a new tab, vertical split, horizontal split, and
-current buffer respectively. Defaults to current buffer if not set:
+                                                   *g:vim_markdown_edit_url_in*
+- 'g:vim_markdown_edit_url_in'
+
+  By default when following a link the target file will be opened in your
+  current buffer. This behavior can change if you prefer using splits or tabs
+  by using the 'vim_markdown_edit_url_in' variable. Possible values are
+  'tab', 'vsplit', 'hsplit', 'current' opening in a new tab, vertical split,
+  horizontal split, and current buffer respectively. Defaults to current
+  buffer if not set:
 >
   let g:vim_markdown_edit_url_in = 'tab'
 <
diff --git a/sources_non_forked/vim-markdown/syntax/markdown.vim b/sources_non_forked/vim-markdown/syntax/markdown.vim
index d8d34ea1..c1a2b2ca 100644
--- a/sources_non_forked/vim-markdown/syntax/markdown.vim
+++ b/sources_non_forked/vim-markdown/syntax/markdown.vim
@@ -151,11 +151,11 @@ endif
 
 " Strike through
 if get(g:, 'vim_markdown_strikethrough', 0)
-    syn region mkdStrike matchgroup=mkdStrike start="\%(\~\~\)"    end="\%(\~\~\)"
+    execute 'syn region mkdStrike matchgroup=htmlStrike start="\%(\~\~\)" end="\%(\~\~\)"' . s:concealends
     HtmlHiLink mkdStrike        htmlStrike
 endif
 
-syn cluster mkdNonListItem contains=@htmlTop,htmlItalic,htmlBold,htmlBoldItalic,mkdFootnotes,mkdInlineURL,mkdLink,mkdLinkDef,mkdLineBreak,mkdBlockquote,mkdCode,mkdRule,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,mkdMath,htmlStrike
+syn cluster mkdNonListItem contains=@htmlTop,htmlItalic,htmlBold,htmlBoldItalic,mkdFootnotes,mkdInlineURL,mkdLink,mkdLinkDef,mkdLineBreak,mkdBlockquote,mkdCode,mkdRule,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,mkdMath,mkdStrike
 
 "highlighting for Markdown groups
 HtmlHiLink mkdString        String
diff --git a/sources_non_forked/vim-markdown/test/python-folding.vader b/sources_non_forked/vim-markdown/test/python-folding.vader
index 91fc9e27..9196ea60 100644
--- a/sources_non_forked/vim-markdown/test/python-folding.vader
+++ b/sources_non_forked/vim-markdown/test/python-folding.vader
@@ -21,17 +21,16 @@ This is code block
 foobar
 
 Execute (fold level # in code block):
-  AssertEqual foldlevel(1), 0, '# Title'
-  AssertEqual foldlevel(3), 1, '## Chapter 1'
-  AssertEqual foldlevel(7), 1, '# This is just a comment'
-  AssertEqual foldlevel(8), 1, '```'
-  AssertEqual foldlevel(10), 1, '## Chapter 2'
-  AssertEqual foldlevel(12), 1, 'foobar'
+  AssertEqual foldlevel(1), 1, '# Title'
+  AssertEqual foldlevel(3), 2, '## Chapter 1'
+  AssertEqual foldlevel(7), 2, '# This is just a comment'
+  AssertEqual foldlevel(8), 2, '```'
+  AssertEqual foldlevel(10), 2, '## Chapter 2'
+  AssertEqual foldlevel(12), 2, 'foobar'
 
 Execute (fold text of chapters):
   let b:width = winwidth(0)
   let b:hyphen = repeat('-', b:width - 18 > 2 ? b:width - 18 : b:width - 9 > 0 ? 3 : 2)
-  AssertEqual foldtextresult(3), strpart('## Chapter 1', 0, b:width - 9) . ' ' . b:hyphen . ' 6'
   AssertEqual foldtextresult(10), strpart('## Chapter 2', 0, b:width - 9) . ' ' . b:hyphen . ' 2'
 
 Given markdown;
@@ -59,7 +58,7 @@ foobar
 Execute (fold any preamble):
   AssertEqual foldlevel(1), 1, 'Headline'
   AssertEqual foldlevel(3), 1, 'foobar'
-  AssertEqual foldlevel(5), 0, '# Title'
+  AssertEqual foldlevel(5), 1, '# Title'
 
 Given markdown;
 ---
diff --git a/sources_non_forked/vim-markdown/test/toc.vader b/sources_non_forked/vim-markdown/test/toc.vader
index 2510edc7..51269526 100644
--- a/sources_non_forked/vim-markdown/test/toc.vader
+++ b/sources_non_forked/vim-markdown/test/toc.vader
@@ -175,10 +175,6 @@ Given markdown;
 ### header 3
 
 Execute (Toc cursor on the current header):
-  normal! 4G
-  :Toc
-  AssertEqual line('.'), 2
-  :lclose
   normal! G
   :Toc
   AssertEqual line('.'), 3
diff --git a/sources_non_forked/vim-multiple-cursors/README.md b/sources_non_forked/vim-multiple-cursors/README.md
index ac5093e3..1f7e1be7 100644
--- a/sources_non_forked/vim-multiple-cursors/README.md
+++ b/sources_non_forked/vim-multiple-cursors/README.md
@@ -61,10 +61,10 @@ call plug#end()
     * next:         `<C-n>` add a new _virtual cursor + selection_ on the next match
     * skip:         `<C-x>` skip the next match
     * prev:         `<C-p>` remove current _virtual cursor + selection_ and go back on previous match
-  * select all:     `<A-n>` start muticursor and directly select all matches
+  * select all:     `<A-n>` start multicursor and directly select all matches
 
-You can now change the _virtual cursors + selection_ with **visual mode** commands.  
-For instance: `c`, `s`, `I`, `A` work without any issues.  
+You can now change the _virtual cursors + selection_ with **visual mode** commands.
+For instance: `c`, `s`, `I`, `A` work without any issues.
 You could also go to **normal mode** by pressing `v` and use normal commands there.
 
 At any time, you can press `<Esc>` to exit back to regular Vim.
@@ -74,11 +74,11 @@ At any time, you can press `<Esc>` to exit back to regular Vim.
 ### visual mode when multiple lines are selected
   * start: `<C-n>` add _virtual cursors_ on each line
 
-You can now change the _virtual cursors_ with **normal mode** commands.  
+You can now change the _virtual cursors_ with **normal mode** commands.
 For instance: `ciw`.
 
 ### command
-The command `MultipleCursorsFind` accepts a range and a pattern (regexp), it creates a _visual cursor_ at the end of each match.  
+The command `MultipleCursorsFind` accepts a range and a pattern (regexp), it creates a _visual cursor_ at the end of each match.
 If no range is passed in, then it defaults to the entire buffer.
 
 
@@ -103,20 +103,20 @@ let g:multi_cursor_quit_key            = '<Esc>'
 ## Settings
 Currently there are four additional global settings one can tweak:
 
-### ```g:multi_cursor_exit_from_visual_mode``` (Default: 1)
-If set to 0, then pressing `g:multi_cursor_quit_key` in _Visual_ mode will not quit and delete all existing cursors.  
-Useful if you want to go back to Normal mode, and still be able to operate on all the cursors.
+### ```g:multi_cursor_exit_from_visual_mode``` (Default: 0)
+If set to 1, then pressing `g:multi_cursor_quit_key` in _Visual_ mode will quit and
+delete all existing cursors, just skipping normal mode with multiple cursors.
 
-### ```g:multi_cursor_exit_from_insert_mode``` (Default: 1)
-If set to 0, then pressing `g:multi_cursor_quit_key` in _Insert_ mode will not quit and delete all existing cursors.  
-Useful if you want to go back to Normal mode, and still be able to operate on all the cursors.
+### ```g:multi_cursor_exit_from_insert_mode``` (Default: 0)
+If set to 1, then pressing `g:multi_cursor_quit_key` in _Insert_ mode will quit and
+delete all existing cursors, just skipping normal mode with multiple cursors.
 
 ### ```g:multi_cursor_normal_maps``` (Default: see below)
 `{'@': 1, 'F': 1, 'T': 1, '[': 1, '\': 1, ']': 1, '!': 1, '"': 1, 'c': 1, 'd': 1, 'f': 1, 'g': 1, 'm': 1, 'q': 1, 'r': 1, 't': 1, 'y': 1, 'z': 1, '<': 1, '=': 1, '>': 1}`
 
 Any key in this map (values are ignored) will cause multi-cursor _Normal_ mode
 to pause for map completion just like normal vim. Otherwise keys mapped in
-normal mode will "fail to replay" when multiple cursors are active.  
+normal mode will "fail to replay" when multiple cursors are active.
 For example: `{'d':1}` makes normal-mode command `dw` work in multi-cursor mode.
 
 The default list contents should work for anybody, unless they have remapped a
@@ -136,7 +136,7 @@ Same principle as `g:multi_cursor_normal_maps`
 
 ### ```Multiple_cursors_before/Multiple_cursors_after``` (Default: `nothing`)
 
-Other plugins may be incompatible in insert mode.  
+Other plugins may be incompatible in insert mode.
 That is why we provide hooks to disable those plug-ins when vim-multiple-cursors is active:
 
 For example, if you are using [Neocomplete](https://github.com/Shougo/neocomplete.vim),
@@ -171,7 +171,7 @@ highlight link multiple_cursors_visual Visual
 ## FAQ
 
 #### **Q** <kbd>ALT</kbd>+<kbd>n</kbd> doesn't seem to work in VIM but works in gVIM, why?
-**A** This is a well known terminal/Vim [issue](http://vim.wikia.com/wiki/Get_Alt_key_to_work_in_terminal), different terminal have different ways to send ```Alt+key```.  
+**A** This is a well known terminal/Vim [issue](http://vim.wikia.com/wiki/Get_Alt_key_to_work_in_terminal), different terminal have different ways to send ```Alt+key```.
 Try adding this in your `.vimrc` and **make sure to replace the string**:
 ```vim
 if !has('gui_running')
diff --git a/sources_non_forked/vim-multiple-cursors/doc/multiple_cursors.txt b/sources_non_forked/vim-multiple-cursors/doc/multiple_cursors.txt
index b3b26c49..219853f7 100644
--- a/sources_non_forked/vim-multiple-cursors/doc/multiple_cursors.txt
+++ b/sources_non_forked/vim-multiple-cursors/doc/multiple_cursors.txt
@@ -94,17 +94,15 @@ otherwise you'll have a tough time quitting from multicursor mode.
 
 Currently there are four additional global settings one can tweak:
 
-*g:multi_cursor_exit_from_visual_mode* (Default: 1)
+*g:multi_cursor_exit_from_visual_mode* (Default: 0)
 
-If set to 0, then pressing |g:multi_cursor_quit_key| in |visual-mode| will not
-quit and delete all existing cursors. Useful if you want to go back to
-|normal-mode|, and still be able to operate on all the cursors.
+If set to 0, then pressing |g:multi_cursor_quit_key| in |visual-mode| will quit
+and delete all existing cursors, skipping normal mode with multiple cursors.
 
-*g:multi_cursor_exit_from_insert_mode* (Default: 1)
+*g:multi_cursor_exit_from_insert_mode* (Default: 0)
 
-If set to 0, then pressing |g:multi_cursor_quit_key| in |insert-mode| will not
-quit and delete all existing cursors. Useful if you want to go back to Normal
-mode, and still be able to operate on all the cursors.
+If set to 1, then pressing |g:multi_cursor_quit_key| in |insert-mode| will quit
+and delete all existing cursors, skipping normal mode with multiple cursors.
 
 *g:multi_cursor_normal_maps* (Default: see below)
 
diff --git a/sources_non_forked/vim-multiple-cursors/plugin/multiple_cursors.vim b/sources_non_forked/vim-multiple-cursors/plugin/multiple_cursors.vim
index ef84cab5..0f6e41f4 100644
--- a/sources_non_forked/vim-multiple-cursors/plugin/multiple_cursors.vim
+++ b/sources_non_forked/vim-multiple-cursors/plugin/multiple_cursors.vim
@@ -27,8 +27,8 @@ endfunction
 
 " Settings
 let s:settings = {
-      \ 'exit_from_visual_mode': 1,
-      \ 'exit_from_insert_mode': 1,
+      \ 'exit_from_visual_mode': 0,
+      \ 'exit_from_insert_mode': 0,
       \ 'use_default_mapping': 1,
       \ 'debug_latency': 0,
       \ }
diff --git a/sources_non_forked/vim-multiple-cursors/spec/multiple_cursors_spec.rb b/sources_non_forked/vim-multiple-cursors/spec/multiple_cursors_spec.rb
index 1f817bfa..867e665d 100644
--- a/sources_non_forked/vim-multiple-cursors/spec/multiple_cursors_spec.rb
+++ b/sources_non_forked/vim-multiple-cursors/spec/multiple_cursors_spec.rb
@@ -175,7 +175,9 @@ describe "Multiple Cursors when using insert mappings" do
   let(:options) { ['set timeoutlen=10000',
                    'imap jj <esc>',
                    'imap jojo dude',
-                   'imap jk <esc>:%s/bla/hey/g<cr>'] }
+                   'imap jk <esc>:%s/bla/hey/g<cr>',
+                   'let g:multi_cursor_exit_from_insert_mode = 1',
+                   'let g:multi_cursor_exit_from_visual_mode = 1'] }
   specify "#mapping doing <Esc>" do
     before <<-EOF
       hello world!
diff --git a/sources_non_forked/vim-repeat/README.markdown b/sources_non_forked/vim-repeat/README.markdown
index f8b44699..448d2d6d 100644
--- a/sources_non_forked/vim-repeat/README.markdown
+++ b/sources_non_forked/vim-repeat/README.markdown
@@ -12,6 +12,7 @@ The following plugins support repeat.vim:
 * [speeddating.vim](https://github.com/tpope/vim-speeddating)
 * [unimpaired.vim](https://github.com/tpope/vim-unimpaired)
 * [vim-easyclip](https://github.com/svermeulen/vim-easyclip)
+* [vim-radical](https://github.com/glts/vim-radical)
 
 Adding support to a plugin is generally as simple as the following
 command at the end of your map functions.
diff --git a/sources_non_forked/vim-snippets/UltiSnips/html.snippets b/sources_non_forked/vim-snippets/UltiSnips/html.snippets
index 924f02fd..a81b1d88 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/html.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/html.snippets
@@ -333,6 +333,10 @@ snippet mailto "HTML <a mailto: >" w
 <a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a>
 endsnippet
 
+snippet tel "HTML <a tel: >" w
+<a href="tel:+${1:XX1234567890}">${2:call me}</a>
+endsnippet
+
 snippet main "<main>"
 <main>
 	${1:main content}
diff --git a/sources_non_forked/vim-snippets/UltiSnips/javascript-node.snippets b/sources_non_forked/vim-snippets/UltiSnips/javascript-node.snippets
index e4a64e95..a46ed7f0 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/javascript-node.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/javascript-node.snippets
@@ -1,6 +1,6 @@
 priority -50
 
-snippet #! "shebang"
+snippet #! "#!/usr/bin/env node" b
 #!/usr/bin/env node
 endsnippet
 
diff --git a/sources_non_forked/vim-snippets/UltiSnips/lua.snippets b/sources_non_forked/vim-snippets/UltiSnips/lua.snippets
index b6d0c1a3..0fd5eefc 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/lua.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/lua.snippets
@@ -3,7 +3,7 @@ priority -50
 #################################
 # Snippets for the Lua language #
 #################################
-snippet #! "Shebang header" b
+snippet #! "#!/usr/bin/env lua" b
 #!/usr/bin/env lua
 $0
 endsnippet
diff --git a/sources_non_forked/vim-snippets/UltiSnips/python.snippets b/sources_non_forked/vim-snippets/UltiSnips/python.snippets
index a6c7416e..cdbe517d 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/python.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/python.snippets
@@ -5,8 +5,12 @@ priority -50
 ###########################################################################
 
 #! header
-snippet #! "Shebang header for python scripts" b
+snippet #! "#!/usr/bin/env python" b
 #!/usr/bin/env python
+$0
+endsnippet
+
+snippet "^# ?[uU][tT][fF]-?8" "# encoding: UTF-8" r
 # -*- coding: utf-8 -*-
 $0
 endsnippet
@@ -267,7 +271,7 @@ class ${1:MyClass}(${2:object}):
 	`!p snip.rv = triple_quotes(snip)`${3:Docstring for $1. }`!p snip.rv = triple_quotes(snip)`
 
 	def __init__(self$4):
-		`!p snip.rv = triple_quotes(snip)`${5:TODO: to be defined1.}`!p
+		`!p snip.rv = triple_quotes(snip)`${5:TODO: to be defined.}`!p
 snip.rv = ""
 snip >> 2
 
diff --git a/sources_non_forked/vim-snippets/UltiSnips/r.snippets b/sources_non_forked/vim-snippets/UltiSnips/r.snippets
index f81b0c9c..773880b5 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/r.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/r.snippets
@@ -15,8 +15,9 @@ FIELD_TYPES = [
 'vector']
 endglobal
 
-snippet #! "Hashbang for Rscript (#!)" b
+snippet #! "#!/usr/bin/env Rscript" b
 #!/usr/bin/env Rscript
+$0
 endsnippet
 
 snippet setwd "Set workingdir" b
diff --git a/sources_non_forked/vim-snippets/UltiSnips/ruby.snippets b/sources_non_forked/vim-snippets/UltiSnips/ruby.snippets
index cb90a9db..7b360ffa 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/ruby.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/ruby.snippets
@@ -21,7 +21,7 @@ endglobal
 # Snippets
 #
 
-snippet "^#!" "#!/usr/bin/env ruby" r
+snippet #! "#!/usr/bin/env ruby" b
 #!/usr/bin/env ruby
 $0
 endsnippet
diff --git a/sources_non_forked/vim-snippets/UltiSnips/sh.snippets b/sources_non_forked/vim-snippets/UltiSnips/sh.snippets
index 611b1ce3..9bacc725 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/sh.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/sh.snippets
@@ -25,12 +25,8 @@ endglobal
 ###########################################################################
 #                            TextMate Snippets                            #
 ###########################################################################
-snippet #!
-`!p snip.rv = '#!/bin/' + getShell() + "\n\n" `
-endsnippet
-
-snippet !env "#!/usr/bin/env (!env)"
-`!p snip.rv = '#!/usr/bin/env ' + getShell() + "\n\n" `
+snippet #! "#!/usr/bin/env (!env)" b
+`!p snip.rv = '#!/usr/bin/env ' + getShell() + "\n" `
 endsnippet
 
 snippet sbash "safe bash options"
diff --git a/sources_non_forked/vim-snippets/UltiSnips/tex.snippets b/sources_non_forked/vim-snippets/UltiSnips/tex.snippets
index b3383aec..355d9e46 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/tex.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/tex.snippets
@@ -85,7 +85,7 @@ snippet fig "Figure environment" b
 \begin{figure}[${2:htpb}]
 	\centering
 	\includegraphics[width=${3:0.8}\linewidth]{${4:name.ext}}
-	\caption{${4/(\w+)\.\w+/\u$1/}$0}
+	\caption{${4/(\w+)\.\w+/\u$1/}$0}%
 	\label{fig:${4/(\w+)\.\w+/$1/}}
 \end{figure}
 endsnippet
diff --git a/sources_non_forked/vim-snippets/UltiSnips/zsh.snippets b/sources_non_forked/vim-snippets/UltiSnips/zsh.snippets
index f7986ea5..678fbd19 100644
--- a/sources_non_forked/vim-snippets/UltiSnips/zsh.snippets
+++ b/sources_non_forked/vim-snippets/UltiSnips/zsh.snippets
@@ -4,14 +4,9 @@ extends sh
 
 priority -49
 
-snippet #! "shebang" b
-#!/bin/zsh
-
-endsnippet
-
-snippet !env "#!/usr/bin/env (!env)" b
+snippet #! "#!/usr/bin/env zsh" b
 #!/usr/bin/env zsh
-
+$0
 endsnippet
 
 # vim:ft=snippets:
diff --git a/sources_non_forked/vim-snippets/snippets/cpp.snippets b/sources_non_forked/vim-snippets/snippets/cpp.snippets
index f47a6834..f39d743e 100644
--- a/sources_non_forked/vim-snippets/snippets/cpp.snippets
+++ b/sources_non_forked/vim-snippets/snippets/cpp.snippets
@@ -62,9 +62,13 @@ snippet pqueue
 # std::shared_ptr
 snippet msp
 	std::shared_ptr<${1:T}> ${2} = std::make_shared<$1>(${3});
+snippet amsp
+	auto ${1} = std::make_shared<${2:T}>(${3});
 # std::unique_ptr
 snippet mup
 	std::unique_ptr<${1:T}> ${2} = std::make_unique<$1>(${3});
+snippet amup
+	auto ${1} = std::make_unique<${2:T}>(${3});
 ##
 ## Access Modifiers
 # private
diff --git a/sources_non_forked/vim-snippets/snippets/css.snippets b/sources_non_forked/vim-snippets/snippets/css.snippets
index dd688cbe..54b529ae 100644
--- a/sources_non_forked/vim-snippets/snippets/css.snippets
+++ b/sources_non_forked/vim-snippets/snippets/css.snippets
@@ -36,45 +36,71 @@ snippet @m "@media mediatype { }"
 		${2:${VISUAL}}
 	}${0}
 snippet ac
-	align-content: ${0:stretch};
+	align-content: ${1:stretch};
+snippet ac:s
+	align-content: start;
+snippet ac:e
+	align-content: end;
 snippet ac:c
 	align-content: center;
-snippet ac:fe
-	align-content: flex-end;
 snippet ac:fs
 	align-content: flex-start;
-snippet ac:sa
-	align-content: space-around;
+snippet ac:fe
+	align-content: flex-end;
 snippet ac:sb
 	align-content: space-between;
-snippet ac:s
+snippet ac:sa
+	align-content: space-around;
+snippet ac:se
+	align-content: space-evenly;
+snippet ac:st
 	align-content: stretch;
+snippet ac:b
+	align-content: baseline;
+snippet ac:fb
+	align-content: first baseline;
+snippet ac:lb
+	align-content: last baseline;
 snippet ai
-	align-items: ${0:stretch};
-snippet ai:b
-	align-items: baseline;
+	align-items: ${1:stretch};
+snippet ai:s
+	align-items: start;
+snippet ai:e
+	align-items: end;
 snippet ai:c
 	align-items: center;
-snippet ai:fe
-	align-items: flex-end;
 snippet ai:fs
 	align-items: flex-start;
-snippet ai:s
+snippet ai:fe
+	align-items: flex-end;
+snippet ai:st
 	align-items: stretch;
+snippet ai:b
+	align-items: baseline;
+snippet ai:fb
+	align-items: first baseline;
+snippet ai:lb
+	align-items: last baseline;
 snippet as
-	align-self:  ${0};
-snippet as:a
-	align-self: auto;
-snippet as:b
-	align-self: baseline;
+	align-self: ${1:stretch};
+snippet as:s
+	align-self: start;
+snippet as:e
+	align-self: end;
 snippet as:c
 	align-self: center;
-snippet as:fe
-	align-self: flex-end;
+snippet as:st
+	align-self: stretch;
 snippet as:fs
 	align-self: flex-start;
-snippet as:s
-	align-self: stretch;
+snippet as:fe
+	align-self: flex-end;
+snippet as:b
+	align-self: baseline;
+snippet as:fb
+	align-self: first baseline;
+snippet as:lb
+	align-self: last baseline;
 snippet bg+
 	background: #${1:fff} url(${2}) ${3:0} ${4:0} ${5:no-repeat};${0}
 snippet bga
@@ -423,6 +449,8 @@ snippet d:b
 	display: block;
 snippet d:cp
 	display: compact;
+snippet d:g
+	display: grid;
 snippet d:f
 	display: flex;
 snippet d:ib
@@ -605,24 +633,122 @@ snippet fw:n
 	font-weight: normal;
 snippet f
 	font: ${1};${0}
+snippet g
+	grid: ${1};
+snippet gaf
+	grid-auto-flow: ${1:row};
+snippet gaf+
+	grid-auto-flow: ${1:row} ${2:dense};
+snippet gaf:r
+	grid-auto-flow: row;
+snippet gaf:c
+	grid-auto-flow: column;
+snippet gaf:d
+	grid-auto-flow: dense;
+snippet gaf:rd
+	grid-auto-flow: row dense;
+snippet gaf:cd
+	grid-auto-flow: column dense;
+snippet gar
+	grid-auto-rows: ${1};
+snippet gar:a
+	grid-auto-rows: auto
+snippet gar:mac
+	grid-auto-rows: max-content;
+snippet gar:mic
+	grid-auto-rows: min-content;
+snippet gac
+	grid-auto-columns: ${1};
+snippet gac:a
+	grid-auto-columns: auto
+snippet gac:mac
+	grid-auto-columns: max-content;
+snippet gac:mic
+	grid-auto-columns: min-content;
+snippet gt
+	grid-template: ${1};
+snippet gt+
+	grid-template: ${1} / ${2};
+snippet gtr
+	grid-template-rows: ${1};
+snippet gtc
+	grid-template-columns: ${1};
+snippet gta
+	grid-template-areas: ${1};
+snippet gg
+	grid-gap: ${1};
+snippet gg+
+	grid-gap: ${1} ${2};
+snippet gg:0
+	grid-gap: 0;
+snippet grg
+	grid-row-gap: ${1};
+snippet grg:0
+	grid-row-gap: 0;
+snippet gcg
+	grid-column-gap: ${1};
+snippet gcg:0
+	grid-column-gap: 0;
+snippet gr
+	grid-row: ${1} / ${2};
+snippet grs
+	grid-row-start: ${1};
+snippet gre
+	grid-row-end: ${1};
+snippet gc
+	grid-column: ${1} / ${2};
+snippet gcs
+	grid-column-start: ${1};
+snippet gce
+	grid-column-end: ${1};
 snippet h
 	height: ${1};${0}
 snippet h:a
 	height: auto;
 snippet jc
-	justify-content: ${0:flex-start};
+	justify-content: ${1};
+snippet jc:s
+	justify-content: start;
+snippet jc:e
+	justify-content: end;
 snippet jc:c
 	justify-content: center;
-snippet jc:fe
-	justify-content: flex-end;
 snippet jc:fs
 	justify-content: flex-start;
-snippet jc:sa
-	justify-content: space-around;
+snippet jc:fe
+	justify-content: flex-end;
 snippet jc:sb
 	justify-content: space-between;
+snippet jc:sa
+	justify-content: space-around;
 snippet jc:se
 	justify-content: space-evenly;
+snippet jc:st
+	justify-content: space-evenly;
+snippet jc:l
+	justify-content: left;
+snippet jc:r
+	justify-content: right;
+snippet ji
+	justify-items: ${1:stretch};
+snippet ji:s
+	justify-items: start;
+snippet ji:e
+	justify-items: end;
+snippet ji:c
+	justify-items: center;
+snippet ji:st
+	justify-items: stretch;
+snippet js
+	justify-self: ${1:stretch};
+snippet js:s
+	justify-self: start;
+snippet js:e
+	justify-self: end;
+snippet js:c
+	justify-self: center;
+snippet js:st
+	justify-self: stretch;
 snippet l
 	left: ${1};${0}
 snippet l:a
@@ -789,6 +915,28 @@ snippet p:2
 	padding: ${1:0} ${2:0};${0}
 snippet p:0
 	padding: 0;
+snippet pc
+	place-content: ${1};
+snippet pc+
+	place-content: ${1} ${2};
+snippet pc:s
+	place-content: start;
+snippet pc:e
+	place-content: end;
+snippet pc:c
+	place-content: center;
+snippet pc:fs
+	place-content: flex-start;
+snippet pc:fe
+	place-content: flex-end;
+snippet pc:sb
+	place-content: space-between;
+snippet pc:sa
+	place-content: space-around;
+snippet pc:se
+	place-content: space-evenly;
+snippet pc:st
+	place-content: stretch;
 snippet pgba
 	page-break-after: ${1};${0}
 snippet pgba:aw
@@ -815,6 +963,17 @@ snippet pgbi:a
 	page-break-inside: auto;
 snippet pgbi:av
 	page-break-inside: avoid;
+snippet pi
+	place-items: ${1:stretch};
+snippet pi+
+	place-items: ${1:stretch} ${2:stretch};
+snippet pi:s
+	place-items: start;
+snippet pi:e
+	place-items: end;
+snippet pi:c
+	place-items: center;
+snippet pi:st
 snippet pos
 	position: ${1};${0}
 snippet pos:a
@@ -825,6 +984,18 @@ snippet pos:r
 	position: relative;
 snippet pos:s
 	position: static;
+snippet ps
+	place-self: ${1:stretch};
+snippet ps+
+	place-self: ${1:stretch} ${2:stretch};
+snippet ps:s
+	place-self: start;
+snippet ps:e
+	place-self: end;
+snippet ps:c
+	place-self: center;
+snippet ps:st
+	place-self: stretch;
 snippet q
 	quotes: ${1};${0}
 snippet q:en
diff --git a/sources_non_forked/vim-snippets/snippets/eelixir.snippets b/sources_non_forked/vim-snippets/snippets/eelixir.snippets
index 9910975a..456bed51 100644
--- a/sources_non_forked/vim-snippets/snippets/eelixir.snippets
+++ b/sources_non_forked/vim-snippets/snippets/eelixir.snippets
@@ -1,9 +1,11 @@
 extends html
 
-snippet %
+snippet % <% %>
 	<% ${0} %>
-snippet =
+snippet = <%= %>
 	<%= ${0} %>
+snippet # <%# %>
+	<%# ${0} %>
 snippet end
 	<% end %>
 snippet for
@@ -20,13 +22,35 @@ snippet ife
 	<% else %>
 		${0}
 	<% end %>
-snippet ft
+snippet cond
+	<%= cond do %>
+		<% ${1} -> %>
+			${2:${VISUAL}}
+
+		<% true -> %>
+			${0}
+	<% end %>
+snippet unless
+	<%= unless ${1} do %>
+		${0:${VISUAL}}
+	<% end %>
+snippet ft form_tag
 	<%= form_tag(${1:"/users"}, method: ${2::post}) %>
 		${0}
 	</form>
-snippet lin
+snippet et error_tag
+	<%= error_tag ${1:f}, :${2:field} %>
+snippet ti text_input
+	<%= text_input ${1:f}, :${2:field} %>
+snippet la label
+	<%= label ${1:f}, :${2:field}, "${3:Label}" %>
+snippet pi password_input
+	<%= password_input ${1:f}, :${2:password} %>
+snippet render
+	<%= render "${1:index}.html", ${2:var: @var} %>
+snippet lin link
 	<%= link "${1:Submit}", to: ${2:"/users"}, method: ${3::delete} %>
-snippet ff
+snippet ff form_for
 	<%= form_for @changeset, ${1:"/users"}, fn f -> %>
 			${0}
 
diff --git a/sources_non_forked/vim-snippets/snippets/go.snippets b/sources_non_forked/vim-snippets/snippets/go.snippets
index 7cbbf5e2..bd7f541a 100644
--- a/sources_non_forked/vim-snippets/snippets/go.snippets
+++ b/sources_non_forked/vim-snippets/snippets/go.snippets
@@ -31,9 +31,6 @@ snippet cs "case"
 	case ${1:value}:
 		${0:${VISUAL}}
 
-snippet c "const"
-	const ${1:NAME} = ${0:0}
-
 snippet co "constants with iota"
 	const (
 		${1:NAME1} = iota
@@ -53,9 +50,6 @@ snippet dfr "defer recover"
 		}
 	}()
 
-snippet i "int"
-	int
-
 snippet im "import"
 	import (
 		"${1:package}"
diff --git a/sources_non_forked/vim-snippets/snippets/javascript/javascript-react.snippets b/sources_non_forked/vim-snippets/snippets/javascript/javascript-react.snippets
index 011c5c1f..0e8d3602 100644
--- a/sources_non_forked/vim-snippets/snippets/javascript/javascript-react.snippets
+++ b/sources_non_forked/vim-snippets/snippets/javascript/javascript-react.snippets
@@ -1,7 +1,7 @@
 snippet ir
 	import React from 'react';
 snippet irc
-	import React, {Component} from 'react';
+	import React, { Component } from 'react';
 snippet ird
 	import ReactDOM from 'react-dom';
 snippet cdm
@@ -42,11 +42,24 @@ snippet pt
 	static propTypes = {
 		${1}: React.PropTypes.${2:type},
 	}
+snippet rfc
+	const ${1:ComponentName} = (${2:props}) => {
+		return (
+			<div>
+				$1
+			</div>
+		);
+	}
 snippet rcc
 	class ${1:ClassName} extends React.Component {
+		state = {
+
+		}
 		render() {
 			return (
-				${0:<div />}
+				<div>
+					$1
+				</div>
 			);
 		}
 	}
diff --git a/sources_non_forked/vim-snippets/snippets/javascript/javascript-redux.snippets b/sources_non_forked/vim-snippets/snippets/javascript/javascript-redux.snippets
new file mode 100644
index 00000000..e13253c3
--- /dev/null
+++ b/sources_non_forked/vim-snippets/snippets/javascript/javascript-redux.snippets
@@ -0,0 +1,37 @@
+snippet ist
+	import { createStore } from 'redux';
+snippet con
+	connect(${1:mapStateToProps}, ${2:mapDispatchToProps})(<${3:VISUAL}/>);
+snippet act
+	const ${1:actionName} = (${2:arg}) => {
+		return {
+			type: ${3:VISUAL},
+			$2
+		};
+	};
+snippet rdc
+	const ${1:reducerName} = (state={}, action) => {
+		switch(action.type) {
+			case ${1:action}:
+				return {
+					...state,
+					$2
+				};
+			default:
+				return state;
+		};
+	};
+snippet mstp
+	const mapStateToProps = (state) => {
+		return {
+			${1:propName}: state.$1,
+		};
+	};
+snippet mdtp
+	const mapDispatchToProps = (dispatch) => {
+		return {
+			${1:propName}: () => {
+				dispatch(${2:actionName}());
+			},
+		};
+	};
diff --git a/sources_non_forked/vim-snippets/snippets/javascript/javascript.es6.snippets b/sources_non_forked/vim-snippets/snippets/javascript/javascript.es6.snippets
deleted file mode 100644
index 7e885e6e..00000000
--- a/sources_non_forked/vim-snippets/snippets/javascript/javascript.es6.snippets
+++ /dev/null
@@ -1,55 +0,0 @@
-snippet const
-	const ${1} = ${0};
-snippet let
-	let ${1} = ${0};
-snippet im "import xyz from 'xyz'"
-	import ${1} from '${2:$1}';
-snippet imas "import * as xyz from 'xyz'"
-	import * as ${1} from '${2:$1}';
-snippet imm "import { member } from 'xyz'"
-	import { ${1} } from '${2}';
-snippet cla
-	class ${1} {
-		${0:${VISUAL}}
-	}
-snippet clax
-	class ${1} extends ${2} {
-		${0:${VISUAL}}
-	}
-snippet clac
-	class ${1} {
-		constructor(${2}) {
-			${0:${VISUAL}}
-		}
-	}
-snippet foro "for (const prop of object}) { ... }"
-	for (const ${1:prop} of ${2:object}) {
-		${0:$1}
-	}
-# Generator
-snippet fun*
-	function* ${1:function_name}(${2}) {
-		${0:${VISUAL}}
-	}
-snippet c=>
-	const ${1:function_name} = (${2}) => {
-		${0:${VISUAL}}
-	}
-snippet caf
-	const ${1:function_name} = (${2}) => {
-		${0:${VISUAL}}
-	}
-snippet =>
-	(${1}) => {
-		${0:${VISUAL}}
-	}
-snippet af
-	(${1}) => {
-		${0:${VISUAL}}
-	}
-snippet sym
-	const ${1} = Symbol('${0}');
-snippet ed
-	export default ${0}
-snippet ${
-	${${1}}${0}
diff --git a/sources_non_forked/vim-snippets/snippets/javascript/javascript.snippets b/sources_non_forked/vim-snippets/snippets/javascript/javascript.snippets
index 0dc5783e..8cf7c6e0 100644
--- a/sources_non_forked/vim-snippets/snippets/javascript/javascript.snippets
+++ b/sources_non_forked/vim-snippets/snippets/javascript/javascript.snippets
@@ -5,10 +5,14 @@ snippet proto
 		${0:${VISUAL}}
 	};
 # Function
-snippet fun
+snippet fun "function"
 	function ${1:function_name}(${2}) {
 		${0:${VISUAL}}
 	}
+snippet fun "async function"
+	async function ${1:function_name}(${2}) {
+		${0:${VISUAL}}
+	}
 # Anonymous Function
 snippet anf "" w
 	function(${1}) {
@@ -202,8 +206,6 @@ snippet @par
 	@param {${1:type}} ${2:name} ${0:description}
 snippet @ret
 	@return {${1:type}} ${0:description}
-# JSON
-
 # JSON.parse
 snippet jsonp
 	JSON.parse(${0:jstr});
@@ -273,9 +275,64 @@ snippet cprof "console.profile"
 snippet ctable "console.table"
 	console.table(${1:"${2:value}"});
 # Misc
-# 'use strict';
 snippet us
 	'use strict';
 # setTimeout function
 snippet timeout
 	setTimeout(function () {${0}}${2}, ${1:10});
+snippet const
+	const ${1} = ${0};
+snippet let
+	let ${1} = ${0};
+snippet im "import xyz from 'xyz'"
+	import ${1} from '${2:$1}';
+snippet imas "import * as xyz from 'xyz'"
+	import * as ${1} from '${2:$1}';
+snippet imm "import { member } from 'xyz'"
+	import { ${1} } from '${2}';
+snippet cla
+	class ${1} {
+		${0:${VISUAL}}
+	}
+snippet clax
+	class ${1} extends ${2} {
+		${0:${VISUAL}}
+	}
+snippet clac
+	class ${1} {
+		constructor(${2}) {
+			${0:${VISUAL}}
+		}
+	}
+snippet foro "for (const prop of object}) { ... }"
+	for (const ${1:prop} of ${2:object}) {
+		${0:$1}
+	}
+snippet fun*
+	function* ${1:function_name}(${2}) {
+		${0:${VISUAL}}
+	}
+snippet c=>
+	const ${1:function_name} = (${2}) => {
+		${0:${VISUAL}}
+	}
+snippet caf
+	const ${1:function_name} = (${2}) => {
+		${0:${VISUAL}}
+	}
+snippet =>
+	(${1}) => {
+		${0:${VISUAL}}
+	}
+snippet af
+	(${1}) => {
+		${0:${VISUAL}}
+	}
+snippet sym
+	const ${1} = Symbol('${0}');
+snippet ed
+	export default ${0}
+snippet ${
+	${${1}}${0}
+snippet aw "await"
+	await ${0:${VISUAL}}
diff --git a/sources_non_forked/vim-snippets/snippets/sass.snippets b/sources_non_forked/vim-snippets/snippets/sass.snippets
index 3e84c20e..5bef5937 100644
--- a/sources_non_forked/vim-snippets/snippets/sass.snippets
+++ b/sources_non_forked/vim-snippets/snippets/sass.snippets
@@ -34,6 +34,72 @@ snippet while
 		${0:${VISUAL}}
 snippet !
 	 !important
+snippet ac
+	align-content: ${0}
+snippet ac:s
+	align-content: start
+snippet ac:e
+	align-content: end
+snippet ac:c
+	align-content: center
+snippet ac:fs
+	align-content: flex-start
+snippet ac:fe
+	align-content: flex-end
+snippet ac:sb
+	align-content: space-between
+snippet ac:sa
+	align-content: space-around
+snippet ac:se
+	align-content: space-evenly
+snippet ac:st
+	align-content: stretch
+snippet ac:b
+	align-content: baseline
+snippet ac:fb
+	align-content: first baseline
+snippet ac:lb
+	align-content: last baseline
+snippet ai
+	align-items: ${0}
+snippet ai:s
+	align-items: start
+snippet ai:e
+	align-items: end
+snippet ai:c
+	align-items: center
+snippet ai:fs
+	align-items: flex-start
+snippet ai:fe
+	align-items: flex-end
+snippet ai:st
+	align-items: stretch
+snippet ai:b
+	align-items: baseline
+snippet ai:fb
+	align-items: first baseline
+snippet ai:lb
+	align-items: last baseline
+snippet as
+	align-self: ${0}
+snippet as:s
+	align-self: start
+snippet as:e
+	align-self: end
+snippet as:c
+	align-self: center
+snippet as:st
+	align-self: stretch
+snippet as:fs
+	align-self: flex-start
+snippet as:fe
+	align-self: flex-end
+snippet as:b
+	align-self: baseline
+snippet as:fb
+	align-self: first baseline
+snippet as:lb
+	align-self: last baseline
 snippet bdi:m+
 	-moz-border-image: url('${1}') ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${0:stretch}
 snippet bdi:m
@@ -411,6 +477,10 @@ snippet d:b
 	display: block
 snippet d:cp
 	display: compact
+snippet d:g
+	display: grid
+snippet d:f
+	display: flex
 snippet d:ib
 	display: inline-block
 snippet d:itb
@@ -561,10 +631,122 @@ snippet fw:n
 	font-weight: normal
 snippet f
 	font: ${0}
+snippet g
+	grid: ${0}
+snippet gaf
+	grid-auto-flow: ${0}
+snippet gaf+
+	grid-auto-flow: ${1:row} ${0:dense}
+snippet gaf:r
+	grid-auto-flow: row
+snippet gaf:c
+	grid-auto-flow: column
+snippet gaf:d
+	grid-auto-flow: dense
+snippet gaf:rd
+	grid-auto-flow: row dense
+snippet gaf:cd
+	grid-auto-flow: column dense
+snippet gar
+	grid-auto-rows: ${0}
+snippet gar:a
+	grid-auto-rows: auto
+snippet gar:mac
+	grid-auto-rows: max-content
+snippet gar:mic
+	grid-auto-rows: min-content
+snippet gac
+	grid-auto-columns: ${0}
+snippet gac:a
+	grid-auto-columns: auto
+snippet gac:mac
+	grid-auto-columns: max-content
+snippet gac:mic
+	grid-auto-columns: min-content
+snippet gt
+	grid-template: ${0}
+snippet gt+
+	grid-template: ${1} / ${0}
+snippet gtr
+	grid-template-rows: ${0}
+snippet gtc
+	grid-template-columns: ${0}
+snippet gta
+	grid-template-areas: ${0}
+snippet gg
+	grid-gap: ${0}
+snippet gg+
+	grid-gap: ${1} ${0}
+snippet gg:0
+	grid-gap: 0
+snippet grg
+	grid-row-gap: ${0}
+snippet grg:0
+	grid-row-gap: 0
+snippet gcg
+	grid-column-gap: ${0}
+snippet gcg:0
+	grid-column-gap: 0
+snippet gr
+	grid-row: ${1} / ${0}
+snippet grs
+	grid-row-start: ${0}
+snippet gre
+	grid-row-end: ${0}
+snippet gc
+	grid-column: ${1} / ${0}
+snippet gcs
+	grid-column-start: ${0}
+snippet gce
+	grid-column-end: ${0}
 snippet h
 	height: ${0}
 snippet h:a
 	height: auto
+snippet jc
+	justify-content: ${0}
+snippet jc:s
+	justify-content: start
+snippet jc:e
+	justify-content: end
+snippet jc:c
+	justify-content: center
+snippet jc:fs
+	justify-content: flex-start
+snippet jc:fe
+	justify-content: flex-end
+snippet jc:sb
+	justify-content: space-between
+snippet jc:sa
+	justify-content: space-around
+snippet jc:se
+	justify-content: space-evenly
+snippet jc:st
+	justify-content: space-evenly
+snippet jc:l
+	justify-content: left
+snippet jc:r
+	justify-content: right
+snippet ji
+	justify-items: ${0}
+snippet ji:s
+	justify-items: start
+snippet ji:e
+	justify-items: end
+snippet ji:c
+	justify-items: center
+snippet ji:st
+	justify-items: stretch
+snippet js
+	justify-self: ${0}
+snippet js:s
+	justify-self: start
+snippet js:e
+	justify-self: end
+snippet js:c
+	justify-self: center
+snippet js:st
+	justify-self: stretch
 snippet l
 	left: ${0}
 snippet l:a
@@ -729,6 +911,28 @@ snippet p:2
 	padding: ${1:0} ${0:0}
 snippet p:0
 	padding: 0
+snippet pc
+	place-content: ${0}
+snippet pc+
+	place-content: ${1} ${0}
+snippet pc:s
+	place-content: start
+snippet pc:e
+	place-content: end
+snippet pc:c
+	place-content: center
+snippet pc:fs
+	place-content: flex-start
+snippet pc:fe
+	place-content: flex-end
+snippet pc:sb
+	place-content: space-between
+snippet pc:sa
+	place-content: space-around
+snippet pc:se
+	place-content: space-evenly
+snippet pc:st
+	place-content: stretch
 snippet pgba
 	page-break-after: ${0}
 snippet pgba:aw
@@ -755,6 +959,18 @@ snippet pgbi:a
 	page-break-inside: auto
 snippet pgbi:av
 	page-break-inside: avoid
+snippet pi
+	place-items: ${0}
+snippet pi+
+	place-items: ${1:stretch} ${0:stretch}
+snippet pi:s
+	place-items: start
+snippet pi:e
+	place-items: end
+snippet pi:c
+	place-items: center
+snippet pi:st
+	place-items: stretch
 snippet pos
 	position: ${0}
 snippet pos:a
@@ -765,6 +981,18 @@ snippet pos:r
 	position: relative
 snippet pos:s
 	position: static
+snippet ps
+	place-self: ${0}
+snippet ps+
+	place-self: ${1:stretch} ${0:stretch}
+snippet ps:s
+	place-self: start
+snippet ps:e
+	place-self: end
+snippet ps:c
+	place-self: center
+snippet ps:st
+	place-self: stretch
 snippet q
 	quotes: ${0}
 snippet q:en
diff --git a/sources_non_forked/vim-snippets/snippets/stylus.snippets b/sources_non_forked/vim-snippets/snippets/stylus.snippets
index 3ce35c26..ab703fee 100644
--- a/sources_non_forked/vim-snippets/snippets/stylus.snippets
+++ b/sources_non_forked/vim-snippets/snippets/stylus.snippets
@@ -1,5 +1,71 @@
 snippet !
 	!important
+snippet ac
+	align-content ${0}
+snippet ac:s
+	align-content start
+snippet ac:e
+	align-content end
+snippet ac:c
+	align-content center
+snippet ac:fs
+	align-content flex-start
+snippet ac:fe
+	align-content flex-end
+snippet ac:sb
+	align-content space-between
+snippet ac:sa
+	align-content space-around
+snippet ac:se
+	align-content space-evenly
+snippet ac:st
+	align-content stretch
+snippet ac:b
+	align-content baseline
+snippet ac:fb
+	align-content first baseline
+snippet ac:lb
+	align-content last baseline
+snippet ai
+	align-items ${0}
+snippet ai:s
+	align-items start
+snippet ai:e
+	align-items end
+snippet ai:c
+	align-items center
+snippet ai:fs
+	align-items flex-start
+snippet ai:fe
+	align-items flex-end
+snippet ai:st
+	align-items stretch
+snippet ai:b
+	align-items baseline
+snippet ai:fb
+	align-items first baseline
+snippet ai:lb
+	align-items last baseline
+snippet as
+	align-self ${0}
+snippet as:s
+	align-self start
+snippet as:e
+	align-self end
+snippet as:c
+	align-self center
+snippet as:st
+	align-self stretch
+snippet as:fs
+	align-self flex-start
+snippet as:fe
+	align-self flex-end
+snippet as:b
+	align-self baseline
+snippet as:fb
+	align-self first baseline
+snippet as:lb
+	align-self last baseline
 snippet bdi:m+
 	-moz-border-image url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${0:stretch}
 snippet bdi:m
@@ -379,10 +445,12 @@ snippet d:mis
 	display -moz-inline-stack
 snippet d:b
 	display block
-snippet d:f
-	display flex
 snippet d:cp
 	display compact
+snippet d:g
+	display grid
+snippet d:f
+	display flex
 snippet d:ib
 	display inline-block
 snippet d:itb
@@ -533,6 +601,74 @@ snippet fw:n
 	font-weight normal
 snippet f
 	font ${0}
+snippet g
+	grid ${0}
+snippet gaf
+	grid-auto-flow ${0}
+snippet gaf+
+	grid-auto-flow ${1:row} ${0:dense}
+snippet gaf:r
+	grid-auto-flow row
+snippet gaf:c
+	grid-auto-flow column
+snippet gaf:d
+	grid-auto-flow dense
+snippet gaf:rd
+	grid-auto-flow row dense
+snippet gaf:cd
+	grid-auto-flow column dense
+snippet gar
+	grid-auto-rows ${0}
+snippet gar:a
+	grid-auto-rows auto
+snippet gar:mac
+	grid-auto-rows max-content
+snippet gar:mic
+	grid-auto-rows min-content
+snippet gac
+	grid-auto-columns ${0}
+snippet gac:a
+	grid-auto-columns auto
+snippet gac:mac
+	grid-auto-columns max-content
+snippet gac:mic
+	grid-auto-columns min-content
+snippet gt
+	grid-template ${0}
+snippet gt+
+	grid-template ${1} / ${0}
+snippet gtr
+	grid-template-rows ${0}
+snippet gtc
+	grid-template-columns ${0}
+snippet gta
+	grid-template-areas ${0}
+snippet gg
+	grid-gap ${0}
+snippet gg+
+	grid-gap ${1} ${0}
+snippet gg:0
+	grid-gap 0
+snippet grg
+	grid-row-gap ${0}
+snippet grg:0
+	grid-row-gap 0
+snippet gcg
+	grid-column-gap ${0}
+snippet gcg:0
+	grid-column-gap 0
+snippet gr
+	grid-row ${1} / ${0}
+snippet grs
+	grid-row-start ${0}
+snippet gre
+	grid-row-end ${0}
+snippet gc
+	grid-column ${1} / ${0}
+snippet gcs
+	grid-column-start ${0}
+snippet gce
+	grid-column-end ${0}
 snippet h
 	height ${0}
 snippet h:a
@@ -701,6 +837,28 @@ snippet p:2
 	padding ${1:0} ${0:0}
 snippet p:0
 	padding 0
+snippet pc
+	place-content ${0}
+snippet pc+
+	place-content ${1} ${0}
+snippet pc:s
+	place-content start
+snippet pc:e
+	place-content end
+snippet pc:c
+	place-content center
+snippet pc:fs
+	place-content flex-start
+snippet pc:fe
+	place-content flex-end
+snippet pc:sb
+	place-content space-between
+snippet pc:sa
+	place-content space-around
+snippet pc:se
+	place-content space-evenly
+snippet pc:st
+	place-content stretch
 snippet pgba
 	page-break-after ${0}
 snippet pgba:aw
@@ -727,6 +885,18 @@ snippet pgbi:a
 	page-break-inside auto
 snippet pgbi:av
 	page-break-inside avoid
+snippet pi
+	place-items ${0}
+snippet pi+
+	place-items ${1:stretch} ${0:stretch}
+snippet pi:s
+	place-items start
+snippet pi:e
+	place-items end
+snippet pi:c
+	place-items center
+snippet pi:st
+	place-items stretch
 snippet pos
 	position ${0}
 snippet pos:a
@@ -737,6 +907,18 @@ snippet pos:r
 	position relative
 snippet pos:s
 	position static
+snippet ps
+	place-self ${0}
+snippet ps+
+	place-self ${1:stretch} ${0:stretch}
+snippet ps:s
+	place-self start
+snippet ps:e
+	place-self end
+snippet ps:c
+	place-self center
+snippet ps:st
+	place-self stretch
 snippet q
 	quotes ${0}
 snippet q:en
@@ -993,7 +1175,47 @@ snippet for
 	for ${1:i} in ${0}
 snippet keyf
 	@keyframes ${0}
+snippet jc
+	justify-content ${0}
+snippet jc:s
+	justify-content start
+snippet jc:e
+	justify-content end
 snippet jc:c
 	justify-content center
-snippet jc
-	justify-content
+snippet jc:fs
+	justify-content flex-start
+snippet jc:fe
+	justify-content flex-end
+snippet jc:sb
+	justify-content space-between
+snippet jc:sa
+	justify-content space-around
+snippet jc:se
+	justify-content space-evenly
+snippet jc:st
+	justify-content space-evenly
+snippet jc:l
+	justify-content left
+snippet jc:r
+	justify-content right
+snippet ji
+	justify-items ${0}
+snippet ji:s
+	justify-items start
+snippet ji:e
+	justify-items end
+snippet ji:c
+	justify-items center
+snippet ji:st
+	justify-items stretch
+snippet js
+	justify-self ${0}
+snippet js:s
+	justify-self start
+snippet js:e
+	justify-self end
+snippet js:c
+	justify-self center
+snippet js:st
+	justify-self stretch
diff --git a/sources_non_forked/vim-snippets/snippets/tex.snippets b/sources_non_forked/vim-snippets/snippets/tex.snippets
index 895fbe57..24d4ff8a 100644
--- a/sources_non_forked/vim-snippets/snippets/tex.snippets
+++ b/sources_non_forked/vim-snippets/snippets/tex.snippets
@@ -248,7 +248,7 @@ snippet tikz figure environment (tikzpicture)
 		${2}
 	\\end{tikzpicture}
 	\\end{center}
-	\\caption{${3}}
+	\\caption{${3}}%
 	\\label{fig:${4}}
 	\\end{figure}
 	${0}
diff --git a/sources_non_forked/vim-surround/plugin/surround.vim b/sources_non_forked/vim-surround/plugin/surround.vim
index 5626f22f..59092601 100644
--- a/sources_non_forked/vim-surround/plugin/surround.vim
+++ b/sources_non_forked/vim-surround/plugin/surround.vim
@@ -336,7 +336,16 @@ function! s:insert(...) " {{{1
   if exists("g:surround_insert_tail")
     call setreg('"',g:surround_insert_tail,"a".getregtype('"'))
   endif
-  if col('.') >= col('$')
+  if &ve != 'all' && col('.') >= col('$')
+    if &ve == 'insert'
+      let extra_cols = virtcol('.') - virtcol('$')
+      if extra_cols > 0
+        let [regval,regtype] = [getreg('"',1,1),getregtype('"')]
+        call setreg('"',join(map(range(extra_cols),'" "'),''),'v')
+        norm! ""p
+        call setreg('"',regval,regtype)
+      endif
+    endif
     norm! ""p
   else
     norm! ""P