From bf7dfc725ec894aac6f540c9469f54beab1cae5e Mon Sep 17 00:00:00 2001 From: diego castillo salazar Date: Fri, 18 Nov 2022 16:55:19 -0500 Subject: [PATCH] uploading vim configs --- .vim/.netrwhist | 12 + .vim/Gemfile | 2 + .vim/autoload/plug.vim | 2804 ++++++++++ .vim/colors/base16-grayscale-dark.vim | 413 ++ .vim/compiler/tex.vim | 412 ++ .vim/doc/Makefile | 62 + .vim/doc/Makefile.in | 29 + .vim/doc/README | 110 + .vim/doc/README.new | 25 + .vim/doc/catalog.xml | 12 + .vim/doc/db2vim/db2vim | 715 +++ .vim/doc/db2vim/domutils.py | 27 + .vim/doc/db2vim/textutils.py | 207 + .vim/doc/imaps.txt | 86 + .vim/doc/latex-suite-chunk.xsl | 50 + .vim/doc/latex-suite-common.xsl | 62 + .vim/doc/latex-suite-quickstart.css | 182 + .vim/doc/latex-suite-quickstart.txt | 391 ++ .vim/doc/latex-suite-quickstart.xml | 433 ++ .vim/doc/latex-suite.css | 182 + .vim/doc/latex-suite.txt | 3529 ++++++++++++ .vim/doc/latex-suite.xml | 4749 +++++++++++++++++ .vim/doc/latex-suite.xsl | 22 + .vim/doc/tags | 621 +++ .vim/ftplugin/bib_latexSuite.vim | 22 + .vim/ftplugin/latex-suite/bibtex.vim | 253 + .vim/ftplugin/latex-suite/bibtools.py | 248 + .vim/ftplugin/latex-suite/brackets.vim | 146 + .vim/ftplugin/latex-suite/compiler.vim | 935 ++++ .vim/ftplugin/latex-suite/custommacros.vim | 251 + .vim/ftplugin/latex-suite/diacritics.vim | 124 + .../ftplugin/latex-suite/dictionaries/SIunits | 289 + .../latex-suite/dictionaries/dictionary | 676 +++ .vim/ftplugin/latex-suite/elementmacros.vim | 330 ++ .vim/ftplugin/latex-suite/envmacros.vim | 1193 +++++ .vim/ftplugin/latex-suite/folding.vim | 546 ++ .vim/ftplugin/latex-suite/macros/example | 11 + .vim/ftplugin/latex-suite/main.vim | 1189 +++++ .vim/ftplugin/latex-suite/mathmacros-utf.vim | 729 +++ .vim/ftplugin/latex-suite/mathmacros.vim | 730 +++ .vim/ftplugin/latex-suite/multicompile.vim | 16 + .vim/ftplugin/latex-suite/outline.py | 200 + .vim/ftplugin/latex-suite/packages.vim | 689 +++ .vim/ftplugin/latex-suite/packages/SIunits | 315 ++ .vim/ftplugin/latex-suite/packages/accents | 28 + .vim/ftplugin/latex-suite/packages/acromake | 10 + .vim/ftplugin/latex-suite/packages/afterpage | 10 + .vim/ftplugin/latex-suite/packages/alltt | 12 + .vim/ftplugin/latex-suite/packages/amsmath | 106 + .vim/ftplugin/latex-suite/packages/amsthm | 21 + .vim/ftplugin/latex-suite/packages/amsxtra | 12 + .vim/ftplugin/latex-suite/packages/arabic | 10 + .vim/ftplugin/latex-suite/packages/array | 17 + .vim/ftplugin/latex-suite/packages/babel | 103 + .vim/ftplugin/latex-suite/packages/bar | 27 + .vim/ftplugin/latex-suite/packages/biblatex | 159 + .vim/ftplugin/latex-suite/packages/bm | 10 + .vim/ftplugin/latex-suite/packages/bophook | 12 + .../latex-suite/packages/boxedminipage | 10 + .vim/ftplugin/latex-suite/packages/caption2 | 43 + .vim/ftplugin/latex-suite/packages/cases | 12 + .vim/ftplugin/latex-suite/packages/ccaption | 20 + .vim/ftplugin/latex-suite/packages/changebar | 35 + .vim/ftplugin/latex-suite/packages/chapterbib | 24 + .vim/ftplugin/latex-suite/packages/cite | 32 + .vim/ftplugin/latex-suite/packages/color | 43 + .vim/ftplugin/latex-suite/packages/comma | 12 + .vim/ftplugin/latex-suite/packages/csquotes | 104 + .vim/ftplugin/latex-suite/packages/deleq | 36 + .vim/ftplugin/latex-suite/packages/drftcite | 29 + .vim/ftplugin/latex-suite/packages/dropping | 12 + .vim/ftplugin/latex-suite/packages/enumerate | 10 + .vim/ftplugin/latex-suite/packages/eqlist | 19 + .vim/ftplugin/latex-suite/packages/eqparbox | 12 + .vim/ftplugin/latex-suite/packages/everyshi | 10 + .vim/ftplugin/latex-suite/packages/exmpl | 55 + .vim/ftplugin/latex-suite/packages/fixme | 42 + .vim/ftplugin/latex-suite/packages/flafter | 10 + .vim/ftplugin/latex-suite/packages/float | 16 + .vim/ftplugin/latex-suite/packages/floatflt | 12 + .vim/ftplugin/latex-suite/packages/fn2end | 10 + .vim/ftplugin/latex-suite/packages/footmisc | 21 + .vim/ftplugin/latex-suite/packages/geometry | 93 + .vim/ftplugin/latex-suite/packages/german | 17 + .vim/ftplugin/latex-suite/packages/graphicx | 69 + .vim/ftplugin/latex-suite/packages/graphpap | 10 + .vim/ftplugin/latex-suite/packages/harpoon | 18 + .vim/ftplugin/latex-suite/packages/hhline | 21 + .vim/ftplugin/latex-suite/packages/histogram | 13 + .vim/ftplugin/latex-suite/packages/hyperref | 167 + .vim/ftplugin/latex-suite/packages/ifthen | 21 + .vim/ftplugin/latex-suite/packages/inputenc | 29 + .../ftplugin/latex-suite/packages/letterspace | 10 + .vim/ftplugin/latex-suite/packages/lineno | 60 + .vim/ftplugin/latex-suite/packages/longtable | 35 + .vim/ftplugin/latex-suite/packages/lscape | 10 + .vim/ftplugin/latex-suite/packages/manyfoot | 15 + .vim/ftplugin/latex-suite/packages/moreverb | 28 + .vim/ftplugin/latex-suite/packages/multibox | 10 + .vim/ftplugin/latex-suite/packages/multicol | 21 + .vim/ftplugin/latex-suite/packages/newalg | 26 + .vim/ftplugin/latex-suite/packages/ngerman | 17 + .vim/ftplugin/latex-suite/packages/numprint | 18 + .vim/ftplugin/latex-suite/packages/oldstyle | 12 + .vim/ftplugin/latex-suite/packages/outliner | 19 + .vim/ftplugin/latex-suite/packages/overcite | 34 + .vim/ftplugin/latex-suite/packages/pagenote | 26 + .vim/ftplugin/latex-suite/packages/parallel | 15 + .vim/ftplugin/latex-suite/packages/plain | 10 + .vim/ftplugin/latex-suite/packages/plates | 16 + .vim/ftplugin/latex-suite/packages/polski | 165 + .vim/ftplugin/latex-suite/packages/psgo | 27 + .vim/ftplugin/latex-suite/packages/schedule | 20 + .vim/ftplugin/latex-suite/packages/textfit | 12 + .vim/ftplugin/latex-suite/packages/times | 10 + .vim/ftplugin/latex-suite/packages/tipa | 364 ++ .vim/ftplugin/latex-suite/packages/ulem | 21 + .vim/ftplugin/latex-suite/packages/url | 24 + .vim/ftplugin/latex-suite/packages/verbatim | 18 + .vim/ftplugin/latex-suite/packages/version | 12 + .vim/ftplugin/latex-suite/projecttemplate.vim | 11 + .vim/ftplugin/latex-suite/pytools.py | 60 + .vim/ftplugin/latex-suite/smartspace.vim | 102 + .vim/ftplugin/latex-suite/templates.vim | 167 + .../latex-suite/templates/IEEEtran.tex | 142 + .../latex-suite/templates/article.tex | 9 + .../ftplugin/latex-suite/templates/report.tex | 9 + .../templates/report_two_column.tex | 9 + .vim/ftplugin/latex-suite/texmenuconf.vim | 130 + .vim/ftplugin/latex-suite/texproject.vim | 55 + .vim/ftplugin/latex-suite/texrc | 768 +++ .vim/ftplugin/latex-suite/texviewer.vim | 1111 ++++ .vim/ftplugin/latex-suite/version.vim | 30 + .vim/ftplugin/latex-suite/wizardfuncs.vim | 335 ++ .vim/ftplugin/tex.vim | 7 + .vim/ftplugin/tex_latexSuite.vim | 20 + .vim/indent/tex.vim | 389 ++ .vim/latextags | 11 + .vim/ltags | 78 + .vim/plugged/colorizer | 1 + .vim/plugin/SyntaxFolds.vim | 321 ++ .vim/plugin/filebrowser.vim | 249 + .vim/plugin/imaps.vim | 766 +++ .vim/plugin/remoteOpen.vim | 154 + .vim/spell/es.utf-8.spl | Bin 0 -> 601019 bytes .vim/spell/es.utf-8.sug | Bin 0 -> 1912378 bytes 146 files changed, 31642 insertions(+) create mode 100644 .vim/.netrwhist create mode 100644 .vim/Gemfile create mode 100644 .vim/autoload/plug.vim create mode 100644 .vim/colors/base16-grayscale-dark.vim create mode 100644 .vim/compiler/tex.vim create mode 100644 .vim/doc/Makefile create mode 100644 .vim/doc/Makefile.in create mode 100644 .vim/doc/README create mode 100644 .vim/doc/README.new create mode 100644 .vim/doc/catalog.xml create mode 100644 .vim/doc/db2vim/db2vim create mode 100644 .vim/doc/db2vim/domutils.py create mode 100644 .vim/doc/db2vim/textutils.py create mode 100644 .vim/doc/imaps.txt create mode 100644 .vim/doc/latex-suite-chunk.xsl create mode 100644 .vim/doc/latex-suite-common.xsl create mode 100644 .vim/doc/latex-suite-quickstart.css create mode 100644 .vim/doc/latex-suite-quickstart.txt create mode 100644 .vim/doc/latex-suite-quickstart.xml create mode 100644 .vim/doc/latex-suite.css create mode 100644 .vim/doc/latex-suite.txt create mode 100644 .vim/doc/latex-suite.xml create mode 100644 .vim/doc/latex-suite.xsl create mode 100644 .vim/doc/tags create mode 100644 .vim/ftplugin/bib_latexSuite.vim create mode 100644 .vim/ftplugin/latex-suite/bibtex.vim create mode 100644 .vim/ftplugin/latex-suite/bibtools.py create mode 100644 .vim/ftplugin/latex-suite/brackets.vim create mode 100644 .vim/ftplugin/latex-suite/compiler.vim create mode 100644 .vim/ftplugin/latex-suite/custommacros.vim create mode 100644 .vim/ftplugin/latex-suite/diacritics.vim create mode 100644 .vim/ftplugin/latex-suite/dictionaries/SIunits create mode 100644 .vim/ftplugin/latex-suite/dictionaries/dictionary create mode 100644 .vim/ftplugin/latex-suite/elementmacros.vim create mode 100644 .vim/ftplugin/latex-suite/envmacros.vim create mode 100644 .vim/ftplugin/latex-suite/folding.vim create mode 100644 .vim/ftplugin/latex-suite/macros/example create mode 100644 .vim/ftplugin/latex-suite/main.vim create mode 100644 .vim/ftplugin/latex-suite/mathmacros-utf.vim create mode 100644 .vim/ftplugin/latex-suite/mathmacros.vim create mode 100644 .vim/ftplugin/latex-suite/multicompile.vim create mode 100644 .vim/ftplugin/latex-suite/outline.py create mode 100644 .vim/ftplugin/latex-suite/packages.vim create mode 100644 .vim/ftplugin/latex-suite/packages/SIunits create mode 100644 .vim/ftplugin/latex-suite/packages/accents create mode 100644 .vim/ftplugin/latex-suite/packages/acromake create mode 100644 .vim/ftplugin/latex-suite/packages/afterpage create mode 100644 .vim/ftplugin/latex-suite/packages/alltt create mode 100644 .vim/ftplugin/latex-suite/packages/amsmath create mode 100644 .vim/ftplugin/latex-suite/packages/amsthm create mode 100644 .vim/ftplugin/latex-suite/packages/amsxtra create mode 100644 .vim/ftplugin/latex-suite/packages/arabic create mode 100644 .vim/ftplugin/latex-suite/packages/array create mode 100644 .vim/ftplugin/latex-suite/packages/babel create mode 100644 .vim/ftplugin/latex-suite/packages/bar create mode 100644 .vim/ftplugin/latex-suite/packages/biblatex create mode 100644 .vim/ftplugin/latex-suite/packages/bm create mode 100644 .vim/ftplugin/latex-suite/packages/bophook create mode 100644 .vim/ftplugin/latex-suite/packages/boxedminipage create mode 100644 .vim/ftplugin/latex-suite/packages/caption2 create mode 100644 .vim/ftplugin/latex-suite/packages/cases create mode 100644 .vim/ftplugin/latex-suite/packages/ccaption create mode 100644 .vim/ftplugin/latex-suite/packages/changebar create mode 100644 .vim/ftplugin/latex-suite/packages/chapterbib create mode 100644 .vim/ftplugin/latex-suite/packages/cite create mode 100644 .vim/ftplugin/latex-suite/packages/color create mode 100644 .vim/ftplugin/latex-suite/packages/comma create mode 100644 .vim/ftplugin/latex-suite/packages/csquotes create mode 100644 .vim/ftplugin/latex-suite/packages/deleq create mode 100644 .vim/ftplugin/latex-suite/packages/drftcite create mode 100644 .vim/ftplugin/latex-suite/packages/dropping create mode 100644 .vim/ftplugin/latex-suite/packages/enumerate create mode 100644 .vim/ftplugin/latex-suite/packages/eqlist create mode 100644 .vim/ftplugin/latex-suite/packages/eqparbox create mode 100644 .vim/ftplugin/latex-suite/packages/everyshi create mode 100644 .vim/ftplugin/latex-suite/packages/exmpl create mode 100644 .vim/ftplugin/latex-suite/packages/fixme create mode 100644 .vim/ftplugin/latex-suite/packages/flafter create mode 100644 .vim/ftplugin/latex-suite/packages/float create mode 100644 .vim/ftplugin/latex-suite/packages/floatflt create mode 100644 .vim/ftplugin/latex-suite/packages/fn2end create mode 100644 .vim/ftplugin/latex-suite/packages/footmisc create mode 100644 .vim/ftplugin/latex-suite/packages/geometry create mode 100644 .vim/ftplugin/latex-suite/packages/german create mode 100644 .vim/ftplugin/latex-suite/packages/graphicx create mode 100644 .vim/ftplugin/latex-suite/packages/graphpap create mode 100644 .vim/ftplugin/latex-suite/packages/harpoon create mode 100644 .vim/ftplugin/latex-suite/packages/hhline create mode 100644 .vim/ftplugin/latex-suite/packages/histogram create mode 100644 .vim/ftplugin/latex-suite/packages/hyperref create mode 100644 .vim/ftplugin/latex-suite/packages/ifthen create mode 100644 .vim/ftplugin/latex-suite/packages/inputenc create mode 100644 .vim/ftplugin/latex-suite/packages/letterspace create mode 100644 .vim/ftplugin/latex-suite/packages/lineno create mode 100644 .vim/ftplugin/latex-suite/packages/longtable create mode 100644 .vim/ftplugin/latex-suite/packages/lscape create mode 100644 .vim/ftplugin/latex-suite/packages/manyfoot create mode 100644 .vim/ftplugin/latex-suite/packages/moreverb create mode 100644 .vim/ftplugin/latex-suite/packages/multibox create mode 100644 .vim/ftplugin/latex-suite/packages/multicol create mode 100644 .vim/ftplugin/latex-suite/packages/newalg create mode 100644 .vim/ftplugin/latex-suite/packages/ngerman create mode 100644 .vim/ftplugin/latex-suite/packages/numprint create mode 100644 .vim/ftplugin/latex-suite/packages/oldstyle create mode 100644 .vim/ftplugin/latex-suite/packages/outliner create mode 100644 .vim/ftplugin/latex-suite/packages/overcite create mode 100644 .vim/ftplugin/latex-suite/packages/pagenote create mode 100644 .vim/ftplugin/latex-suite/packages/parallel create mode 100644 .vim/ftplugin/latex-suite/packages/plain create mode 100644 .vim/ftplugin/latex-suite/packages/plates create mode 100644 .vim/ftplugin/latex-suite/packages/polski create mode 100644 .vim/ftplugin/latex-suite/packages/psgo create mode 100644 .vim/ftplugin/latex-suite/packages/schedule create mode 100644 .vim/ftplugin/latex-suite/packages/textfit create mode 100644 .vim/ftplugin/latex-suite/packages/times create mode 100644 .vim/ftplugin/latex-suite/packages/tipa create mode 100644 .vim/ftplugin/latex-suite/packages/ulem create mode 100644 .vim/ftplugin/latex-suite/packages/url create mode 100644 .vim/ftplugin/latex-suite/packages/verbatim create mode 100644 .vim/ftplugin/latex-suite/packages/version create mode 100644 .vim/ftplugin/latex-suite/projecttemplate.vim create mode 100644 .vim/ftplugin/latex-suite/pytools.py create mode 100644 .vim/ftplugin/latex-suite/smartspace.vim create mode 100644 .vim/ftplugin/latex-suite/templates.vim create mode 100644 .vim/ftplugin/latex-suite/templates/IEEEtran.tex create mode 100644 .vim/ftplugin/latex-suite/templates/article.tex create mode 100644 .vim/ftplugin/latex-suite/templates/report.tex create mode 100644 .vim/ftplugin/latex-suite/templates/report_two_column.tex create mode 100644 .vim/ftplugin/latex-suite/texmenuconf.vim create mode 100644 .vim/ftplugin/latex-suite/texproject.vim create mode 100644 .vim/ftplugin/latex-suite/texrc create mode 100644 .vim/ftplugin/latex-suite/texviewer.vim create mode 100644 .vim/ftplugin/latex-suite/version.vim create mode 100644 .vim/ftplugin/latex-suite/wizardfuncs.vim create mode 100644 .vim/ftplugin/tex.vim create mode 100644 .vim/ftplugin/tex_latexSuite.vim create mode 100644 .vim/indent/tex.vim create mode 100644 .vim/latextags create mode 100644 .vim/ltags create mode 160000 .vim/plugged/colorizer create mode 100644 .vim/plugin/SyntaxFolds.vim create mode 100644 .vim/plugin/filebrowser.vim create mode 100644 .vim/plugin/imaps.vim create mode 100644 .vim/plugin/remoteOpen.vim create mode 100644 .vim/spell/es.utf-8.spl create mode 100644 .vim/spell/es.utf-8.sug diff --git a/.vim/.netrwhist b/.vim/.netrwhist new file mode 100644 index 0000000..c800935 --- /dev/null +++ b/.vim/.netrwhist @@ -0,0 +1,12 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhistcnt =0 +let g:netrw_dirhist_0='/home/diegofcs/.config/qutebrowser' +let g:netrw_dirhist_9='/tmp/updates_void' +let g:netrw_dirhist_8='/etc/fonts/conf.avail' +let g:netrw_dirhist_7='/home/diegofcs/.config/suckless_soft/slstatus' +let g:netrw_dirhist_6='/home/diegofcs/.vim/plugged/vimtex' +let g:netrw_dirhist_5='/home/diegofcs/.vim/plugged' +let g:netrw_dirhist_4='/home/diegofcs/.vim' +let g:netrw_dirhist_3='/home/diegofcs/.config/suckless_soft/dmenu' +let g:netrw_dirhist_2='/home/diegofcs/.config' +let g:netrw_dirhist_1='/home/diegofcs/.config/dwm' diff --git a/.vim/Gemfile b/.vim/Gemfile new file mode 100644 index 0000000..9f127bd --- /dev/null +++ b/.vim/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'vim-flavor', '~> 4.0.1' diff --git a/.vim/autoload/plug.vim b/.vim/autoload/plug.vim new file mode 100644 index 0000000..e664b26 --- /dev/null +++ b/.vim/autoload/plug.vim @@ -0,0 +1,2804 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" +" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align +" Plug 'junegunn/vim-easy-align' +" +" " Any valid git URL is allowed +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Multiple Plug commands can be written in a single line using | separators +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using a non-default branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } +" +" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) +" Plug 'fatih/vim-go', { 'tag': '*' } +" +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Initialize plugin system +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" +" Plug options: +" +"| Option | Description | +"| ----------------------- | ------------------------------------------------ | +"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | +"| `rtp` | Subdirectory that contains Vim plugin | +"| `dir` | Custom directory for the plugin | +"| `as` | Use different name for the plugin | +"| `do` | Post-update hook (string or funcref) | +"| `on` | On-demand loading: Commands or ``-mappings | +"| `for` | On-demand loading: File types | +"| `frozen` | Do not update unless explicitly specified | +" +" More information: https://github.com/junegunn/vim-plug +" +" +" Copyright (c) 2017 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') +let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) +let s:vim8 = has('patch-8.0.0039') && exists('*job_start') +if s:is_win && &shellslash + set noshellslash + let s:me = resolve(expand(':p')) + set shellslash +else + let s:me = resolve(expand(':p')) +endif +let s:base_spec = { 'branch': '', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! s:is_powershell(shell) + return a:shell =~# 'powershell\(\.exe\)\?$' || a:shell =~# 'pwsh\(\.exe\)\?$' +endfunction + +function! s:isabsolute(dir) abort + return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)') +endfunction + +function! s:git_dir(dir) abort + let gitdir = s:trim(a:dir) . '/.git' + if isdirectory(gitdir) + return gitdir + endif + if !filereadable(gitdir) + return '' + endif + let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*') + if len(gitdir) && !s:isabsolute(gitdir) + let gitdir = a:dir . '/' . gitdir + endif + return isdirectory(gitdir) ? gitdir : '' +endfunction + +function! s:git_origin_url(dir) abort + let gitdir = s:git_dir(a:dir) + let config = gitdir . '/config' + if empty(gitdir) || !filereadable(config) + return '' + endif + return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze') +endfunction + +function! s:git_revision(dir) abort + let gitdir = s:git_dir(a:dir) + let head = gitdir . '/HEAD' + if empty(gitdir) || !filereadable(head) + return '' + endif + + let line = get(readfile(head), 0, '') + let ref = matchstr(line, '^ref: \zs.*') + if empty(ref) + return line + endif + + if filereadable(gitdir . '/' . ref) + return get(readfile(gitdir . '/' . ref), 0, '') + endif + + if filereadable(gitdir . '/packed-refs') + for line in readfile(gitdir . '/packed-refs') + if line =~# ' ' . ref + return matchstr(line, '^[0-9a-f]*') + endif + endfor + endif + + return '' +endfunction + +function! s:git_local_branch(dir) abort + let gitdir = s:git_dir(a:dir) + let head = gitdir . '/HEAD' + if empty(gitdir) || !filereadable(head) + return '' + endif + let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*') + return len(branch) ? branch : 'HEAD' +endfunction + +function! s:git_origin_branch(spec) + if len(a:spec.branch) + return a:spec.branch + endif + + " The file may not be present if this is a local repository + let gitdir = s:git_dir(a:spec.dir) + let origin_head = gitdir.'/refs/remotes/origin/HEAD' + if len(gitdir) && filereadable(origin_head) + return matchstr(get(readfile(origin_head), 0, ''), + \ '^ref: refs/remotes/origin/\zs.*') + endif + + " The command may not return the name of a branch in detached HEAD state + let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir)) + return v:shell_error ? '' : result[-1] +endfunction + +if s:is_win + function! s:plug_call(fn, ...) + let shellslash = &shellslash + try + set noshellslash + return call(a:fn, a:000) + finally + let &shellslash = shellslash + endtry + endfunction +else + function! s:plug_call(fn, ...) + return call(a:fn, a:000) + endfunction +endif + +function! s:plug_getcwd() + return s:plug_call('getcwd') +endfunction + +function! s:plug_fnamemodify(fname, mods) + return s:plug_call('fnamemodify', a:fname, a:mods) +endfunction + +function! s:plug_expand(fmt) + return s:plug_call('expand', a:fmt, 1) +endfunction + +function! s:plug_tempname() + return s:plug_call('tempname') +endfunction + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif has('nvim') + let home = stdpath('data') . '/plugged' + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp + return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call plug#() + if !executable('git') + return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') + endif + if has('win32') + \ && &shellslash + \ && (&shell =~# 'cmd\(\.exe\)\?$' || s:is_powershell(&shell)) + return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.') + endif + if !has('nvim') + \ && (has('win32') || has('win32unix')) + \ && !has('multi_byte') + return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) + command! -nargs=0 -bar -bang PlugClean call s:clean(0) + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:glob(from, pattern) + return s:lines(globpath(a:from, a:pattern)) +endfunction + +function! s:source(from, ...) + let found = 0 + for pattern in a:000 + for vim in s:glob(a:from, pattern) + execute 'source' s:esc(vim) + let found = 1 + endfor + endfor + return found +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! s:ask(message, ...) + call inputsave() + echohl WarningMsg + let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) + echohl None + call inputrestore() + echo "\r" + return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 +endfunction + +function! s:ask_no_interrupt(...) + try + return call('s:ask', a:000) + catch + return 0 + endtry +endfunction + +function! s:lazy(plug, opt) + return has_key(a:plug, a:opt) && + \ (empty(s:to_a(a:plug[a:opt])) || + \ !isdirectory(a:plug.dir) || + \ len(s:glob(s:rtp(a:plug), 'plugin')) || + \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('plug#end() called without calling plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + if get(g:, 'did_load_filetypes', 0) + filetype off + endif + for name in g:plugs_order + if !has_key(g:plugs, name) + continue + endif + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + let cmd = substitute(cmd, '!*$', '', '') + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or ``.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + augroup filetypedetect + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + augroup END + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', + \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + if has('syntax') && !exists('g:syntax_on') + syntax enable + end + else + call s:reload_plugins() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:load_plugin(spec) + call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') +endfunction + +function! s:reload_plugins() + for name in s:loaded_names() + call s:load_plugin(g:plugs[name]) + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + if !exists('s:git_version') + let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)') + endif + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) +endfunction + +if s:is_win + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction + + " Copied from fzf + function! s:wrap_cmds(cmds) + let cmds = [ + \ '@echo off', + \ 'setlocal enabledelayedexpansion'] + \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) + \ + ['endlocal'] + if has('iconv') + if !exists('s:codepage') + let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0) + endif + return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage)) + endif + return map(cmds, 'v:val."\r"') + endfunction + + function! s:batchfile(cmd) + let batchfile = s:plug_tempname().'.bat' + call writefile(s:wrap_cmds(a:cmd), batchfile) + let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0}) + if s:is_powershell(&shell) + let cmd = '& ' . cmd + endif + return [batchfile, cmd] + endfunction +else + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None +endfunction + +function! s:warn(cmd, msg) + echohl WarningMsg + execute a:cmd 'a:msg' + echohl None +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! s:doautocmd(...) + if exists('#'.join(a:000, '#')) + execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) + endif +endfunction + +function! s:dobufread(names) + for name in a:names + let path = s:rtp(g:plugs[name]) + for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin'] + if len(finddir(dir, path)) + if exists('#BufRead') + doautocmd BufRead + endif + return + endif + endfor + endfor +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 + let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') + if !empty(unloaded) + for name in unloaded + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + call s:dobufread(unloaded) + return 1 + end + return 0 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types, ...) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if a:0 + if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) + execute 'runtime' a:1 + endif + call s:source(rtp, a:2) + endif + call s:doautocmd('User', name) + endfor +endfunction + +function! s:lod_ft(pat, names) + let syn = 'syntax/'.a:pat.'.vim' + call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) + execute 'autocmd! PlugLOD FileType' a:pat + call s:doautocmd('filetypeplugin', 'FileType') + call s:doautocmd('filetypeindent', 'FileType') +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, with_prefix, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + + if a:with_prefix + let prefix = v:count ? v:count : '' + let prefix .= '"'.v:register.a:prefix + if mode(1) == 'no' + if v:operator == 'c' + let prefix = "\" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^', "\", '') . extra) +endfunction + +function! plug#(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec + let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??')) + let spec = extend(s:infer_properties(name, repo), opts) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(repo . ' ' . v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)' + if type == s:TYPE.string + if empty(a:arg) + throw printf(opt_errfmt, 'tag', 'string') + endif + let opts.tag = a:arg + elseif type == s:TYPE.dict + for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as'] + if has_key(a:arg, opt) + \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) + throw printf(opt_errfmt, opt, 'string') + endif + endfor + for opt in ['on', 'for'] + if has_key(a:arg, opt) + \ && type(a:arg[opt]) != s:TYPE.list + \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) + throw printf(opt_errfmt, opt, 'string or list') + endif + endfor + if has_key(a:arg, 'do') + \ && type(a:arg.do) != s:TYPE.funcref + \ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do)) + throw printf(opt_errfmt, 'do', 'string or funcref') + endif + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(s:plug_expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(s:plug_expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([s:rtp(spec), 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-\{1}\ / + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ + syn match plugTag /(tag: [^)]\+)/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag + syn match plugEdge /^ \X\+$/ + syn match plugEdge /^ \X*/ contained nextgroup=plugSha + syn match plugSha /[0-9a-f]\{7,9}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ + syn match plugH2 /^.*:\n-\+$/ + syn match plugH2 /^-\{2,}/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugH2 Type + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugDeleted Ignore + hi def link plugRelDate Comment + hi def link plugEdge PreProc + hi def link plugSha Identifier + hi def link plugTag Constant + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:finish_bindings() + nnoremap R :call retry() + nnoremap D :PlugDiff + nnoremap S :PlugStatus + nnoremap U :call status_update() + xnoremap U :call status_update() + nnoremap ]] :silent! call section('') + nnoremap [[ :silent! call section('b') +endfunction + +function! s:prepare(...) + if empty(s:plug_getcwd()) + throw 'Invalid current working directory. Cannot proceed.' + endif + + for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] + if exists(evar) + throw evar.' detected. Cannot proceed.' + endif + endfor + + call s:job_abort() + if s:switch_in() + if b:plug_preview == 1 + pc + endif + enew + else + call s:new_window() + endif + + nnoremap q :call close_pane() + if a:0 == 0 + call s:finish_bindings() + endif + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + + for k in ['', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap ' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + if exists('+colorcolumn') + setlocal colorcolumn= + endif + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + endif +endfunction + +function! s:close_pane() + if b:plug_preview == 1 + pc + let b:plug_preview = -1 + else + bd + endif +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:chsh(swap) + let prev = [&shell, &shellcmdflag, &shellredir] + if !s:is_win + set shell=sh + endif + if a:swap + if s:is_powershell(&shell) + let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s' + elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$' + set shellredir=>%s\ 2>&1 + endif + endif + return prev +endfunction + +function! s:bang(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + call s:load_plugin(spec) + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:git_revision(a:spec.dir) + if !empty(output) && !s:hash_match(sha, s:lines(output)[0]) + let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : '' + let output = s:system( + \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') + call s:finish_bindings() +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + echo + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:check_ruby() + silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") + if !exists('g:plug_ruby') + redraw! + return s:warn('echom', 'Warning: Ruby interface is broken') + endif + let ruby_version = split(g:plug_ruby, '\.') + unlet g:plug_ruby + return s:version_requirement(ruby_version, [1, 8, 7]) +endfunction + +function! s:update_impl(pull, force, args) abort + let sync = index(a:args, '--sync') >= 0 || has('vim_starting') + let args = filter(copy(a:args), 'v:val != "--sync"') + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') + endif + + let use_job = s:nvim || s:vim8 + let python = (has('python') || has('python3')) && !use_job + let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare(1) + call append(0, ['', '']) + normal! 2G + silent! redraw + + " Set remote name, overriding a possible user git config's clone.defaultRemoteName + let s:clone_opt = ['--origin', 'origin'] + if get(g:, 'plug_shallow', 1) + call extend(s:clone_opt, ['--depth', '1']) + if s:git_version_requirement(1, 7, 10) + call add(s:clone_opt, '--no-single-branch') + endif + endif + + if has('win32unix') || has('wsl') + call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input']) + endif + + let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 + redir => pyv + silent python import platform; print platform.python_version() + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + while use_job && sync + sleep 100m + if s:update.fin + break + endif + endwhile + endif +endfunction + +function! s:log4(name, msg) + call setline(4, printf('- %s (%s)', a:msg, a:name)) + redraw +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call append(3, '- Updating ...') | 4 + for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) + let [pos, _] = s:logpos(name) + if !pos + continue + endif + if has_key(spec, 'commit') + call s:log4(name, 'Checking out '.spec.commit) + let out = s:checkout(spec) + elseif has_key(spec, 'tag') + let tag = spec.tag + if tag =~ '\*' + let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir)) + if !v:shell_error && !empty(tags) + let tag = tags[0] + call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) + call append(3, '') + endif + endif + call s:log4(name, 'Checking out '.tag) + let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir) + else + let branch = s:git_origin_branch(spec) + call s:log4(name, 'Merging origin/'.s:esc(branch)) + let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir) + endif + if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && + \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) + call s:log4(name, 'Updating submodules. This may take a while.') + let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) + endif + let msg = s:format_message(v:shell_error ? 'x': '-', name, out) + if v:shell_error + call add(s:update.errors, name) + call s:regress_bar() + silent execute pos 'd _' + call append(4, msg) | 4 + elseif !empty(out) + call setline(pos, msg[0]) + endif + redraw + endfor + silent 4 d _ + try + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) + catch + call s:warn('echom', v:exception) + call s:warn('echo', '') + return + endtry + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if (!s:nvim && !s:vim8) || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + if s:nvim + silent! call jobstop(j.jobid) + elseif s:vim8 + silent! call job_stop(j.jobid) + endif + if j.new + call s:rm_rf(g:plugs[name].dir) + endif + endfor + let s:jobs = {} +endfunction + +function! s:last_non_empty_line(lines) + let len = len(a:lines) + for idx in range(len) + let line = a:lines[len-idx-1] + if !empty(line) + return line + endif + endfor + return '' +endfunction + +function! s:job_out_cb(self, data) abort + let self = a:self + let data = remove(self.lines, -1) . a:data + let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') + call extend(self.lines, lines) + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if !self.running || self.tick % len(s:jobs) == 0 + let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') + let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) + call s:log(bullet, self.name, result) + endif +endfunction + +function! s:job_exit_cb(self, data) abort + let a:self.running = 0 + let a:self.error = a:data != 0 + call s:reap(a:self.name) + call s:tick() +endfunction + +function! s:job_cb(fn, job, ch, data) + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + call call(a:fn, [a:job, a:data]) +endfunction + +function! s:nvim_cb(job_id, data, event) dict abort + return (a:event == 'stdout' || a:event == 'stderr') ? + \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : + \ s:job_cb('s:job_exit_cb', self, 0, a:data) +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], + \ 'new': get(a:opts, 'new', 0) } + let s:jobs[a:name] = job + + if s:nvim + if has_key(a:opts, 'dir') + let job.cwd = a:opts.dir + endif + let argv = a:cmd + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_stderr': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = s:plug_call('jobstart', argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = [jid < 0 ? argv[0].' is not executable' : + \ 'Invalid arguments (or job table is full)'] + endif + elseif s:vim8 + let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})')) + if has_key(a:opts, 'dir') + let cmd = s:with_cd(cmd, a:opts.dir, 0) + endif + let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd] + let jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'err_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ 'err_mode': 'raw', + \ 'out_mode': 'raw' + \}) + if job_status(jid) == 'run' + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = ['Failed to start job'] + endif + else + let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd])) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + let bullet = job.error ? 'x' : '-' + let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) + call s:log(bullet, a:name, empty(result) ? 'OK' : result) + call s:bar() + + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + let max = line('$') + for i in range(4, max > 4 ? max : 4) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, max > 5 ? max : 5) + if getline(j) !~ '^ ' + return [i, j - 1] + endif + endfor + return [i, i] + endif + endfor + return [0, 0] +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let [b, e] = s:logpos(a:name) + if b > 0 + silent execute printf('%d,%d d _', b, e) + if b > winheight('.') + let b = 4 + endif + else + let b = 4 + endif + " FIXME For some reason, nomodifiable is set after :d in vim8 + setlocal modifiable + call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim || s:vim8) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + call s:update_finish() + let s:update.fin = 1 + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = empty(globpath(spec.dir, '.git', 1)) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + if !new + let [error, _] = s:git_validate(spec, 0) + if empty(error) + if pull + let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch'] + if has_tag && !empty(globpath(spec.dir, '.git/shallow')) + call extend(cmd, ['--depth', '99999999']) + endif + if !empty(prog) + call add(cmd, prog) + endif + call s:spawn(name, cmd, { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } + endif + else + let cmd = ['git', 'clone'] + if !has_tag + call extend(cmd, s:clone_opt) + endif + if !empty(prog) + call add(cmd, prog) + endif + call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python') ? 'python' : 'python3' +execute py_exe "<< EOF" +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt')) +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_IS_WIN = vim.eval('s:is_win') == '1' + +class PlugError(Exception): + def __init__(self, msg): + self.msg = msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + CD = 'cd /d' if G_IS_WIN else 'cd' + + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + if cmd_dir: + self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + preexec_fn = not G_IS_WIN and os.setsid or None + self.proc = subprocess.Popen(self.cmd, stdout=tfile, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, shell=True, + preexec_fn=preexec_fn) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = '' if G_IS_WIN else nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + if G_IS_WIN: + os.kill(self.proc.pid, signal.SIGINT) + else: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + self.tag = args.get('tag', 0) + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + if target[-1] == '\\': + target = target[0:-1] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + actual_uri = self.repo_uri() + expect_uri = self.args['uri'] + regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') + ma = regex.match(actual_uri) + mb = regex.match(expect_uri) + if ma is None or mb is None or ma.groups() != mb.groups(): + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + start_cnt = thr.active_count() + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or thr.active_count() != start_cnt: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, ['OK'] if not msg else msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } + else + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + end + + def compare_git_uri a, b + regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} + regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + if vim7 + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + else + require 'io/console' # >= Ruby 1.9 + nil until IO.console.getch == 3.chr + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } unless vim7 + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt').join(' ') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, tag = pair.last.values_at *%w[dir uri tag] + exists = File.directory? dir + ok, result = + if exists + chdir = "#{cd} #{iswin ? dir : esc(dir)}" + ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif !compare_git_uri(current_uri, uri) + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc_cmd(arg, script) + let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g') + return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g') +endfunction + +function! s:shellesc_ps1(arg) + return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'" +endfunction + +function! s:shellesc_sh(arg) + return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'" +endfunction + +" Escape the shell argument based on the shell. +" Vim and Neovim's shellescape() are insufficient. +" 1. shellslash determines whether to use single/double quotes. +" Double-quote escaping is fragile for cmd.exe. +" 2. It does not work for powershell. +" 3. It does not work for *sh shells if the command is executed +" via cmd.exe (ie. cmd.exe /c sh -c command command_args) +" 4. It does not support batchfile syntax. +" +" Accepts an optional dictionary with the following keys: +" - shell: same as Vim/Neovim 'shell' option. +" If unset, fallback to 'cmd.exe' on Windows or 'sh'. +" - script: If truthy and shell is cmd.exe, escape for batchfile syntax. +function! plug#shellescape(arg, ...) + if a:arg =~# '^[A-Za-z0-9_/:.-]\+$' + return a:arg + endif + let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} + let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') + let script = get(opts, 'script', 1) + if shell =~# 'cmd\(\.exe\)\?$' + return s:shellesc_cmd(a:arg, script) + elseif s:is_powershell(shell) + return s:shellesc_ps1(a:arg) + endif + return s:shellesc_sh(a:arg) +endfunction + +function! s:glob_dir(path) + return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + " See `git help clone' + " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] + " [git@] github.com[:port] : junegunn/vim-plug [.git] + " file:// / junegunn/vim-plug [/] + " / junegunn/vim-plug [/] + let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' + let ma = matchlist(a:a, pat) + let mb = matchlist(a:b, pat) + return ma[1:2] ==# mb[1:2] +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir, ...) + let script = a:0 > 0 ? a:1 : 1 + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd) +endfunction + +function! s:system(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + if type(a:cmd) == s:TYPE.list + " Neovim's system() supports list argument to bypass the shell + " but it cannot set the working directory for the command. + " Assume that the command does not rely on the shell. + if has('nvim') && a:0 == 0 + return system(a:cmd) + endif + let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})')) + if s:is_powershell(&shell) + let cmd = '& ' . cmd + endif + else + let cmd = a:cmd + endif + if a:0 > 0 + let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list) + endif + if s:is_win && type(a:cmd) != s:TYPE.list + let [batchfile, cmd] = s:batchfile(cmd) + endif + return system(cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)] + let remote = result[-1] + if empty(remote) + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let sha = s:git_revision(a:spec.dir) + if empty(sha) + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let current_branch = result[0] + " Check tag + let origin_branch = s:git_origin_branch(a:spec) + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif origin_branch !=# current_branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ current_branch, origin_branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system([ + \ 'git', 'rev-list', '--count', '--left-right', + \ printf('HEAD...origin/%s', origin_branch) + \ ], a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ origin_branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + return s:system(s:is_win + \ ? 'rmdir /S /Q '.plug#shellescape(a:dir) + \ : ['rm', '-rf', a:dir]) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for invalid plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let errs = {} + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) + call add(dirs, spec.dir) + else + let [err, clean] = s:git_validate(spec, 1) + if clean + let errs[spec.dir] = s:lines(err)[0] + else + call add(dirs, spec.dir) + endif + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + if has_key(errs, f) + call append(line('$'), ' ' . errs[f]) + endif + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + 4 + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + let s:clean_count = 0 + call append(3, ['Directories to delete:', '']) + redraw! + if a:force || s:ask_no_interrupt('Delete all directories?') + call s:delete([6, line('$')], 1) + else + call setline(4, 'Cancelled.') + nnoremap d :set opfunc=delete_opg@ + nmap dd d_ + xnoremap d :call delete_op(visualmode(), 1) + echo 'Delete the lines (d{motion}) to delete the corresponding directories' + endif + endif + 4 + setlocal nomodifiable +endfunction + +function! s:delete_op(type, ...) + call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) +endfunction + +function! s:delete(range, force) + let [l1, l2] = a:range + let force = a:force + let err_count = 0 + while l1 <= l2 + let line = getline(l1) + if line =~ '^- ' && isdirectory(line[2:]) + execute l1 + redraw! + let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) + let force = force || answer > 1 + if answer + let err = s:rm_rf(line[2:]) + setlocal modifiable + if empty(err) + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + else + delete _ + call append(l1 - 1, s:format_message('x', line[1:], err)) + let l2 += len(s:lines(err)) + let err_count += 1 + endif + let msg = printf('Removed %d directories.', s:clean_count) + if err_count > 0 + let msg .= printf(' Failed to remove %d directories.', err_count) + endif + call setline(4, msg) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = s:plug_tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp]) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let branch = s:git_origin_branch(v) + if len(branch) + let range = origin ? '..origin/'.branch : 'HEAD@{1}..' + let cmd = ['git', 'log', '--graph', '--color=never'] + if s:git_version_requirement(2, 10, 0) + call add(cmd, '--no-show-signature') + endif + call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range]) + if has_key(v, 'rtp') + call extend(cmd, ['--', v.rtp]) + endif + let diff = s:system_chomp(cmd, v.dir) + if !empty(diff) + let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' + call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) + let cnts[origin] += 1 + endif + endif + let bar .= '=' + call s:progress_bar(2, bar, len(total)) + normal! 2G + redraw + endfor + if !cnts[origin] + call append(5, ['', 'N/A']) + endif + endfor + call setline(1, printf('%d plugin(s) updated.', cnts[0]) + \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) + + if cnts[0] || cnts[1] + nnoremap (plug-preview) :silent! call preview_commit() + if empty(maparg("\", 'n')) + nmap (plug-preview) + endif + if empty(maparg('o', 'n')) + nmap o (plug-preview) + endif + endif + if cnts[0] + nnoremap X :call revert() + echo "Press 'X' on each block to revert the update" + endif + normal! gg + setlocal nomodifiable +endfunction + +function! s:revert() + if search('^Pending updates', 'bnW') + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted' +endfunction + +function! s:snapshot(force, ...) abort + call s:prepare() + setf vim + call append(0, ['" Generated by vim-plug', + \ '" '.strftime("%c"), + \ '" :source this file in vim to restore the snapshot', + \ '" or execute: vim -S snapshot.vim', + \ '', '', 'PlugUpdate!']) + 1 + let anchor = line('$') - 3 + let names = sort(keys(filter(copy(g:plugs), + \'has_key(v:val, "uri") && isdirectory(v:val.dir)'))) + for name in reverse(names) + let sha = has_key(g:plugs[name], 'commit') ? g:plugs[name].commit : s:git_revision(g:plugs[name].dir) + if !empty(sha) + call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = s:plug_expand(a:1) + if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) + return + endif + call writefile(getline(1, '$'), fn) + echo 'Saved as '.a:1 + silent execute 'e' s:esc(fn) + setf vim + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@hi(group, guifg, guibg, ctermfg, ctermbg, attr, guisp) + call g:Base16hi(a:group, a:guifg, a:guibg, a:ctermfg, a:ctermbg, a:attr, a:guisp) +endfun + +" Vim editor colors +call hi("Normal", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("Bold", "", "", "", "", "bold", "") +call hi("Debug", s:gui08, "", s:cterm08, "", "", "") +call hi("Directory", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Error", s:gui00, s:gui08, s:cterm00, s:cterm08, "", "") +call hi("ErrorMsg", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("Exception", s:gui08, "", s:cterm08, "", "", "") +call hi("FoldColumn", s:gui0C, s:gui01, s:cterm0C, s:cterm01, "", "") +call hi("Folded", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("IncSearch", s:gui01, s:gui09, s:cterm01, s:cterm09, "none", "") +call hi("Italic", "", "", "", "", "none", "") +call hi("Macro", s:gui08, "", s:cterm08, "", "", "") +call hi("MatchParen", "", s:gui03, "", s:cterm03, "", "") +call hi("ModeMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("MoreMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Question", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Search", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "", "") +call hi("Substitute", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "none", "") +call hi("SpecialKey", s:gui03, "", s:cterm03, "", "", "") +call hi("TooLong", s:gui08, "", s:cterm08, "", "", "") +call hi("Underlined", s:gui08, "", s:cterm08, "", "", "") +call hi("Visual", "", s:gui02, "", s:cterm02, "", "") +call hi("VisualNOS", s:gui08, "", s:cterm08, "", "", "") +call hi("WarningMsg", s:gui08, "", s:cterm08, "", "", "") +call hi("WildMenu", s:gui08, s:gui0A, s:cterm08, "", "", "") +call hi("Title", s:gui0D, "", s:cterm0D, "", "none", "") +call hi("Conceal", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("Cursor", s:gui00, s:gui05, s:cterm00, s:cterm05, "", "") +call hi("NonText", s:gui03, "", s:cterm03, "", "", "") +call hi("LineNr", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("SignColumn", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("StatusLine", s:gui04, s:gui02, s:cterm04, s:cterm02, "none", "") +call hi("StatusLineNC", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("VertSplit", s:gui02, s:gui02, s:cterm02, s:cterm02, "none", "") +call hi("ColorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLineNr", s:gui04, s:gui01, s:cterm04, s:cterm01, "", "") +call hi("QuickFixLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("PMenu", s:gui05, s:gui01, s:cterm05, s:cterm01, "none", "") +call hi("PMenuSel", s:gui01, s:gui05, s:cterm01, s:cterm05, "", "") +call hi("TabLine", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineFill", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineSel", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "none", "") + +" Standard syntax highlighting +call hi("Boolean", s:gui09, "", s:cterm09, "", "", "") +call hi("Character", s:gui08, "", s:cterm08, "", "", "") +call hi("Comment", s:gui03, "", s:cterm03, "", "", "") +call hi("Conditional", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Constant", s:gui09, "", s:cterm09, "", "", "") +call hi("Define", s:gui0E, "", s:cterm0E, "", "none", "") +call hi("Delimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Float", s:gui09, "", s:cterm09, "", "", "") +call hi("Function", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Identifier", s:gui08, "", s:cterm08, "", "none", "") +call hi("Include", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Keyword", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Label", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Number", s:gui09, "", s:cterm09, "", "", "") +call hi("Operator", s:gui05, "", s:cterm05, "", "none", "") +call hi("PreProc", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Repeat", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Special", s:gui0C, "", s:cterm0C, "", "", "") +call hi("SpecialChar", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Statement", s:gui08, "", s:cterm08, "", "", "") +call hi("StorageClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("String", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Structure", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Tag", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Todo", s:gui0A, s:gui01, s:cterm0A, s:cterm01, "", "") +call hi("Type", s:gui0A, "", s:cterm0A, "", "none", "") +call hi("Typedef", s:gui0A, "", s:cterm0A, "", "", "") + +" C highlighting +call hi("cOperator", s:gui0C, "", s:cterm0C, "", "", "") +call hi("cPreCondit", s:gui0E, "", s:cterm0E, "", "", "") + +" C# highlighting +call hi("csClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csAttribute", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csModifier", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csType", s:gui08, "", s:cterm08, "", "", "") +call hi("csUnspecifiedStatement", s:gui0D, "", s:cterm0D, "", "", "") +call hi("csContextualStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csNewDecleration", s:gui08, "", s:cterm08, "", "", "") + +" CSS highlighting +call hi("cssBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("cssClassName", s:gui0E, "", s:cterm0E, "", "", "") +call hi("cssColor", s:gui0C, "", s:cterm0C, "", "", "") + +" Diff highlighting +call hi("DiffAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("DiffChange", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("DiffDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("DiffText", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("DiffAdded", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffFile", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("DiffNewFile", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffLine", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("DiffRemoved", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") + +" Git highlighting +call hi("gitcommitOverflow", s:gui08, "", s:cterm08, "", "", "") +call hi("gitcommitSummary", s:gui0B, "", s:cterm0B, "", "", "") +call hi("gitcommitComment", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitUntracked", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitDiscarded", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitSelected", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitHeader", s:gui0E, "", s:cterm0E, "", "", "") +call hi("gitcommitSelectedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitUnmergedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitDiscardedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitBranch", s:gui09, "", s:cterm09, "", "bold", "") +call hi("gitcommitUntrackedFile", s:gui0A, "", s:cterm0A, "", "", "") +call hi("gitcommitUnmergedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitDiscardedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitSelectedFile", s:gui0B, "", s:cterm0B, "", "bold", "") + +" GitGutter highlighting +call hi("GitGutterAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("GitGutterChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("GitGutterDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("GitGutterChangeDelete", s:gui0E, s:gui01, s:cterm0E, s:cterm01, "", "") + +" HTML highlighting +call hi("htmlBold", s:gui0A, "", s:cterm0A, "", "", "") +call hi("htmlItalic", s:gui0E, "", s:cterm0E, "", "", "") +call hi("htmlEndTag", s:gui05, "", s:cterm05, "", "", "") +call hi("htmlTag", s:gui05, "", s:cterm05, "", "", "") + +" JavaScript highlighting +call hi("javaScript", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptNumber", s:gui09, "", s:cterm09, "", "", "") +" pangloss/vim-javascript highlighting +call hi("jsOperator", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsReturn", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsThis", s:gui08, "", s:cterm08, "", "", "") +call hi("jsClassDefinition", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsFunction", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsFuncCall", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassMethodType", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsRegexpString", s:gui0C, "", s:cterm0C, "", "", "") +call hi("jsGlobalObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsGlobalNodeObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsExceptions", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsBuiltins", s:gui0A, "", s:cterm0A, "", "", "") + +" Mail highlighting +call hi("mailQuoted1", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailQuoted2", s:gui0B, "", s:cterm0B, "", "", "") +call hi("mailQuoted3", s:gui0E, "", s:cterm0E, "", "", "") +call hi("mailQuoted4", s:gui0C, "", s:cterm0C, "", "", "") +call hi("mailQuoted5", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailQuoted6", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailURL", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailEmail", s:gui0D, "", s:cterm0D, "", "", "") + +" Markdown highlighting +call hi("markdownCode", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownError", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("markdownCodeBlock", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownHeadingDelimiter", s:gui0D, "", s:cterm0D, "", "", "") + +" NERDTree highlighting +call hi("NERDTreeDirSlash", s:gui0D, "", s:cterm0D, "", "", "") +call hi("NERDTreeExecFile", s:gui05, "", s:cterm05, "", "", "") + +" PHP highlighting +call hi("phpMemberSelector", s:gui05, "", s:cterm05, "", "", "") +call hi("phpComparison", s:gui05, "", s:cterm05, "", "", "") +call hi("phpParent", s:gui05, "", s:cterm05, "", "", "") +call hi("phpMethodsVar", s:gui0C, "", s:cterm0C, "", "", "") + +" Python highlighting +call hi("pythonOperator", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonRepeat", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonStatement", s:gui0E, "", s:cterm0E, "", "", "") + +" Ruby highlighting +call hi("rubyAttribute", s:gui0D, "", s:cterm0D, "", "", "") +call hi("rubyConstant", s:gui0A, "", s:cterm0A, "", "", "") +call hi("rubyInterpolationDelimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("rubyRegexp", s:gui0C, "", s:cterm0C, "", "", "") +call hi("rubySymbol", s:gui0B, "", s:cterm0B, "", "", "") +call hi("rubyStringDelimiter", s:gui0B, "", s:cterm0B, "", "", "") + +" SASS highlighting +call hi("sassidChar", s:gui08, "", s:cterm08, "", "", "") +call hi("sassClassChar", s:gui09, "", s:cterm09, "", "", "") +call hi("sassInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixing", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixinName", s:gui0D, "", s:cterm0D, "", "", "") + +" Signify highlighting +call hi("SignifySignAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("SignifySignChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("SignifySignDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") + +" Spelling highlighting +call hi("SpellBad", "", "", "", "", "undercurl", s:gui08) +call hi("SpellLocal", "", "", "", "", "undercurl", s:gui0C) +call hi("SpellCap", "", "", "", "", "undercurl", s:gui0D) +call hi("SpellRare", "", "", "", "", "undercurl", s:gui0E) + +" Startify highlighting +call hi("StartifyBracket", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifyFile", s:gui07, "", s:cterm07, "", "", "") +call hi("StartifyFooter", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifyHeader", s:gui0B, "", s:cterm0B, "", "", "") +call hi("StartifyNumber", s:gui09, "", s:cterm09, "", "", "") +call hi("StartifyPath", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifySection", s:gui0E, "", s:cterm0E, "", "", "") +call hi("StartifySelect", s:gui0C, "", s:cterm0C, "", "", "") +call hi("StartifySlash", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifySpecial", s:gui03, "", s:cterm03, "", "", "") + +" Java highlighting +call hi("javaOperator", s:gui0D, "", s:cterm0D, "", "", "") + +" Remove functions +delf hi + +" Remove color variables +unlet s:gui00 s:gui01 s:gui02 s:gui03 s:gui04 s:gui05 s:gui06 s:gui07 s:gui08 s:gui09 s:gui0A s:gui0B s:gui0C s:gui0D s:gui0E s:gui0F +unlet s:cterm00 s:cterm01 s:cterm02 s:cterm03 s:cterm04 s:cterm05 s:cterm06 s:cterm07 s:cterm08 s:cterm09 s:cterm0A s:cterm0B s:cterm0C s:cterm0D s:cterm0E s:cterm0F diff --git a/.vim/compiler/tex.vim b/.vim/compiler/tex.vim new file mode 100644 index 0000000..54090bd --- /dev/null +++ b/.vim/compiler/tex.vim @@ -0,0 +1,412 @@ +" File: tex.vim +" Type: compiler plugin for LaTeX +" Original Author: Artem Chuprina +" Customization: Srinath Avadhanula +" Description: {{{ +" This file sets the 'makeprg' and 'errorformat' options for the LaTeX +" compiler. It is customizable to optionally ignore certain warnings and +" provides the ability to set a dynamic 'ignore-warning' level. +" +" By default it is set up in a 'non-verbose', 'ignore-common-warnings' mode, +" which means that irrelevant lines from the compilers output will be +" ignored and also some very common warnings are ignored. +" +" Depending on the 'ignore-level', the following kinds of messages are +" ignored. An ignore level of 3 for instance means that messages 1-3 will be +" ignored. By default, the ignore level is set to 4. +" +" 1. LaTeX Warning: Specifier 'h' changed to 't'. +" This errors occurs when TeX is not able to correctly place a floating +" object at a specified location, because of which it defaulted to the +" top of the page. +" 2. LaTeX Warning: Underfull box ... +" 3. LaTeX Warning: Overfull box ... +" both these warnings (very common) are due to \hbox settings not being +" satisfied nicely. +" 4. LaTeX Warning: You have requested ..., +" This warning occurs in slitex when using the xypic package. +" 5. Missing number error: +" Usually, when the name of an included eps file is spelled incorrectly, +" then the \bb-error message is accompanied by a bunch of "missing +" number, treated as zero" error messages. This level ignores these +" warnings. +" NOTE: number 5 is actually a latex error, not a warning! +" +" Use +" TCLevel +" where level is a number to set the ignore level dynamically. +" +" When TCLevel is called with the unquoted string strict +" TClevel strict +" then the 'efm' switches to a 'verbose', 'no-lines-ignored' mode which is +" useful when you want to make final checks of your document and want to be +" careful not to let things slip by. +" +" TIP: MikTeX has a bug where it sometimes erroneously splits a line number +" into multiple lines. i.e, if the warning is on line 1234. the compiler +" output is: +" LaTeX Warning: ... on input line 123 +" 4. +" In this case, vim will wrongly interpret the line-number as 123 instead +" of 1234. If you have cygwin, a simple remedy around this is to first +" copy the file vimlatex (provided) into your $PATH, make sure its +" executable and then set the variable g:tex_flavor to vimlatex in your +" ~/.vimrc (i.e putting let "g:tex_flavor = 'vimlatex'" in your .vimrc). +" This problem occurs rarely enough that its not a botheration for most +" people. +" +" TODO: +" 1. menu items for dynamically selecting a ignore warning level. +" }}} + +if exists('b:suppress_latex_suite') && b:suppress_latex_suite == 1 + finish +endif + +" avoid reinclusion for the same buffer. keep it buffer local so it can be +" externally reset in case of emergency re-sourcing. +if exists('b:doneTexCompiler') && !exists('b:forceRedoTexCompiler') + finish +endif +let b:doneTexCompiler = 1 + +" ============================================================================== +" Customization of 'efm': {{{ +" This section contains the customization variables which the user can set. +" g:Tex_IgnoredWarnings: This variable contains a ¡ seperated list of +" patterns which will be ignored in the TeX compiler's output. Use this +" carefully, otherwise you might end up losing valuable information. +if !exists('g:Tex_IgnoredWarnings') + let g:Tex_IgnoredWarnings = + \'Underfull'."\n". + \'Overfull'."\n". + \'specifier changed to'."\n". + \'You have requested'."\n". + \'Missing number, treated as zero.'."\n". + \'There were undefined references'."\n". + \'Citation %.%# undefined' +endif +" This is the number of warnings in the g:Tex_IgnoredWarnings string which +" will be ignored. +if !exists('g:Tex_IgnoreLevel') + let g:Tex_IgnoreLevel = 7 +endif +" There will be lots of stuff in a typical compiler output which will +" completely fall through the 'efm' parsing. This options sets whether or not +" you will be shown those lines. +if !exists('g:Tex_IgnoreUnmatched') + let g:Tex_IgnoreUnmatched = 1 +endif +" With all this customization, there is a slight risk that you might be +" ignoring valid warnings or errors. Therefore before getting the final copy +" of your work, you might want to reset the 'efm' with this variable set to 1. +" With that value, all the lines from the compiler are shown irrespective of +" whether they match the error or warning patterns. +" NOTE: An easier way of resetting the 'efm' to show everything is to do +" TCLevel strict +if !exists('g:Tex_ShowallLines') + let g:Tex_ShowallLines = 0 +endif + +" }}} +" ============================================================================== +" Customization of 'makeprg': {{{ + +" There are several alternate ways in which 'makeprg' is set up. +" +" Case 1 +" ------ +" The first is when this file is a part of latex-suite. In this case, a +" variable called g:Tex_DefaultTargetFormat exists, which gives the default +" format .tex files should be compiled into. In this case, we use the TTarget +" command provided by latex-suite. +" +" Case 2 +" ------ +" The user is using this file without latex-suite AND he wants to directly +" specify the complete 'makeprg'. Then he should set the g:Tex_CompileRule_dvi +" variable. This is a string which should be directly be able to be cast into +" &makeprg. An example of one such string is: +" +" g:Tex_CompileRule_dvi = 'pdflatex \\nonstopmode \\input\{$*\}' +" +" NOTE: You will need to escape back-slashes, {'s etc yourself if you are +" using this file independently of latex-suite. +" TODO: Should we also have a check for backslash escaping here based on +" platform? +" +" Case 3 +" ------ +" The use is using this file without latex-suite and he doesnt want any +" customization. In this case, this file makes some intelligent guesses based +" on the platform. If he doesn't want to specify the complete 'makeprg' but +" only the name of the compiler program (for example 'pdflatex' or 'latex'), +" then he sets b:tex_flavor or g:tex_flavor. + +if exists('g:Tex_DefaultTargetFormat') + exec 'TTarget '.g:Tex_DefaultTargetFormat +elseif exists('g:Tex_CompileRule_dvi') + let &l:makeprg = g:Tex_CompileRule_dvi +else + " If buffer-local variable 'tex_flavor' exists, it defines TeX flavor, + " otherwize the same for global variable with same name, else it will be LaTeX + if exists("b:tex_flavor") + let current_compiler = b:tex_flavor + elseif exists("g:tex_flavor") + let current_compiler = g:tex_flavor + else + let current_compiler = "latex" + end + if has('win32') + let escChars = '' + else + let escChars = '{}\' + endif + " Furthermore, if 'win32' is detected, then we want to set the arguments up so + " that miktex can handle it. + if has('win32') + let options = '--src-specials' + else + let options = '' + endif + let &l:makeprg = current_compiler . ' ' . options . + \ escape(' \nonstopmode \input{$*}', escChars) +endif + +" }}} +" ============================================================================== +" Functions for setting up a customized 'efm' {{{ + +" IgnoreWarnings: parses g:Tex_IgnoredWarnings for message customization {{{ +" Description: +function! IgnoreWarnings() + let s:Ignored_Overfull = 0 + + let i = 1 + while s:Strntok(g:Tex_IgnoredWarnings, "\n", i) != '' && + \ i <= g:Tex_IgnoreLevel + let warningPat = s:Strntok(g:Tex_IgnoredWarnings, "\n", i) + let warningPat = escape(substitute(warningPat, '[\,]', '%\\\\&', 'g'), ' ') + + if warningPat =~? 'overfull' + let s:Ignored_Overfull = 1 + if ( v:version > 800 || v:version == 800 && has("patch26") ) + " Overfull warnings are ignored as 'warnings'. Therefore, we can gobble + " some of the following lines with %-C (see below) + exe 'setlocal efm+=%-W%.%#'.warningPat.'%.%#' + else + exe 'setlocal efm+=%-G%.%#'.warningPat.'%.%#' + endif + else + exe 'setlocal efm+=%-G%.%#'.warningPat.'%.%#' + endif + + let i = i + 1 + endwhile +endfunction + +" }}} +" SetLatexEfm: sets the 'efm' for the latex compiler {{{ +" Description: +function! SetLatexEfm() + + let pm = ( g:Tex_ShowallLines == 1 ? '+' : '-' ) + + " Add a dummy entry to overwrite the global setting. + setlocal efm=dummy_value + + if !g:Tex_ShowallLines + call s:IgnoreWarnings() + endif + + setlocal efm+=%E!\ LaTeX\ %trror:\ %m + setlocal efm+=%E!\ %m + setlocal efm+=%E%f:%l:\ %m + + " If we do not ignore 'overfull \hbox' messages, we care for them to get the + " line number. + if s:Ignored_Overfull == 0 + setlocal efm+=%+WOverfull\ %mat\ lines\ %l--%*\\d + setlocal efm+=%+WOverfull\ %mat\ line\ %l + endif + + " Add some generic warnings + setlocal efm+=%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%# + setlocal efm+=%+W%.%#\ at\ lines\ %l--%*\\d + setlocal efm+=%+WLaTeX\ %.%#Warning:\ %m + setlocal efm+=%+WPackage\ %.%#Warning:\ %m + + " 'Overfull \hbox' messages are ended by: + exec 'setlocal efm+=%'.pm.'Z\ []' + + " Empty line ends multi-line messages + setlocal efm+=%-Z + + exec 'setlocal efm+=%'.pm.'C(%.%#)\ %#%m\ on\ input\ line\ %l.' + exec 'setlocal efm+=%'.pm.'C(%.%#)\ %#%m' + + exec 'setlocal efm+=%'.pm.'Cl.%l\ %m' + exec 'setlocal efm+=%'.pm.'Cl.%l\ ' + exec 'setlocal efm+=%'.pm.'C\ \ %m' + exec 'setlocal efm+=%'.pm.'C%.%#-%.%#' + exec 'setlocal efm+=%'.pm.'C%.%#[]%.%#' + exec 'setlocal efm+=%'.pm.'C[]%.%#' + exec 'setlocal efm+=%'.pm.'C%.%#%[{}\\]%.%#' + exec 'setlocal efm+=%'.pm.'C<%.%#>%m' + exec 'setlocal efm+=%'.pm.'C\ \ %m' + exec 'setlocal efm+=%'.pm.'GSee\ the\ LaTeX%m' + exec 'setlocal efm+=%'.pm.'GType\ \ H\ %m' + exec 'setlocal efm+=%'.pm.'G\ ...%.%#' + exec 'setlocal efm+=%'.pm.'G%.%#\ (C)\ %.%#' + exec 'setlocal efm+=%'.pm.'G(see\ the\ transcript%.%#)' + exec 'setlocal efm+=%'.pm.'G\\s%#' + + " After a 'overfull \hbox' message, there is some garbage from the input. + " We try to match it, such that parenthesis in this garbage does not + " confuse the OPQ-patterns below. + " Every line continues a multiline pattern (hopefully a 'overfull \hbox' + " message). + " Due to a bug in old versions of vim, this cannot be used if we ignore the + " 'overfull \hbox' messages, see vim/vim#1126. + if s:Ignored_Overfull == 0 || ( v:version > 800 || v:version == 800 && has("patch26") ) + exec 'setlocal efm+=%'.pm.'C%.%#' + endif + + " Now, we try to trace the used files. + " + " In principle, the following combinations could arise in the LaTeX logs: + " + " )* \((%f)\)* (%f + " [Close files, skip some files, open a file] + " + " (%f))* + " [Skip some files, close some files] + " + " And you will find many more awkward combinations... + " + " Even something like this is possible: + " [18] [19] [20] (./bla.bbl [21]) + " + " After a %[OPQ] is matched, the %r part is passed to the same and + " following patterns. Hence, we have to add many $[OPQ]-patterns. + " + " If you use vim to compile your documents, you might want to use + " :let $max_print_line=1024 + " such that latex will not wrap the filenames. Otherwise, you could use it + " as an environment variable or simply use + " max_print_line=1024 pdflatex ... + " in your terminal. If you are using latexmk, you should set + " $ENV{'max_print_line'} = '1024'; + " $log_wrap = $ENV{'max_print_line'}; + " in your ~/.latexmkrc + + " The first pattern is needed to match lines like + " '[10] [11] (some_file.txt)', + " where the first number correspond to an output page in the document + exec 'setlocal efm+=%'.pm.'O[%*\\d]%r' + + " Some close patters + exec 'setlocal efm+=%'.pm.'Q\ %#)%r' + exec 'setlocal efm+=%'.pm.'Q\ %#[%\\d%*[^()])%r' + " The next pattern is needed to match lines like + " ' ])', + exec 'setlocal efm+=%'.pm.'Q\ %#])%r' + + " Skip pattern + exec 'setlocal efm+=%'.pm.'O(%f)%r' + + " Some openings + exec 'setlocal efm+=%'.pm.'P(%f%r' + exec 'setlocal efm+=%'.pm.'P%*[^()](%f%r' + exec 'setlocal efm+=%'.pm.'P(%f%*[^()]' + exec 'setlocal efm+=%'.pm.'P[%\\d%[^()]%#(%f%r' + + + " Now, the sledgehammer to cope with awkward endless combinations (did you + " ever tried tikz/pgf?) + " We have to build up the string first, otherwise we cannot append it with + " '+='. + let PQO = '%'.pm.'P(%f%r,%'.pm.'Q)%r,%'.pm.'O(%f)%r,%'.pm.'O[%*\\d]%r' + let PQOs = PQO + for xxx in range(3) + let PQOs .= ',' . PQO + endfor + exec 'setlocal efm+=' . PQOs + + " Finally, there are some lonely page numbers after all the patterns. + exec 'setlocal efm+=%'.pm.'O[%*\\d' + + " This gobbles some entries consisting only of whitespace, in fact, it + " matches the empty line. + " See https://github.com/vim/vim/issues/807 + exec 'setlocal efm+=%'.pm.'O' + + if g:Tex_IgnoreUnmatched && !g:Tex_ShowallLines + " Ignore all lines which are unmatched so far. + setlocal efm+=%-G%.%# + " Sometimes, there is some garbage after a ')' + setlocal efm+=%-O%.%# + endif + + " Finally, remove the dummy entry. + setlocal efm-=dummy_value + +endfunction + +" }}} +" Strntok: extract the n^th token from a list {{{ +" example: Strntok('1,23,3', ',', 2) = 23 +fun! Strntok(s, tok, n) + return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}') +endfun + +" }}} +" SetTexCompilerLevel: sets the "level" for the latex compiler {{{ +function! SetTexCompilerLevel(...) + if a:0 > 0 + let level = a:1 + else + call Tex_ResetIncrementNumber(0) + echo substitute(g:Tex_IgnoredWarnings, + \ '^\|\n\zs\S', '\=Tex_IncrementNumber(1)." ".submatch(0)', 'g') + let level = input("\nChoose an ignore level: ") + if level == '' + return + endif + endif + if level == 'strict' + let g:Tex_ShowallLines = 1 + elseif level =~ '^\d\+$' + let g:Tex_ShowallLines = 0 + let g:Tex_IgnoreLevel = level + else + echoerr "SetTexCompilerLevel: Unkwown option [".level."]" + end + call s:SetLatexEfm() +endfunction + +com! -nargs=? TCLevel :call SetTexCompilerLevel() +" }}} + +" }}} +" ============================================================================== + +call s:SetLatexEfm() + +" Set the errorfile if not already set by somebody else +if &errorfile ==# '' || &errorfile ==# 'errors.err' + try + execute 'set errorfile=' . fnameescape(Tex_GetMainFileName(':p:r') . '.log') + catch + endtry +endif + + +if !exists('*Tex_Debug') + function! Tex_Debug(...) + endfunction +endif + +call Tex_Debug("compiler/tex.vim: sourcing this file", "comp") + +" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 diff --git a/.vim/doc/Makefile b/.vim/doc/Makefile new file mode 100644 index 0000000..7e05e67 --- /dev/null +++ b/.vim/doc/Makefile @@ -0,0 +1,62 @@ +projects = latex-suite latex-suite-quickstart +htmlfiles = $(addsuffix .html, $(projects)) +txtfiles = $(addsuffix .txt, $(projects)) +cssfiles = $(addsuffix .css, $(projects)) +all = $(projects) $(htmlfiles) $(cssfiles) $(txtfiles) + + +xsltproc=xsltproc +db2vim=db2vim/db2vim + +# Use for debugging: +#xsltproc=strace -e trace=file xsltproc --nonet --load-trace +# export XML_DEBUG_CATALOG = 1 + +# Specify local catalog to not use system installed dtd/xsl files +# export XML_CATALOG_FILES=catalog.xml + +# User configuration of this Makefile goes into Makefile.local +# E.g. to use a catalog file installed by the user. +-include Makefile.local + +# Default Target is to create all documentation files +all: $(all) + +# create multi page html (chunk xhtml) +$(projects): %: %.xml latex-suite-chunk.xsl latex-suite-common.xsl + $(xsltproc) -o $@/ latex-suite-chunk.xsl $< + +# create single html files +$(htmlfiles): %.html: %.xml latex-suite.xsl latex-suite-common.xsl + $(xsltproc) -o $@ latex-suite.xsl $< + +# create vim flat files +latex-suite.txt: %.txt: %.xml + $(db2vim) --prefix=ls_ $< > $@ + +latex-suite-quickstart.txt: %.txt: %.xml + $(db2vim) --prefix=lq_ $< > $@ + +# validate xml +validate: + for file in *.xml; do \ + xmllint --valid --noout $$file; \ + done + +clean: + rm -f $(htmlfiles) + rm -rf $(projects) + +# $(txtfiles) are currently in revision control, therefore they are not +# removed in the clean target +mr-proper: clean + rm -f $(txtfiles) + +upload: $(all) +# vim-latex-web is configured in ~/.ssh/config +#Host vim-latex-web +# Hostname web.sourceforge.net +# User SOURCEFORGE_USERNAME,vim-latex + rsync --perms --chmod g+w,o-w --delete -lrtvz $(all) vim-latex-web:/home/groups/v/vi/vim-latex/htdocs/documentation/ + +# vim:nowrap diff --git a/.vim/doc/Makefile.in b/.vim/doc/Makefile.in new file mode 100644 index 0000000..6d5e614 --- /dev/null +++ b/.vim/doc/Makefile.in @@ -0,0 +1,29 @@ +# Manual files +ls-flat: + java com.icl.saxon.StyleSheet latex-suite.xml latex-suite.xsl > latex-suite.html + +ls-chunk: + ( \ + cd latex-suite && \ + java com.icl.saxon.StyleSheet ../latex-suite.xml ../latex-suite-chunk.xsl \ + ) + +ls-txt: + db2vim --prefix=ls_ latex-suite.xml > latex-suite.txt + +# Quickstart files +lsq-flat: + java com.icl.saxon.StyleSheet latex-suite-quickstart.xml latex-suite.xsl > latex-suite-quickstart.html + +lsq-chunk: + ( \ + cd latex-suite-quickstart && \ + java com.icl.saxon.StyleSheet ../latex-suite-quickstart.xml ../latex-suite-chunk.xsl \ + ) + +lsq-txt: + db2vim --prefix=lq_ latex-suite-quickstart.xml > latex-suite-quickstart.txt + +cvsci: + cvs ci latex-suite.xml latex-suite.txt +# vim:nowrap diff --git a/.vim/doc/README b/.vim/doc/README new file mode 100644 index 0000000..7ba1d7c --- /dev/null +++ b/.vim/doc/README @@ -0,0 +1,110 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +This file is outdated, please look at README.new for updated information +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +==================================== +Generating Latex-Suite documentation +==================================== + +In order to generate the html files and vim-help files from the XML source, +you will need to do follow the following steps. The steps are complex only +for a windows machine. On most (modern) linux machines, the various +utilities are already installed and all you need to do is some +soft-linking. + +1. Download the Docbook XSL stylesheets from + + http://sourceforge.net/project/showfiles.php?group_id=21935 + + I downloaded docbook-xsl-1.61.2.tar.gz. Unpack this archive under the + present directory. You should see something like:: + + ./docbook-xsl-1.XX.X/ + + Rename this to:: + + ./docbook-xsl + + Alternatively, if you are on a modern unix system, the docbook-xsl + stylesheets should already be installed on your system. Soft-linking + will thus work more simply. On a typical Debian box, just do:: + + ln -s /usr/share/sgml/docbook/stylesheet/xsl/nwalsh docbook-xsl + + The docbook-xsl stylesheets can be installed via the docbook-xsl + package on Debian. (Just use apt-get). + +2. Download the Docbook DTD from + + http://www.oasis-open.org/docbook/xml/4.2/docbook-xml-4.2.zip + + Extract this into a subdirectory ``docbook-xml/`` under the present + directory. You should see something like:: + + ./docbook-xml/ + + with a file ``docbookx.dtd`` located there. + + **CAUTION**: + The archive above does not create a top level directory but + unzips directly into the present directory. Therefore, make sure to + run the unzip by first creating ``./docbook-xml/``, copying the zip + file there and then unzipping. + + Alternatively, if you are on a modern unix system, the docbook-xml DTD + will already be installed. Softlinking will thus work. On a typical + Debian box, you could do:: + + ln -s /usr/share/sgml/docbook/dtd/xml/4.2 docbook-xml + + On debian, you need the docbook-xml package on Debian. (Just use + apt-get). + +3. Download saxon.jar from + + http://vim-latex.sourceforge.net/documentation/saxon.jar + + This is the bare .jar file without any of the other things which saxon + comes with. Add the ``saxon.jar`` file to your ``$CLASSPATH`` setting. + + **NOTE:** + The ``$CLASSPATH`` setting should point to the ``saxon.jar`` file, + not the directory where it resides. + + Again, on a unix system, you might not need to download this. For debian + systems, the saxon.jar file resides in:: + + /usr/share/java/saxon.jar + + You can point your ``$CLASSPATH`` to that file. + +4. Download db2vim (created by me :)) via anonymous cvs:: + + mkdir -p ~/bin/db2vim + cvs -d :pserver:anonymous@cvs.vim-latex.sf.net:/cvsroot/vim-latex \ + co -d ~/bin/db2vim db2vim + + Add the ``~/bin/db2vim/`` directory thus created to your ``$PATH`` + setting. + +5. Create a new directory ``latex-suite/`` under the present directory for + the chunked html files to reside in. You should see something like:: + + ./latex-suite/ + +6. Copy ``Makefile.in`` to ``Makefile`` or ``makefile`` and perform any + necessary customizations. For example, if you are using Activestate + python under windows, you will need to change the ls-txt: target as:: + + python e:/srinath/testing/db2vim/db2vim latex-suite.xml > latex-suite.txt + + +Thats it! You are ready. Now you can do:: + + make ls-chunk + make ls-flat + make ls-txt + +to create the 3 formats. + +Author: Srinath Avadhanula diff --git a/.vim/doc/README.new b/.vim/doc/README.new new file mode 100644 index 0000000..623e514 --- /dev/null +++ b/.vim/doc/README.new @@ -0,0 +1,25 @@ +==================================== +Generating Latex-Suite documentation +==================================== + +You need: +- xsltproc +- Docbook XSL stylesheets (*) +- Docbook DTD (*) + +(*) These files will be downloaded every time you create the documentation, +unless you install or download them. + +To install the required packages, you can run as root on + +Fedora: + + yum install libxslt docbook-style-xsl docbook-dtds + +Arch Linux: + + pacman -S libxslt docbook-xml docbook-xsl + +Ubuntu (16.04): + + apt-get install xsltproc docbook-xsl diff --git a/.vim/doc/catalog.xml b/.vim/doc/catalog.xml new file mode 100644 index 0000000..cfc984c --- /dev/null +++ b/.vim/doc/catalog.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/.vim/doc/db2vim/db2vim b/.vim/doc/db2vim/db2vim new file mode 100644 index 0000000..8d9eb01 --- /dev/null +++ b/.vim/doc/db2vim/db2vim @@ -0,0 +1,715 @@ +#!/usr/bin/env python2 +r""" +db2vim [options] file.xml + +SHORT OPTIONS + +-d Prints some debugging information on stderr. + +-s If given, the db2vim operates in a 'stict' conversion mode, i.e, any + element which does not have a handler defined for them it be + completeley ignored including all its children. Otherwise, db2vim will + recurse into an unknown tag and process any of its children it + recognizes. Since db2vim always recognizes text nodes, not using this + option has the effect that all text will be printed out, even if + somewhat incorrectly. + +LONG OPTIONS + +--prefix= + This is a string like "ls_" which will be prepended to the section + numbers. Default to 'ls_' if unsupplied. +""" + + +import xml.dom.minidom +import getopt +import string +import re +import sys + +# Okay. so I import *. Shoot me. +from textutils import * +from domutils import * + +# define a bunch of constants for formatting. +TEXT_WIDTH = 80 +BLOCK_QUOTE = 4 +COL_SPACE = 2 + +# a bunch of globals used in creating the Table of contents. +# +# TOC_HASH['section 1.1 label'] = 'ls_1_1' +# +# LEVEL_HASH['section 1.1 label'] = 1 +# (top level article has level 0) +# +# TITLE_HASH['section 1.1 label'] = 'Title of section 1.1' +# +# FILENAME = the name of the file being processed with the last extension +# changed to .txt +# +# TOC_PREFIX = 'ls_' (the prefix used to create the section labels). +TOC_HASH = {} +LEVEL_HASH = {} +TITLE_HASH = {} +FILENAME = '' +TOC_PREFIX = '' + +ANCHOR_HASH = {} +URL_HASH = {} + +# STDERR for printing debugging info. +DEBUG = 0 +STDERR = sys.stderr +STRICT = 0 +NUM_ANCHORS = {0: 1} + +############################################################################### +# Miscellaneous utility functions +############################################################################### + + +def encodeTo52(num): + if num < 26: + return unichr(ord('a') + num) + elif num < 52: + return unichr(ord('A') + num - 26) + else: + return encodeTo52(int(num / 52)) + encodeTo52(num % 52) + + +def makeTocHash(rootElement, width, prefix='', level=0): + lastLabelUsed = 0 + + for section in rootElement.getChildrenByTagName('section'): + title = section.getChildrenByTagName('title')[0] + titleText = handleElement(title, width) + lastLabelUsed += 1 + thisLabel = TOC_PREFIX + prefix + str(lastLabelUsed) + + sectionid = section.getAttribute('id') + if not sectionid: + section.setAttribute('id', thisLabel) + sectionid = thisLabel + + NUM_ANCHORS[0] += 1 + ANCHOR_HASH[sectionid] = TOC_PREFIX + 'a_' + encodeTo52( + NUM_ANCHORS[0] + 52) + + TOC_HASH[sectionid] = thisLabel + LEVEL_HASH[sectionid] = level + TITLE_HASH[sectionid] = titleText + + if section.getChildrenByTagName('section'): + makeTocHash(section, width - 5, prefix=prefix + + str(lastLabelUsed) + '_', level=level + 1) + + +def makeAnchorHash(rootElement): + anchors = rootElement.getElementsByTagName( + 'anchor') + rootElement.getElementsByTagName('note') + for anchor in anchors: + if not anchor.getAttribute('id'): + continue + + NUM_ANCHORS[0] += 1 + if anchor.getAttribute('id') in ANCHOR_HASH or \ + anchor.getAttribute('id') in TOC_HASH: + sys.stderr.write("Warning: anchor [%s] multiply defined\n" % + anchor.getAttribute('id')) + + ANCHOR_HASH[anchor.getAttribute( + 'id')] = TOC_PREFIX + 'a_' + encodeTo52(NUM_ANCHORS[0] + 52) + + +def makeURLHash(rootElement): + urls = rootElement.getElementsByTagName('ulink') + numURLs = 0 + for url in urls: + if not url.getAttribute('url') or url.getAttribute('url') in URL_HASH: + continue + numURLs += 1 + URL_HASH[url.getAttribute('url')] = TOC_PREFIX + 'u_' + str(numURLs) + + +def makeTOC(node, width, maxlevel=1): + retText = "" + + for section in node.getChildrenByTagName('section'): + + sectionid = section.getAttribute('id') + thisLabel = TOC_HASH.get(sectionid, '') + titleText = TITLE_HASH.get(sectionid, '') + level = LEVEL_HASH.get(sectionid, 10) + + if level <= maxlevel: + retText += '|' + thisLabel + '| ' + titleText + '\n' + + if level < maxlevel and section.getChildrenByTagName('section'): + childText = makeTOC(section, width - 5) + retText += VertCatString(" ", 4, childText) + '\n' + + retText = re.sub(r'\s+$', r'\n', retText) + + return retText + + +############################################################################### +# Generalized function for handling dom elements. +############################################################################### + + +def IsInlineTag(self): + if self.nodeType == self.TEXT_NODE: + return 1 + elif inlineTags.get(self.tagName, 0): + return 1 + else: + return 0 + + +def getChildrenByTagName(self, name): + """ + extension to the xml.dom.minidom.Element class. returns all direct + descendants of this Element. + """ + nodeList = [] + + child = self.firstChild + while not child is None: + if child.nodeType == child.ELEMENT_NODE and child.nodeName == name: + nodeList.append(child) + + child = child.nextSibling + + return nodeList + +xml.dom.minidom.Element.getChildrenByTagName = getChildrenByTagName + + +def handleElement(rootElement, width=TEXT_WIDTH): + """ + Generalized function to handle an Element node in a DOM tree. + """ + + retText = "" + child = rootElement.firstChild + while not child is None: + + printerr('node type = %d' % child.nodeType) + if child.nodeType == child.ELEMENT_NODE: + printerr('processing [%s]' % child.tagName) + + isinline = IsInlineTag(child) + + # if the child is an Element and if a handler exists, then call it. + if not isinline \ + and child.nodeType == child.ELEMENT_NODE \ + and child.tagName in handlerMaps: + # offset the child text by the current indentation value + printerr('making recursive call to known child.') + retText += handlerMaps[child.tagName](child, width) + child = child.nextSibling + + elif not isinline \ + and child.nodeType == child.PROCESSING_INSTRUCTION_NODE \ + and child.target == 'vimhelp': + + if child.data in handlerMaps: + retText += handlerMaps[child.data](child, width) + + child = child.nextSibling + + # if its a text node or an inline element node, collect consecutive + # text nodes into a single paragraph and indent it. + elif isinline: + + text = "" + while not child is None and IsInlineTag(child): + if child.nodeType == child.TEXT_NODE: + text += child.data + elif child.nodeType == child.ELEMENT_NODE: + if child.tagName in handlerMaps: + text += handlerMaps[child.tagName](child, width) + else: + text += GetText(child.childNodes) + child = child.nextSibling + + retText += IndentParagraphs(text, width) + + # If we cannot understand _anything_ about the element, then just + # handle its children hoping we have something to gather from + # there. + elif not STRICT: + printerr('making recursive call for unkown child') + retText += handleElement(child, width) + child = child.nextSibling + + else: + child = child.nextSibling + + return retText + + +############################################################################### +# Functions for handling various xml tags +############################################################################### + + +def handleArticleInfo(articleinfo, width): + + makeTocHash(articleinfo.parentNode, width) + makeAnchorHash(articleinfo.parentNode) + makeURLHash(articleinfo.parentNode) + + title = articleinfo.getChildrenByTagName('title') + if title is None: + print("Article should have a title!") + sys.exit(1) + + name = GetText(title[0].childNodes) + authors = articleinfo.getChildrenByTagName('author') + + authorText = '' + for author in authors: + firstname = '' + surname = '' + if author.getElementsByTagName('firstname'): + firstname = GetTextFromElementNode(author, 'firstname')[0] + if author.getChildrenByTagName('surname'): + surname = GetTextFromElementNode(author, 'surname')[0] + if author.getElementsByTagName('email'): + email = GetTextFromElementNode(author, 'email')[0] + authorText = authorText + firstname + ' ' + surname + \ + ' <' + email + '>\n' + + abstractText = '' + abstract = articleinfo.getChildrenByTagName('abstract') + if abstract is not None: + abstractText = '\n\n' + CenterText('Abstract\n========', width) + abstractText += handleElement(abstract[0], width) + '\n' + + retText = CenterText(name + '\n*' + FILENAME + '*\n' + authorText, width) + retText += abstractText + + toc = makeTOC(articleinfo.parentNode, width) + + return retText + '\n' + RightJustify('*' + FILENAME + '-toc*', width) + \ + '\n' + toc + + +def handleOption(option, width): + retText = "" + names = GetTextFromElementNode(option, "name") + + for name in names: + retText += string.rjust("*" + name + "*", width) + "\n" + + nameTexts = "" + maxNameLen = -1 + for name in names: + maxNameLen = max(maxNameLen, len(name + " ")) + nameTexts += name + " \n" + + desc = option.getChildrenByTagName("desc")[0] + descText = handleElement(desc, width=width - maxNameLen) + + retText += VertCatString(nameTexts + " ", None, descText) + + return retText + "\n" + + +def handleOptionDefault(default, width): + type = string.join(GetTextFromElementNode(default, "type"), "\n") + extra = string.join(GetTextFromElementNode(default, "extra"), "\n") + return type + "\t(" + extra + ")" + + +def handleTableRoot(root, width): + tgroup = root.getChildrenByTagName('tgroup')[0] + if tgroup is None: + return '' + + rows = [] + numHeadRows = 0 + if tgroup.getChildrenByTagName('thead'): + thead = tgroup.getChildrenByTagName('thead')[0] + rows = thead.getChildrenByTagName('row') + numHeadRows = len(rows) + + tbody = tgroup.getChildrenByTagName('tbody')[0] + rows += tbody.getChildrenByTagName('row') + + widths, text = calculateColumnWidthsDoublePass(rows, width) + + headText = text[0:numHeadRows] + bodyText = text[numHeadRows:] + + headTable = FormatTable(headText, ROW_SPACE=1, COL_SPACE= + COL_SPACE, justify=0, widths=widths) + if headTable: + headTable = re.sub(r'\n|$', '\g<0>~', headTable) + bodyTable = FormatTable(bodyText, ROW_SPACE=1, COL_SPACE= + COL_SPACE, justify=0, widths=widths) + + return headTable + '\n' + re.sub(r'\n+$', '', bodyTable) + '\n\n' + + +def calculateColumnWidths(rows, alloc_widths): + widths = {} + text = [] + for row in rows: + cols = row.getChildrenByTagName("entry") + if len(alloc_widths) == 1: + alloc_widths *= len(cols) + + colwidths = [] + rowtext = [] + for col, width in zip(cols, alloc_widths): + coltext = handleElement(col, width) + + rowtext.append(coltext) + # This is the 'width' of the current cell including the + # whitespace padding. + colwidths.append(max(map(len, coltext.split("\n"))) + + COL_SPACE) + + text.append(rowtext) + + # update the widths of the columns by finding the maximum + # width of all cells in this column. + for i in range(len(colwidths)): + widths[i] = max(colwidths[i], widths.get(i, -1)) + + return widths, text + + +def calculateColumnWidthsDoublePass(rows, width): + maxwidths, text = calculateColumnWidths(rows, [width]) + if reduce(lambda x, y: x + y, maxwidths.values()) <= width: + return maxwidths, text + + # now find out how many columns exceed the maximum permitted width. + # nlarge: number of columns which are too wide. + # remainingWidth: width which these large columns can share. + nlarge = 0 + remainingWidth = width + for colwidth in maxwidths.values(): + if colwidth > width / len(maxwidths): + nlarge += 1 + else: + remainingWidth += -colwidth + + # newmaxwidth: width which each of the large columns is allowed. + newmaxwidth = remainingWidth / max(nlarge, 1) + + newcolwidths = [] + for colwidth in maxwidths.values(): + newcolwidths += [min(colwidth, newmaxwidth)] + + # make another run and this time ask each cell to restrict itself to + # newmaxwidth as calculated above. + newmaxwidth, newtext = calculateColumnWidths(rows, newcolwidths) + + return newmaxwidth, newtext + + +def handleCode(code, width): + retText = GetText(code.childNodes) + return " &codebegin;\n" + VertCatString(" ", 4, retText) + "&codeend;" + + +def handleList(list, width, marker=0): + if list.tagName == 'simplelist': + child = 'member' + decoration = '' + elif list.tagName == 'orderedlist': + child = 'listitem' + else: + child = 'member' + decoration = '- ' + + retText = "" + items = list.getChildrenByTagName(child) + i = 1 + + for item in items: + if list.tagName == 'orderedlist': + decoration = str(i) + '. ' + i = i + 1 + itemText = handleElement(item, width - len(decoration)) + itemText = VertCatString(decoration, None, itemText) + + retText += '\n' + re.sub(r'\s+$', '', itemText) + "\n" + + return retText + + +def handleNote(note, width): + title = None + if note.getChildrenByTagName('title'): + title = note.getChildrenByTagName('title')[0] + name = GetText(title.childNodes) + note.removeChild(title) + + noteid = '' + if note.getAttribute('id'): + noteTagText = '*' + note.getAttribute('id') + '* ' + noteTagText += '*' + ANCHOR_HASH[note.getAttribute('id')] + '*' + noteTagText = IndentParagraphs(noteTagText, width / 2) + noteid = RightJustify(noteTagText, width) + '\n' + + noteText = handleElement(note, width - len("NOTE: ")) + if title is not None: + noteText = name + '\n' + ('-' * len(name)) + '\n' + noteText + + noteText = noteid + VertCatString("NOTE: ", None, noteText) + + return noteText + "\n" + + +def handleParagraph(paragraph, width): + partext = handleElement(paragraph, width) + + partext = re.sub(r'\n+$', '', partext) + partext = re.sub(r'^\n+', '', partext) + + return partext + "\n\n" + + +def handleFormalParagraph(formalparagraph, width): + title = None + if formalparagraph.getChildrenByTagName('title'): + title = formalparagraph.getChildrenByTagName('title')[0] + name = GetText(title.childNodes) + formalparagraph.removeChild(title) + + partext = handleElement(formalparagraph, width) + + partext = re.sub(r'\n+$', '', partext) + partext = re.sub(r'^\n+', '', partext) + if title is not None: + partext = name + '\n' + ('-' * len(name)) + '\n' + partext + + return partext + "\n\n" + + +def handleBlockQuote(block, width): + text = handleElement(block, width - BLOCK_QUOTE) + text = VertCatString(" " * BLOCK_QUOTE, + BLOCK_QUOTE, text) + + return text + "\n" + + +def handleLink(link, width): + linkend = link.getAttribute('linkend') + if linkend not in ANCHOR_HASH: + print >> STDERR, "Warning: Link ID [%s] not found in TOC" % linkend + text = handleElement(link, width) + anchorpt = ANCHOR_HASH.get(linkend) + if not anchorpt: + anchorpt = '' + + return text + ' [|' + anchorpt + '|]' + + +def handleAnchor(anchor, width): + anchorText = '*' + anchor.getAttribute('id') + '* ' + anchorText += '*' + ANCHOR_HASH[anchor.getAttribute('id')] + '*' + return RightJustify(anchorText, width) + "\n" + + +def handleSection(section, width): + title = section.getChildrenByTagName('title')[0] + name = handleElement(title, width) + + sectionid = section.getAttribute('id') + tagsformatted = '' + if sectionid in TOC_HASH: + tagsformatted = '*%s* ' % TOC_HASH[sectionid] + + if sectionid in ANCHOR_HASH: + tagsformatted += '*%s* ' % ANCHOR_HASH[sectionid] + + if sectionid and sectionid in TOC_HASH and \ + sectionid != TOC_HASH[sectionid]: + tagsformatted += '*%s*' % sectionid + + # try to indent to a width of 20 + tagsformatted = RightJustify(IndentParagraphs(tagsformatted, 30), 0) + tagswidth = TextWidth(tagsformatted) + + # width(name) + nspaces + width(tags) = 80 + if len(tagsformatted) > 2: + header = VertCatString(name, 80 - tagswidth, tagsformatted) + else: + header = name + + section.removeChild(title) + text = handleElement(section, width) + + thislevel = LEVEL_HASH.get(sectionid, -1) + if thislevel == 0: + delim = '=' + newlines = '\n\n' + elif thislevel == 1: + delim = '-' + newlines = '\n' + else: + delim = '' + newlines = '\n' + + thisTOC = '' + if thislevel <= 1: + thisTOC = makeTOC(section, width, maxlevel=1) + + return "\n" + (delim * TEXT_WIDTH) + \ + "\n" + header + newlines + thisTOC + newlines + re.sub( + r'\n+$', '', text) + "\n" + + +def handleUlink(ulink, width): + url = ulink.getAttribute('url') + text = handleElement(ulink) + # URL_HASH is created at the very beginning + if url: + return text + ' |%s|' % URL_HASH[url] + else: + print >> STDERR, "Warning: url attribute empty for [%s]" % text + return text + + +def handleIndexTerm(indexterm, width): + return '' + + +def handleEmphasis(emphasis, width): + return '_' + GetText(emphasis.childNodes) + '_' + +############################################################################### +# A dictionary for mapping xml tags to functions. +############################################################################### +handlerMaps = { + 'articleinfo': handleArticleInfo, + 'table': handleTableRoot, + 'informaltable': handleTableRoot, + 'code': handleCode, + 'programlisting': handleCode, + 'list': handleList, + 'simplelist': handleList, + 'orderedlist': handleList, + 'para': handleParagraph, + 'formalpara': handleFormalParagraph, + 'note': handleNote, + 'link': handleLink, + 'anchor': handleAnchor, + 'section': handleSection, + 'blockquote': handleBlockQuote, + 'ulink': handleUlink, + 'emphasis': handleEmphasis, + 'indexterm': handleIndexTerm +} +inlineTags = {'tag': 1, 'literal': 1, 'link': 1, + 'ulink': 1, 'citetitle': 1, 'indexterm': 1, + 'emphasis': 1, 'filename': 1} + +# helper functions for usage() and printerr() + + +def usage(): + print __doc__ + + +def printerr(statement): + if DEBUG: + print >> STDERR, statement + + +def replaceComment(matchobj): + initspace = matchobj.group(1) + firstsent = matchobj.group(2) + code = matchobj.group(3) + + if len(initspace) > 0: + if initspace[0] == '<': + lastspace = initspace + else: + lastspace = '<' + initspace[:-1] + else: + lastspace = initspace + + return '\n' + initspace + firstsent + ' >\n' + code + '\n' + lastspace + + +if __name__ == "__main__": + option = {} + try: + opts, args = getopt.getopt(sys.argv[1:], 'ds', ['prefix=', 'help']) + for oa, ov in opts: + option[oa] = ov + + except getopt.GetoptError: + print >> STDERR, "Usage error: db2vim --help for usage" + sys.exit(1) + + if '--help' in option: + usage() + sys.exit(0) + + TOC_PREFIX = option.get('--prefix', 'ls_') + DEBUG = '-d' in option + + if len(args) != 1: + print >> STDERR, "Usage error: db2vim --help for usage" + sys.exit(1) + + fileName = args[0] + FILENAME = re.sub(r'\.\w+$', r'.txt', fileName) + + try: + fp = open(fileName) + except: + print "Error opening xml file" + + dom = xml.dom.minidom.parse(fp) + + modeline = r''' +================================================================================ +About this file + +This file was created automatically from its XML variant using db2vim. db2vim is +a python script which understands a very limited subset of the Docbook XML 4.2 +DTD and outputs a plain text file in vim help format. + +db2vim can be obtained via anonymous CVS from sourceforge.net. Use + +cvs -d:pserver:anonymous@cvs.vim-latex.sf.net:/cvsroot/vim-latex co db2vim + +Or you can visit the web-interface to sourceforge CVS at: +http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/vim-latex/db2vim/ +================================================================================''' + + STRICT = '-s' in option + + pattern = re.compile( + r'\n([< ]*)([^\n]+)&codebegin;\n(.*?)&codeend;', re.DOTALL) + + processedDoc = handleElement(dom.documentElement) + while re.search('&codebegin;', processedDoc): + processedDoc = re.sub(pattern, replaceComment, processedDoc) + + urlsection = r""" +================================================================================ +URLs used in this file + +""" + labels = zip(URL_HASH.values(), URL_HASH.keys()) + labels.sort() + for label, url in labels: + urlsection += '*%s* : %s\n' % (label, url) + + processedDoc = processedDoc + urlsection + modeline + print processedDoc.encode('iso-8859-1') +# vim:et:sts=4 diff --git a/.vim/doc/db2vim/domutils.py b/.vim/doc/db2vim/domutils.py new file mode 100644 index 0000000..ccd1d88 --- /dev/null +++ b/.vim/doc/db2vim/domutils.py @@ -0,0 +1,27 @@ +def GetTextFromElementNode(element, childNamePattern): + children = element.getElementsByTagName(childNamePattern) + texts = [] + for child in children: + texts.append(GetText(child.childNodes)) + + return texts + + +def GetText(nodelist): + rc = "" + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc + + +def GetTextFromElement(element): + text = "" + child = element.firstChild + while not child.nextSibling is None: + child = child.nextSibling + print child + if child.nodeType == child.TEXT_NODE: + text = text + child.data + + return text diff --git a/.vim/doc/db2vim/textutils.py b/.vim/doc/db2vim/textutils.py new file mode 100644 index 0000000..34160f4 --- /dev/null +++ b/.vim/doc/db2vim/textutils.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python2 +"""Contains functions to do word-wrapping on text paragraphs.""" + +import random +import re +import string + + +def JustifyLine(line, width): + """Stretch a line to width by filling in spaces at word gaps. + + The gaps are picked randomly one-after-another, before it starts + over again. + + Author: Christopher Arndt width and line: + # the line is already long enough -> add it to paragraph + if justify: + # stretch line to fill width + new_par.append(JustifyLine(line, width)) + else: + new_par.append(' '.join(line)) + line = [] + else: + # append next word + line.append(words.pop(0)) + else: + # last line in paragraph + new_par.append(' '.join(line)) + line = [] + break + # replace paragraph with formatted version + paragraphs[i] = '\n'.join(new_par) + # return paragraphs separated by two newlines + return '\n\n'.join(paragraphs) + + +def IndentParagraphs(text, width=80, indent=0, justify=0): + """Indent a paragraph, i.e: + . left (and optionally right) justify text to given width + . add an extra indent if desired. + + This is nothing but a wrapper around FillParagraphs + """ + retText = re.sub(r"^|\n", "\g<0>" + " " * indent, + FillParagraphs(text, width, justify)) + retText = re.sub(r"\n+$", '', retText) + return retText + + +def OffsetText(text, indent): + return re.sub("^|\n", "\g<0>" + " " * indent, text) + + +def RightJustify(lines, width): + if width == 0: + width = TextWidth(lines) + text = "" + for line in lines.split("\n"): + text += " " * (width - len(line)) + line + "\n" + + text = re.sub('\n$', '', text) + return text + + +def CenterText(lines, width): + text = '' + for line in lines.split("\n"): + text += " " * (width / 2 - len(line) / 2) + line + '\n' + return text + + +def TextWidth(text): + """ + TextWidth(text) + + returns the 'width' of the text, i.e the length of the longest segment + in the text not containing new-lines. + """ + return max(map(len, text.split('\n'))) + + +def FormatTable(tableText, ROW_SPACE=2, COL_SPACE=3, COL_WIDTH=1000, + justify=0, widths=None): + """ + returns string + + Given a 2 dimensional array of text as input, produces a plain text + formatted string which resembles the table output. + + The optional arguments specify the inter row/column spacing and the + column width. + """ + + # first find out the max width of the columns + # maxwidths is a dictionary, but can be accessed exactly like an + # array because the keys are integers. + + if widths is None: + widths = {} + for row in tableText: + cellwidths = map(TextWidth, row) + for i in range(len(cellwidths)): + # Using: dictionary.get(key, default) + widths[i] = max(cellwidths[i], widths.get(i, -1)) + + # Truncate each of the maximum lengths to the maximum allowed. + for i in range(0, len(widths)): + widths[i] = min(widths[i], COL_WIDTH) + + if justify: + formattedTable = [] + + for row in tableText: + formattedTable.append(map(FillParagraphs, row, + [COL_WIDTH] * len(row))) + else: + formattedTable = tableText + + retTableText = "" + for row in formattedTable: + rowtext = row[0] + width = widths[0] + for i in range(1, len(row)): + rowtext = VertCatString(rowtext, width, " " * COL_SPACE) + rowtext = VertCatString(rowtext, width + COL_SPACE, row[i]) + + width = width + COL_SPACE + widths[i] + + retTableText += string.join(rowtext, "") + retTableText += "\n" * ROW_SPACE + + return re.sub(r"\n+$", "", retTableText) + + +def VertCatString(string1, width1, string2): + """ + VertCatString(string1, width1=None, string2) + returns string + + Concatenates string1 and string2 vertically. The lines are assumed to + be "\n" separated. + + width1 is the width of the string1 column (It is calculated if left out). + (Width refers to the maximum length of each line of a string) + + NOTE: if width1 is specified < actual width, then bad things happen. + """ + lines1 = string1.split("\n") + lines2 = string2.split("\n") + + if width1 is None: + width1 = -1 + for line in lines1: + width1 = max(width1, len(line)) + + retlines = [] + for i in range(0, max(len(lines1), len(lines2))): + if i >= len(lines1): + lines1.append(" " * width1) + + lines1[i] = lines1[i] + " " * (width1 - len(lines1[i])) + + if i >= len(lines2): + lines2.append("") + + retlines.append(lines1[i] + lines2[i]) + + return string.join(retlines, "\n") +# vim:et:sts=4 diff --git a/.vim/doc/imaps.txt b/.vim/doc/imaps.txt new file mode 100644 index 0000000..5beb983 --- /dev/null +++ b/.vim/doc/imaps.txt @@ -0,0 +1,86 @@ + IMAP -- A fluid replacement for :imap + *imaps.txt* + Srinath Avadhanula + + + + Abstract + ======== +This plugin provides a function IMAP() which emulates vims |:imap| function. The +motivation for providing this plugin is that |:imap| suffers from problems +which get increasingly annoying with a large number of mappings. + +Consider an example. If you do > + imap lhs something + + +then a mapping is set up. However, there will be the following problems: +1. The 'ttimeout' option will generally limit how easily you can type the lhs. + if you type the left hand side too slowly, then the mapping will not be + activated. + +2. If you mistype one of the letters of the lhs, then the mapping is deactivated + as soon as you backspace to correct the mistake. + +3. The characters in lhs are shown on top of each other. This is fairly + distracting. This becomes a real annoyance when a lot of characters initiate + mappings. + +This script provides a function IMAP() which does not suffer from these +problems. + + + + *imaps.txt-toc* +|im_1| Using IMAP + +================================================================================ +Using IMAP *im_1* *imaps-usage* + + + +Each call to IMAP is made using the syntax: > + call IMAP (lhs, rhs, ft [, phs, phe]) + + +This is equivalent to having map to for all files of type . + +Some characters in the have special meaning which help in cursor placement +as described in |imaps-placeholders|. The optional arguments define these +special characters. + +Example One: > + call IMAP ("bit`", "\\begin{itemize}\\\item <++>\\\end{itemize}<++>", "tex") + + +This effectively sets up the map for "bit`" whenever you edit a latex file. When +you type in this sequence of letters, the following text is inserted: > + \begin{itemize} + \item * + \end{itemize}<++> + +where * shows the cursor position. The cursor position after inserting the text +is decided by the position of the first "place-holder". Place holders are +special characters which decide cursor placement and movement. In the example +above, the place holder characters are <+ and +>. After you have typed in the +item, press and you will be taken to the next set of <++>'s. Therefore by +placing the <++> characters appropriately, you can minimize the use of movement +keys. + +Set g:Imap_UsePlaceHolders to 0 to disable placeholders altogether. + +Set g:Imap_PlaceHolderStart and g:Imap_PlaceHolderEnd to something else if you +want different place holder characters. Also, b:Imap_PlaceHolderStart and +b:Imap_PlaceHolderEnd override the values of g:Imap_PlaceHolderStart and +g:Imap_PlaceHolderEnd respectively. This is useful for setting buffer specific +place holders. + +Example Two: You can use the command to insert dynamic elements such as +dates. > + call IMAP ('date`', "\=strftime('%b %d %Y')\", '') + + + +With this mapping, typing date` will insert the present date into the file. + +================================================================================ diff --git a/.vim/doc/latex-suite-chunk.xsl b/.vim/doc/latex-suite-chunk.xsl new file mode 100644 index 0000000..7a557fa --- /dev/null +++ b/.vim/doc/latex-suite-chunk.xsl @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + +appendix toc +article/appendix toc +article toc +sect1 toc +sect2 toc +sect3 toc +sect4 toc +sect5 toc +section toc + + + diff --git a/.vim/doc/latex-suite-common.xsl b/.vim/doc/latex-suite-common.xsl new file mode 100644 index 0000000..2f44272 --- /dev/null +++ b/.vim/doc/latex-suite-common.xsl @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + 3 + 2 + + + +
+ + + + + + + +
+ + + + + +
+
+
+ + + +
diff --git a/.vim/doc/latex-suite-quickstart.css b/.vim/doc/latex-suite-quickstart.css new file mode 100644 index 0000000..52c746e --- /dev/null +++ b/.vim/doc/latex-suite-quickstart.css @@ -0,0 +1,182 @@ +/* + * Authors: Srinath Avadhanula and Mikolaj Machowski + * This style file borrows some elements from main.css, the style file used + * in cream.sf.net + * + * */ +P { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +DT { + font-size : 11pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +LI { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} + +DIV.header { + margin : 0.5cm ; + width : 800px ; + height : 100 +} +.note { +} + +TD { + font-size : 11pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +TD.menu { + text-align : center ; + font-family : verdana, helvetica, sans-serif +} +TD.footright { + text-align : right ; + font-size : 10pt ; + font-family : verdana, helvetica, sans-serif +} +TD.leftpanel { + font-size: 14px ; + font-family: verdana, helvetica, sans-serif ; + vertical-align: top ; + width: 150px; + padding: 15px; + background-color: #88aaaa; +} +TD.mainpanel { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; + padding: 15px; +} +TD.footpanel { + font-size: 12px ; + font-family: verdana, helvetica, sans-serif ; + vertical-align: top ; + text-align: right; + padding: 5px; + background-color: #88aaaa; +} +.navigation { + vertical-align: top; + width: 150px; + padding: 15px; + background-color: #445555; + color: #fffcfc; +} +.navheader { + margin-top: -0.5em; + margin-bottom: 0.5em; + text-align: right; + color: #446644; + font-size: 14px; + font-weight: bold; +} + +SPAN.menu { + text-align : center ; + font-size : 12pt ; + font-family : verdana, helvetica, sans-serif +} + +DIV.merit { + margin : 0.5cm ; + width : 800px +} + +TABLE.meritum { + margin : 0.5cm ; + border : 0 +} +.foot { + margin : 0.5cm ; + width : 800px +} +.head { + margin : 0.5cm ; +} + +CODE { + font-family: "Andale Mono", "Courier New", "Courier", monospace; + background-color: #eef0f3; + white-space: nowrap; +} + +.singlesmall { + font-size: 14px; +} + +.doublesmall { + font-size: 12px; +} + + +DIV.footer { + margin : 0.5cm ; + width : 800px +} +.qa { + margin : 0.5cm ; + font-size : 16px; + font-weight : bold; +} +.ans { + margin : 0.5cm ; + font-weight : normal; +} + +H2.hline { + text-align : center ; + font-family : verdana, helvetica, sans-serif +} + +A.extlinks { + font-size : 11pt ; + font-family : verdana, helvetica, sans-serif ; + font-weight : bold +} + +TT { + font-family: courier,sans-serif; + font-size: 11pt; +} +PRE.programlisting { + font-family: courier,sans-serif; + font-size: 10pt; + background-color:#eef0f3; + border-color: #000000; + border-width: 1px; + border-style: solid; +} +SPAN.conflict { + font-size : small ; + font-family: courier,sans-serif; + color : #DD4444; +} +HR.navig { + color: #446644; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} +A.question { + color: #000000; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} +A.question:hover { + color: #000000; + background-color: #eef0f3; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} + diff --git a/.vim/doc/latex-suite-quickstart.txt b/.vim/doc/latex-suite-quickstart.txt new file mode 100644 index 0000000..5ba10e0 --- /dev/null +++ b/.vim/doc/latex-suite-quickstart.txt @@ -0,0 +1,391 @@ + A (very) quick introduction to Latex-Suite + *latex-suite-quickstart.txt* + Srinath Avadhanula + + + + Abstract + ======== +Latex-Suite is a comprehensive set of scripts to aid in editing, compiling and +viewing LaTeX documents. A thorough explanation of the full capabilities of +Latex-Suite is described in the user manual. This guide on the other hand, +provides a quick 30-45 minute running start to some of the more commonly used +functionalities of Latex-Suite. + + *latex-suite-quickstart.txt-toc* +|lq_1| Using this tutorial +|lq_2| Inserting a template +|lq_3| Inserting a package +|lq_4| Inserting an Environment +|lq_5| A few keyboard shortcuts +|lq_6| Folding in Latex-Suite +|lq_7| Inserting a Reference +|lq_8| Compiling a document + |lq_8_1| Debugging LaTeX source files +|lq_9| Viewing DVI files + |lq_9_1| Performing forward searches + |lq_9_2| Performing inverse searches +|lq_10| Conclusions + +================================================================================ +Using this tutorial *lq_1* *lq_a_bc* + *lsq-using-tutorial* + + + +This tutorial assumes that you have vim version 6.1+ installed on your machine. +To check, open vim and type > + :ver +You will see the version in the first line of the output. Get the latest vim +version from http://vim.sf.net |lq_u_1|. + +Assuming you have Vim 6.1+ already up and running, follow the instructions here +|lq_u_2| to set up Latex-Suite. + +Good, now you are all set to start the tutorial. Since this tutorial aims to +explain the newbie-friendly version of Latex-Suite, it needs some GUI +functionality. Therefore, at least for this tutorial, open the gui version of +vim. (On MS windows, this is the default). Open up this help file in either the +same gvim session in a split window or in a different session and follow the +(friendly) instructions. + +================================================================================ +Inserting a template *lq_2* *lq_a_bd* + *lsq-inserting-template* + + + +Start up gvim and begin editing a new file. > + e newfile.tex +If the installation went well, you should see a new set of menus appear. Goto +Tex-Suite > Templates. You will see a number of templates to choose from. For +now, choose to insert a template for an article. You should get the following in +the main vim window (after possibly a hit-enter prompt). > + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Sun Jun 22 04:00 PM 2003 P + 4 % + 5 \documentclass[a4paper]{article} + 6 \begin{document} + 7 + 8 \end{document} + 9 + 10 ~ + 11 ~ + 12 ~ + 13 ~ + -- INSERT -- 7,1 All + + + +The cursor is left on line 7 (just after the \begin{document} line) from where +you can start typing straight away. Trying to lessen movement is a recurring +theme in Latex-Suite. + +================================================================================ +Inserting a package *lq_3* *lq_a_be* + *lsq-lsq-inserting-package* + + + +Assume that we are writing a mathematical paper and we want to use the popular +amsmath package. We will use some functionality which Latex-Suite provides +specifically for including LaTeX packages, providing options etc. Navigate to +before the \begin{document} line (The portion of the document before the +\begin{document} is called the _preamble_ in LaTeX). On an empty line in the +preamble, type the single word amsmath and then press in normal mode. The +line will change to > + \usepackage[]{amsmath}<++> +with the cursor positioned conveniently between the []'s. For now, do not worry +about the trailing <++> at the end of this line. Assume we want to provide the +sumlimits options to amsmath. You can either type in this option manually, or +choose from a menu of package options which Latex-Suite automatically creates +when you insert a package using . With the cursor still placed between the +[], goto TeX-Suite > Packages > amsmath Options. Choose the sumlimits option. +The package line should get converted to: > + \usepackage[sumlimits,]{amsmath}<++> + + +with the cursor before ]. Press in insert mode. You will see the cursor +jump to the end of the package line and the trailing <++> will disappear. What +just happened?! You had your first taste of _Placeholders_. Read more about them +(later) here |lq_u_3|. In short, pressing in insert mode takes you to the +next <++> in the text. + +================================================================================ +Inserting an Environment *lq_4* *lq_a_bf* + *lsq-insert-environment* + + + +Now let us type in a simple formula in LaTeX. Move back to the body of the +document (The portion of the document between \begin{document} and +\end{document} is called the body). Type in a few simple sentences and then on +an empty line, type the single word equation. Escape to normal mode and press +. (Remember: is very useful!) This time, the line will change to: > + \begin{equation} + <+content+> + \label{<+label+>} + \end{equation}<++> +. + +================================================================================ +A few keyboard shortcuts *lq_5* *lq_a_bg* + *lsq-keyboard-shortcuts* + + + +Now to type in the famous Euler formula. Our aim is to type > + e^{j\pi} + 1 = 0 +Instead of typing this blindly, let us use a few shortcuts to reduce movement. +Start out by typing e^. Now instead of typing {, type another ^. You will see +the e^^ change instantly to e^{}<++> with the cursor on <+content+>. (The ^^ +changed to ^{}<++>.) Continue with the following sequence of letters: j`p. This +will change instantly to j\pi. (The `p changed to \pi.) Having typed in all we +need to type between the {}'s, press . You will pop back out of the +curly-braces. Continue typing the rest of the formula. Latex-Suite provides a +large number of shortcuts which should making typing much more fun and fast if +you get acquainted with them. A list is provided here |lq_u_4|. Definitely spend +some time getting a feel for them. Most of them are pretty intuitive like `/ for +\frac{}{}, `8 for \infty etc. + +Now enter a label. Press to jump to <+label+>. We will use eqn:euler. +After typing in eqn:euler, press . This will take you outside the +curly-braces. Another time you used a Placeholder! + +In order to understand the next section better, it will be helpful to have one +more \label. Lets use the handy key to insert another equation. This time +something simple like the following will do: > + \begin{equation} + \label{eqn:simple} + 1 + 1 = 2 + \end{equation} + + +================================================================================ +Folding in Latex-Suite *lq_6* *lq_a_bh* *lsq-folding* + + + +Okay, we have typed enough. At this stage, hopefully, your file is looking +something like this: > + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Mon Dec 15 07:00 PM 2003 + 4 % + 5 \documentclass[a4paper]{article} + 6 + 7 \usepackage[sumlimits,]{amsmath} + 8 + 9 \begin{document} + 10 \begin{equation} + 11 \label{eqn:euler} + 12 e^{j\pi} + 1 = 0 + 13 \end{equation} + 14 This is the famous euler equation. I + 15 will type another equation, just as + 16 true: + 17 \begin{equation} + 18 \label{eqn:simple} + 19 1 + 1 = 2 + 20 \end{equation} + 21 This is my contribution to mathematics. + 22 \end{document} + +In normal mode, press \rf. This will fold up the entire file and you should see +the file looking as below: > + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Mon Dec 15 07:00 PM 2003 + 4 % + 5 +-- 4 lines: Preamble: \documentclass[a4paper]{article} ----- + 9 \begin{document} + 10 +-- 4 lines: equation (eqn:euler) \label{eqn:euler} ----------- + 14 This is the famous euler equation. I + 15 will type another equation, just as + 16 true: + 10 +-- 4 lines: equation (eqn:simple) \label{eqn:simple} --------- + 21 This is my contribution to mathematics. + 22 \end{document} + +What has happened is that Latex-Suite folded away blocks of LaTeX code into +folded regions. You can open and close folds by using the command za in normal +mode. + +================================================================================ +Inserting a Reference *lq_7* *lq_a_bi* + *lsq-inserting-reference* + + + +A necessary part of LaTeX editing is referencing equations, figures, +bibliographic entries etc. This is done with the \ref and the \cite commands. +Latex-Suite provides an easy way to do this. Somewhere in the body of the +document, type in the following sentence > + This is a reference to (\ref{}). +With the cursor between the {} press in insert mode. Your vim session will +sprout a new windows showing all the \labels found in all the .tex files of your +current project. To insert the reference, just position the cursor on the +relevant line and press . The line which you were editing will change to: > + This is a reference to (\ref{eqn:euler}) +and the bottom window closes automatically. + +The key also works for inserting \cite commands to reference bibliographic +entries, inserting file names for the \inputgraphics command and just plain +searching for words. Click here |lq_u_5| for more information. + +================================================================================ +Compiling a document *lq_8* *lq_a_bj* + *lsq-compiling* + +|lq_8_1| Debugging LaTeX source files + + +Great! We have just created a small latex file. The next step is to make the +latex compiler create a .dvi file from it. Compiling via latex-suite is simple. +Goto normal mode and press \ll (replace \ with whatever mapleader setting you +have). This will call the latex compiler. If all goes well, then the focus +should return to the vim window. + +Nothing happend? Ouch! You might need to do some additional settings as +described here. |lq_u_6| + + +-------------------------------------------------------------------------------- +Debugging LaTeX source files *lq_8_1* *lq_a_bk* + *lsq-debugging* + +To illustrate the debugging procedure, let's create a few mistakes in the file. +Insert the following ``mistakes'' in the file: > + This is a $\mistake$. + And this is $\another$ +Now press \ll again. This time you will notice that after compilation finishes, +the cursor automatically lands on $\mistake$. In addition, 2 new windows will +appear as shown here: + +The middle window is an _Error List_ window showing you the errors which the +latex compiler found. The bottom window is a _Log Preview_ window, which shows +you the context of the error made by displaying the relevant portion of the .log +file created during the latex compilation procedure. Jump to the _Error List_ +window and try scrolling around in it using either the j, k keys or the arrow +keys. You will notice that the _Log Preview_ window scrolls automatically to +retain the context of the error you are currently located on. If you press + on any line, you will see the cursor jump to the location of the error. +Latex-Suite tries to guess the column location as best as it can so you can +continue typing straight away. +Having got a taste for compiling, proceed by deleting the erroneous lines and +re-compiling. + +The Latex-Suite compiler is capable of much more including selectively filtering +out common errors which you might want to ignore for the moment, compiling parts +of a document, setting levels of verbosity in the compiler output etc. See here +|lq_u_7| for more. + +================================================================================ +Viewing DVI files *lq_9* *lq_a_bl* + *lsq-viewing-dvi* + +|lq_9_1| Performing forward searches +|lq_9_2| Performing inverse searches + + +Now that you have compiled your first latex source, its time to view it. Again, +this should be pretty simple. Press \lv in normal mode. Depending on your +platform, a DVI viewer program should open up and display the dvi file generated +in compilation step previously. + +Nothing happend? Ouch! You might need to do some additional settings as +described here. |lq_u_8| + + +-------------------------------------------------------------------------------- +Performing forward searches *lq_9_1* *lq_a_bm* + *lsq-quick-forward-searching* + +If you are using a modern DVI viewer, then it is possible to do what is called +forward and inverse searching. However, you will need to customize the standard +Latex-Suite distribution in order to utilize this functionality. Type in the +following on the command line: > + :let g:Tex_CompileRule_dvi = 'latex -src-specials -interaction=nonstopmode $*' + :TCTarget dvi + + +Now recompile the latex file by pressing \ll. This time, instead of pressing \lv +to view the file, press \ls from within the tex file. If the DVI viewer supports +forward searching (most of them do), then the viewer will actually display the +portion of the DVI file corresponding to the location where you were editing the +tex file. + +NOTE: The reason Latex-Suite does not have this setting by default is that on + some systems this causes unpredictable results in the DVI output. If you + find the DVI output satisfactory, then you can insert the first of the 2 + lines above into your $VIM/ftplugin/tex.vim file. $VIM is ~/vimfiles for + windows and ~/.vim for *nix machines. + + + +-------------------------------------------------------------------------------- +Performing inverse searches *lq_9_2* *lq_a_bn* + *lsq-quick-inverse-searching* + +Most DVI viewers also support inverse searching, whereby you can make the DVI +viewer ask vim to display the tex source corresponding to the DVI file being +shown. This is extremely helpful while proofreading large documents. + +Simply double-click anywhere in the viewer window. If the viewer supports it, +then it will attempt to open an editor window at the location corresponding to +where you double-clicked. On *nix platforms, Latex-Suite attempts to start the +viewer program in such a way that it already knows to use vim to open the tex +source. Thus you should see a vim window open up showing the tex file. However, +if there is an error, or some other program is used, you will need to tell the +viewer program to use gvim as the editor. On windows platforms, if you use the +commonly available yap viewer (available as part of the miktex distribution), +then this option can be set from View > Options > Inverse Search. In the Command +line: window, write > + "C:\Program Files\vim\vim61\gvim" -c ":RemoteOpen +%l %f" +(Customize the path according to where you have installed gvim). If you double +click in the view pane now, you will see gvim start up and take you to the +relevant portion of the tex file. + +================================================================================ +Conclusions *lq_10* *lq_a_bo* + *lsq-conclusions* + + + +Thats all folks! By now, you should know enough of the basic functions of +latex-suite. Ofcourse, latex-suite is capable of much, much more such as +compiling files multiple times to resolve changed labels, compiling +dependencies, handling user packages and more. To get a feel for that, you will +need to take a look at the Latex-Suite user manual. |lq_u_9| + +================================================================================ +URLs used in this file + +*lq_u_1* : http://vim.sf.net +*lq_u_2* : http://vim-latex.sourceforge.net/index.php?subject=download&title=Download +*lq_u_3* : http://vim-latex.sourceforge.net/documentation/latex-suite/latex-macros.html +*lq_u_4* : http://vim-latex.sourceforge.net/documentation/latex-suite/auc-tex-mappings.html +*lq_u_5* : http://vim-latex.sourceforge.net/documentation/latex-suite/latex-completion.html +*lq_u_6* : http://vim-latex.sourceforge.net/index.php?subject=faq&title=FAQ#faq-2 +*lq_u_7* : http://vim-latex.sourceforge.net/documentation/latex-suite/latex-compiling.html +*lq_u_8* : http://vim-latex.sourceforge.net/index.php?subject=faq&title=FAQ#faq-3 +*lq_u_9* : http://vim-latex.sourceforge.net/index.php?subject=manual&title=Manual#user-manual + +================================================================================ +About this file + +This file was created automatically from its XML variant using db2vim. db2vim is +a python script which understands a very limited subset of the Docbook XML 4.2 +DTD and outputs a plain text file in vim help format. + +db2vim can be obtained via anonymous CVS from sourceforge.net. Use + +cvs -d:pserver:anonymous@cvs.vim-latex.sf.net:/cvsroot/vim-latex co db2vim + +Or you can visit the web-interface to sourceforge CVS at: +http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/vim-latex/db2vim/ +================================================================================ diff --git a/.vim/doc/latex-suite-quickstart.xml b/.vim/doc/latex-suite-quickstart.xml new file mode 100644 index 0000000..f7c5b81 --- /dev/null +++ b/.vim/doc/latex-suite-quickstart.xml @@ -0,0 +1,433 @@ + + + + + + + + +]> +
+ + + A (very) quick introduction to Latex-Suite + + + Srinath + Avadhanula + +
srinath AT fastmail DOT fm
+
+
+ + + &ls; is a comprehensive set of scripts to aid in editing, compiling and + viewing &latex; documents. A thorough explanation of the full + capabilities of &ls; is described in the user manual. This guide on the + other hand, provides a quick 30-45 minute running start to some of the + more commonly used functionalities of &ls;. + + + &date; + +
+
+ Using this tutorial + + This tutorial assumes that you have vim version 6.1+ installed on your + machine. To check, open vim and type + :ver + You will see the version in the first line of the output. Get the latest + vim version from http://vim.sf.net. + + + Assuming you have Vim 6.1+ already up and running, follow the + instructions here + to set up Latex-Suite. + + + Good, now you are all set to start the tutorial. Since this tutorial + aims to explain the newbie-friendly version of &ls;, it needs some GUI + functionality. Therefore, at least for this tutorial, open the gui + version of vim. (On MS windows, this is the default). Open up this help + file in either the same gvim session in a split window or in a different + session and follow the (friendly) instructions. + +
+
+ Inserting a template + + Start up gvim and begin editing a new file. + e newfile.tex + If the installation went well, you should see a new set of + menus appear. Goto Tex-Suite > Templates. You will see + a number of templates to choose from. For now, choose to insert a + template for an article. You should get the following in the main + vim window (after possibly a hit-enter prompt). + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Sun Jun 22 04:00 PM 2003 P + 4 % + 5 \documentclass[a4paper]{article} + 6 \begin{document} + 7 + 8 \end{document} + 9 + 10 ~ + 11 ~ + 12 ~ + 13 ~ +-- INSERT -- 7,1 All + + + + + + + The cursor is left on line 7 (just after the + \begin{document} line) from where you can start + typing straight away. Trying to lessen movement is a recurring theme in + Latex-Suite. + +
+
+ Inserting a package + + Assume that we are writing a mathematical paper and we want to use the + popular amsmath package. We will use some functionality which + Latex-Suite provides specifically for including LaTeX packages, + providing options etc. Navigate to before the + \begin{document} line (The portion of the document + before the \begin{document} is called the + preamble in LaTeX). On an empty line in the + preamble, type the single word amsmath and then press + <F5> in normal mode. The line will change to + \usepackage[]{amsmath}&ph; + with the cursor positioned conveniently between the + []'s. For now, do not worry about the trailing + &ph; at the end of this line. Assume we want to + provide the sumlimits options to amsmath. You can + either type in this option manually, or choose from a menu of package + options which Latex-Suite automatically creates when you insert a + package using <F5>. With the cursor still + placed between the [], goto TeX-Suite > + Packages > amsmath Options. Choose the + sumlimits option. The package line should get + converted to: + \usepackage[sumlimits,]{amsmath}&ph; + + + with the cursor before ]. Press + <C-j> in insert mode. You will see the cursor + jump to the end of the package line and the trailing + &ph; will disappear. What just happened?! You had + your first taste of Placeholders. Read more about + them (later) here. + In short, pressing <C-j> in insert mode takes + you to the next &ph; in the text. + +
+
+ Inserting an Environment + + Now let us type in a simple formula in LaTeX. Move back to the body of + the document (The portion of the document between + \begin{document} and + \end{document} is called the body). Type in a few + simple sentences and then on an empty line, type the single word + equation. Escape to normal mode and press + <F5>. (Remember: + <F5> is very useful!) This time, the line will + change to: + \begin{equation} + <+content+> + \label{<+label+>} +\end{equation}&ph; + with the cursor on the <+content+>. + +
+
+ A few keyboard shortcuts + + Now to type in the famous Euler formula. Our aim is to type + e^{j\pi} + 1 = 0 Instead + of typing this blindly, let us use a few shortcuts to reduce + movement. Start out by typing e^. Now instead of + typing {, type another ^. You + will see the e^^ change instantly to + e^{}&ph; with the cursor on + <+content+>. (The ^^ changed to + ^{}&ph;.) Continue with the following sequence of + letters: j`p. This will change instantly to + j\pi. (The `p changed to + \pi.) Having typed in all we need to type between + the {}'s, press <C-j>. + You will pop back out of the curly-braces. Continue typing the rest + of the formula. + Latex-Suite provides a large number + of shortcuts which should making typing much more fun and fast + if you get acquainted with them. A list is provided here. Definitely spend some time getting a feel for + them. Most of them are pretty intuitive like `/ + for \frac{}{}, `8 for + \infty etc. + + + Now enter a label. + Press <C-j> to jump to + <+label+>. + We + will use eqn:euler. After typing in + eqn:euler, press <C-j>. This + will take you outside the curly-braces. Another time you used a + Placeholder! + + + In order to understand the next section better, it will be helpful + to have one more \label. Lets use the handy + <F5> + key to insert another equation. This time something simple like the + following will do: + \begin{equation} + \label{eqn:simple} + 1 + 1 = 2 +\end{equation} + +
+
+ Folding in &ls; + + Okay, we have typed enough. At this stage, hopefully, your file is + looking something like this: + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Mon Dec 15 07:00 PM 2003 + 4 % + 5 \documentclass[a4paper]{article} + 6 + 7 \usepackage[sumlimits,]{amsmath} + 8 + 9 \begin{document} + 10 \begin{equation} + 11 \label{eqn:euler} + 12 e^{j\pi} + 1 = 0 + 13 \end{equation} + 14 This is the famous euler equation. I + 15 will type another equation, just as + 16 true: + 17 \begin{equation} + 18 \label{eqn:simple} + 19 1 + 1 = 2 + 20 \end{equation} + 21 This is my contribution to mathematics. + 22 \end{document} + + In normal mode, press \rf. This will fold up the + entire file and you should see the file looking as below: + + 1 % File: sample.tex + 2 % Created: Sun Jun 22 04:00 PM 2003 P + 3 % Last Change: Mon Dec 15 07:00 PM 2003 + 4 % + 5 +-- 4 lines: Preamble: \documentclass[a4paper]{article} ----- + 9 \begin{document} + 10 +-- 4 lines: equation (eqn:euler) \label{eqn:euler} ----------- + 14 This is the famous euler equation. I + 15 will type another equation, just as + 16 true: + 10 +-- 4 lines: equation (eqn:simple) \label{eqn:simple} --------- + 21 This is my contribution to mathematics. + 22 \end{document} + + What has happened is that &ls; folded away blocks of &latex; code into + folded regions. You can open and close folds by using the command + za in normal mode. + +
+
+ Inserting a Reference + + A necessary part of LaTeX editing is referencing equations, figures, + bibliographic entries etc. This is done with the + \ref and the \cite commands. + Latex-Suite provides an easy way to do this. Somewhere in the body of + the document, type in the following sentence + This is a reference to (\ref{}). + With the cursor between the {} press + <F9> in insert mode. Your vim session will + sprout a new windows showing all the + \labels found in all the .tex files + of your current project. + To insert the reference, just position the cursor on + the relevant line and press + <enter>. The line which you were editing will change + to: + This is a reference to (\ref{eqn:euler}) + and the bottom window closes automatically. + + + The <F9> key also works for inserting + \cite commands to reference bibliographic entries, + inserting file names for the \inputgraphics command + and just plain searching for words. Click here + for more information. + +
+
+ Compiling a document + + Great! We have just created a small latex file. The next step is to + make the latex compiler create a .dvi file from it. Compiling via + latex-suite is simple. Goto normal mode and press \ll + (replace \ with whatever mapleader setting you + have). This will call the latex compiler. If all goes well, then + the focus should return to the vim window. + + + Nothing happend? Ouch! You might need to do some additional settings as + described here. + +
+ Debugging LaTeX source files + + To illustrate the debugging procedure, let's create a few mistakes + in the file. Insert the following ``mistakes'' in the file: + This is a $\mistake$. +And this is $\another$ + Now press \ll again. This time you will notice that + after compilation finishes, the cursor automatically lands on + $\mistake$. In addition, 2 new windows will appear + as shown here: + + + + + + The middle window is an Error List window + showing you the errors which the latex compiler found. The bottom + window is a Log Preview window, which shows you + the context of the error made by displaying the relevant portion of + the .log file created during the latex + compilation procedure. Jump to the Error List + window and try scrolling around in it using either the j, + k keys or the arrow keys. You will notice that the + Log Preview window scrolls automatically to + retain the context of the error you are currently located on. If you + press <enter> on any line, you will see the + cursor jump to the location of the error. Latex-Suite tries to guess + the column location as best as it can so you can continue typing + straight away. + +
+ + Having got a taste for compiling, proceed by deleting the erroneous + lines and re-compiling. + + + The Latex-Suite compiler is capable of much more including + selectively filtering out common errors which you might want to + ignore for the moment, compiling parts of a document, setting + levels of verbosity in the compiler output etc. See here + for more. + +
+
+ Viewing DVI files + + Now that you have compiled your first latex source, its time to + view it. Again, this should be pretty simple. Press + \lv in normal mode. Depending on your platform, a DVI + viewer program should open up and display the dvi file generated in + compilation step previously. + + + Nothing happend? Ouch! You might need to do some additional settings as + described here. + +
+ Performing forward searches + + If you are using a modern DVI viewer, then it is possible to do what + is called forward and inverse searching. However, you will need to + customize the standard Latex-Suite distribution in order to utilize + this functionality. Type in the following on the command line: + + :let g:Tex_CompileRule_dvi = 'latex -src-specials -interaction=nonstopmode $*' +:TCTarget dvi + + Now recompile the latex file by pressing \ll. + This time, instead of pressing \lv to view the + file, press \ls from within the tex file. If the + DVI viewer supports forward searching (most of them do), then the + viewer will actually display the portion of the DVI file + corresponding to the location where you were editing the tex file. + + + + The reason Latex-Suite does not have this setting by default is + that on some systems this causes unpredictable results in the DVI + output. If you find the DVI output satisfactory, then you can + insert the first of the 2 lines above into your + $VIM/ftplugin/tex.vim file. + $VIM is ~/vimfiles for + windows and ~/.vim for *nix machines. + + +
+
+ Performing inverse searches + + Most DVI viewers also support inverse searching, whereby you can + make the DVI viewer ask vim to display the tex source corresponding + to the DVI file being shown. This is extremely helpful while + proofreading large documents. + + + + Simply double-click anywhere in the viewer window. If the viewer + supports it, then it will attempt to open an editor window at the + location corresponding to where you double-clicked. On *nix + platforms, Latex-Suite attempts to start the viewer program in such + a way that it already knows to use vim to open the tex source. Thus + you should see a vim window open up showing the tex file. However, + if there is an error, or some other program is used, you will need + to tell the viewer program to use gvim as the editor. On windows + platforms, if you use the commonly available yap + viewer (available as part of the miktex distribution), then this + option can be set from View > Options > Inverse + Search. In the Command line: window, + write + "C:\Program Files\vim\vim61\gvim" -c ":RemoteOpen +%l %f" + (Customize the path according to where you have installed gvim). + If you double click in the view pane now, you will see gvim start + up and take you to the relevant portion of the tex file. + +
+
+
+ Conclusions + + Thats all folks! By now, you should know enough of the basic functions + of latex-suite. Ofcourse, latex-suite is capable of much, much more such + as compiling files multiple times to resolve changed labels, compiling + dependencies, handling user packages and more. To get a feel for that, + you will need to take a look at the &ls; + user manual. + +
+
+ + diff --git a/.vim/doc/latex-suite.css b/.vim/doc/latex-suite.css new file mode 100644 index 0000000..52c746e --- /dev/null +++ b/.vim/doc/latex-suite.css @@ -0,0 +1,182 @@ +/* + * Authors: Srinath Avadhanula and Mikolaj Machowski + * This style file borrows some elements from main.css, the style file used + * in cream.sf.net + * + * */ +P { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +DT { + font-size : 11pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +LI { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} + +DIV.header { + margin : 0.5cm ; + width : 800px ; + height : 100 +} +.note { +} + +TD { + font-size : 11pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; +} +TD.menu { + text-align : center ; + font-family : verdana, helvetica, sans-serif +} +TD.footright { + text-align : right ; + font-size : 10pt ; + font-family : verdana, helvetica, sans-serif +} +TD.leftpanel { + font-size: 14px ; + font-family: verdana, helvetica, sans-serif ; + vertical-align: top ; + width: 150px; + padding: 15px; + background-color: #88aaaa; +} +TD.mainpanel { + font-size : 12pt ; + font-family : helvetica, arial, verdana, sans-serif ; + vertical-align : top; + padding: 15px; +} +TD.footpanel { + font-size: 12px ; + font-family: verdana, helvetica, sans-serif ; + vertical-align: top ; + text-align: right; + padding: 5px; + background-color: #88aaaa; +} +.navigation { + vertical-align: top; + width: 150px; + padding: 15px; + background-color: #445555; + color: #fffcfc; +} +.navheader { + margin-top: -0.5em; + margin-bottom: 0.5em; + text-align: right; + color: #446644; + font-size: 14px; + font-weight: bold; +} + +SPAN.menu { + text-align : center ; + font-size : 12pt ; + font-family : verdana, helvetica, sans-serif +} + +DIV.merit { + margin : 0.5cm ; + width : 800px +} + +TABLE.meritum { + margin : 0.5cm ; + border : 0 +} +.foot { + margin : 0.5cm ; + width : 800px +} +.head { + margin : 0.5cm ; +} + +CODE { + font-family: "Andale Mono", "Courier New", "Courier", monospace; + background-color: #eef0f3; + white-space: nowrap; +} + +.singlesmall { + font-size: 14px; +} + +.doublesmall { + font-size: 12px; +} + + +DIV.footer { + margin : 0.5cm ; + width : 800px +} +.qa { + margin : 0.5cm ; + font-size : 16px; + font-weight : bold; +} +.ans { + margin : 0.5cm ; + font-weight : normal; +} + +H2.hline { + text-align : center ; + font-family : verdana, helvetica, sans-serif +} + +A.extlinks { + font-size : 11pt ; + font-family : verdana, helvetica, sans-serif ; + font-weight : bold +} + +TT { + font-family: courier,sans-serif; + font-size: 11pt; +} +PRE.programlisting { + font-family: courier,sans-serif; + font-size: 10pt; + background-color:#eef0f3; + border-color: #000000; + border-width: 1px; + border-style: solid; +} +SPAN.conflict { + font-size : small ; + font-family: courier,sans-serif; + color : #DD4444; +} +HR.navig { + color: #446644; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} +A.question { + color: #000000; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} +A.question:hover { + color: #000000; + background-color: #eef0f3; + height: 1px; + margin-top: 1em; + border-top: 0px; /* Mozilla work-around to eliminate "groove" */ +} + diff --git a/.vim/doc/latex-suite.txt b/.vim/doc/latex-suite.txt new file mode 100644 index 0000000..3d571ba --- /dev/null +++ b/.vim/doc/latex-suite.txt @@ -0,0 +1,3529 @@ + Latex-Suite Reference + *latex-suite.txt* + Srinath Avadhanula + Mikolaj Machowski + + + + Abstract + ======== +Latex-Suite attempts to provide a comprehensive set of tools to view, edit and +compile LaTeX documents in Vim. Together, they provide tools starting from +macros to speed up editing LaTeX documents to functions for forward searching +.dvi documents. Latex-Suite has been possible because of the contributions of +many people. Please see latex-suite-credits [|ls_a_eg|] for a list of people who +have helped. + +Latex-Suite is released under the Vim charityware license. For license and +conditions of use look at |copyright|. Replace all occurrences of ``Vim'' with +``Latex-Suite''. The current copyright holders of Latex-Suite are Srinath +Avadhanula and Mikolaj Machowski. + +Homepage: http://vim-latex.sourceforge.net |ls_u_1| + + + + *latex-suite.txt-toc* +|ls_1| Installation and recommended Settings +|ls_2| Inserting Templates +|ls_3| Latex-Suite Macros + |ls_3_1| Environment Mappings + |ls_3_2| Command Mappings + |ls_3_3| Font Mappings + |ls_3_4| Section Mappings + |ls_3_5| Greek Letter Mappings + |ls_3_6| Auc-Tex Key Bindings + |ls_3_7| Diacritics + |ls_3_8| BibTeX Shortcuts + |ls_3_9| Smart Key Mappings + |ls_3_10| Alt Key Macros + |ls_3_11| Custom Macros + |ls_3_12| Making your own Macros via IMAP() +|ls_4| Package Handling + |ls_4_1| Inserting package commands + |ls_4_2| Actions taken for supported packages + |ls_4_3| Automatic Package detection + |ls_4_4| Writing supporting for a package +|ls_5| Latex Completion + |ls_5_1| Latex-Suite \ref completion + |ls_5_2| Latex-Suite \cite completion + |ls_5_3| Latex-Suite filename completion + |ls_5_4| Custom command completion +|ls_6| LaTeX Compiling + |ls_6_1| Setting Compilation rules + |ls_6_2| Handling dependencies in compilation + |ls_6_3| Compiling multiple times + |ls_6_4| Customizing the compiler output + |ls_6_5| Compiling parts of a file + |ls_6_6| Load log file after external compilation +|ls_7| Latex Viewing and Searching + |ls_7_1| Setting Viewing rules + |ls_7_2| Forward Searching documents + |ls_7_3| Inverse Searching +|ls_8| Latex Folding + |ls_8_1| Default Folding Scheme in Latex-Suite + |ls_8_2| Customizing what to fold +|ls_9| Multiple file LaTeX projects + |ls_9_1| Latex-Suite project settings + |ls_9_2| Specifying which file to compile +|ls_10| Latex-Suite Commands and Maps + |ls_10_1| Latex-Suite Maps + |ls_10_2| Latex Suite Commands +|ls_11| Customizing Latex-Suite + |ls_11_1| General Settings + |ls_11_2| Place-Holder Customization + |ls_11_3| Macro Customization + |ls_11_4| Smart Key Customization + |ls_11_5| Latex Completion Customization + |ls_11_6| Compiler Customization + |ls_11_7| Viewer Customization + |ls_11_8| Menu Customization + |ls_11_9| Folding Customization + |ls_11_10| Package Handling Customization + |ls_11_11| Template Directory Customization +|ls_12| Credits + +================================================================================ +Installation and recommended Settings *ls_1* *ls_a_bc* + *recommended-settings* + + + +If you are reading this, it most probably means that you have already installed +Latex-Suite and the help files. If this is not the case, follow the detailed +instructions on Latex-Suite's download page |ls_u_2|. + +Make sure that you create a few necessary settings in your ~/.vimrc. > + + " REQUIRED. This makes vim invoke Latex-Suite when you open a tex file. + filetype plugin on + + " IMPORTANT: win32 users will need to have 'shellslash' set so that latex + " can be called correctly. + set shellslash + + " OPTIONAL: This enables automatic indentation as you type. + filetype indent on + + " OPTIONAL: Starting with Vim 7, the filetype of empty .tex files defaults to + " 'plaintex' instead of 'tex', which results in vim-latex not being loaded. + " The following changes the default filetype back to 'tex': + let g:tex_flavor='latex' + + + +In addition, the following settings could go in your ~/.vim/ftplugin/tex.vim +file: > + " this is mostly a matter of taste. but LaTeX looks good with just a bit + " of indentation. + set sw=2 + " TIP: if you write your \label's as \label{fig:something}, then if you + " type in \ref{fig: and press you will automatically cycle through + " all the figure labels. Very useful! + set iskeyword+=: + + + +In the unlikely case that Latex-Suite is installed, but you do not want to use +it (e.g., if it is installed system-wide and you use some other package to deal +with tex files), you can suppress the loading of Latex-Suite by setting > + let b:suppress_latex_suite = 1 +in your ~/.vim/ftplugin/tex.vim. + +================================================================================ +Inserting Templates *ls_2* *ls_a_bd* + *latex-suite-templates* + + + +This functionality is available via the TeX-Suite > Templates menu. This module +provides a way to insert custom templates at the beginning of the current file. + +When Latex-Suite first starts up, it scans the template directory [|ls_a_ef|] +and creates menu items based on the files found there. When you select a +template from this menu, the file will be read in above the first line of the +current file. + +A template file can utilize placeholders for initializing the cursor position +when the template is read in and subsequent movement. In addition, template +files can contain dynamic elements such as the time of creation of a file etc, +by using vim expressions. + +You can place your own templates in the template directory [|ls_a_ef|] in order +for them to be available via the menu. + +NOTE: Templates are also accessible for non-gui users with the command + |:TTemplate|. The argument should be name of the corresponding template + file. If the command is called without arguments (preferred usage), then a + list of available templates is displayed and the user is asked to choose + one of them. + + + +================================================================================ +Latex-Suite Macros *ls_3* *ls_a_be* + *latex-macros* + +|ls_3_1| Environment Mappings +|ls_3_2| Command Mappings +|ls_3_3| Font Mappings +|ls_3_4| Section Mappings +|ls_3_5| Greek Letter Mappings +|ls_3_6| Auc-Tex Key Bindings +|ls_3_7| Diacritics +|ls_3_8| BibTeX Shortcuts +|ls_3_9| Smart Key Mappings +|ls_3_10| Alt Key Macros +|ls_3_11| Custom Macros +|ls_3_12| Making your own Macros via IMAP() + + +Latex-Suite ships with a very comprehensive set of insert mode and |visual-mode| +mappings and menu items to typeset most of the LaTeX elements. + +NOTE: These mappings are are not standard mappings in the sense that only the + last character is mapped. See plugin/imaps.vim for further documentation. + For example, in the case of the mapping EFI provided by Latex-Suite you + can press the characters 'E', 'F' and 'I' as slowly as you wish (unlike + the normal imap command where timeout issues are involved). The characters + are visible as you type them (unlike normal imaps) and you can use the + movement or backspace key to correct yourself unlike normal mappings. + + + *place-holder* *ls_a_eh* + *place-holders* *ls_a_eO* +NOTE: Place Holders + ------------- + Almost all macros provided in Latex-Suite implement Stephen Riem's + bracketing system and Gergely Kontra's JumpFunc() for handling + place-holders. This consists of using "place-holders" to mark off + locations where the next relevant editing has to be done. As an example, + when you type EFI in |insert-mode|, you will get the following: > + \begin{figure}[<+htpb+>] + \centering + \includegraphics{<+file+>} + \caption{<+caption text+>} + \label{fig:<+label+>} + \end{figure}<++> +< The text <+htpb+> will be selected and you will be left in |select-mode| + so that you can continue typing straight away. After having typed in the + placement specifier, you can press (while still in insert-mode). + This will take you directly to the next "place-holder". i.e, <+file+> will + be visually selected with Vim in select mode again for typing in the file + name. This saves on a lot of key presses. + + + *overriding-macros* *ls_a_eP* +NOTE: Over-riding Latex-Suite Macros + ------------------------------ + If you wish to change these macros from their default values, for example, + if you wish to change `w to expand to \wedge instead of its default + expansion to \omega, you should use the IMAP function as described in the + Using IMAP() [|ls_a_bG|] section. + + An important thing to note is that if you wish to over-ride macros created + by Latex-Suite rather than merely create new macros, you should place the + IMAP() calls in a script which gets sourced after the files in + Latex-Suite. A good place typically is as a file-type plugin file in the + ~/.vim/after/ftplugin/ directory. (Use ~/vimfiles if you are using + WINDOWS). For example to over-ride `w to \wedge instead of \omega, place + the following line in (say) ~/.vim/after/ftplugin/tex_macros.vim: > + call IMAP('`w', '\wedge', 'tex') +< To delete a mapping, you can use > + call IUNMAP('FEM', 'tex') +< in ~/.vim/after/ftplugin/tex_macros.vim. + + NOTE: It is important to use a file-name which will get sourced on a + FileType event. Therefore you must use a file-name which conforms to + the standards as described in |ftplugin-name|. + + + + *pausing-imaps* *ls_a_eQ* +NOTE: Pausing Macro expansion + ----------------------- + If you wish to temporarily suspend the imaps functionality, then you can + set the Imap_FreezeImap to 1. If you set g:Imap_FreezeImap to 1, then it + will be a system-wide setting. Setting b:Imap_FreezeImap will affect only + the current buffer. + + +The following sections describe the various editing macros provided by +Latex-Suite. + + +-------------------------------------------------------------------------------- +Environment Mappings *ls_3_1* *ls_a_bf* + *environment-mappings* + +Latex-Suite provides a rich set of mappings to insert, enclose and modify LaTeX +environments, i.e, \begin{...} ... \end{...} pairs. There are several +possibilities for the customization of the inserted environments, see the +section about customizations [|ls_a_cY|]. + +Inserting Environments *ls_3_1_1* *ls_a_bg* + *inserting-environments* + +Latex-Suite provides the following ways to insert environments + + + +Method 1: Pressing *ls_3_1_1_1* *ls_a_bh* + *inserting-env-f5* + +If you press in the insert or normal mode while on an empty line, +Latex-Suite prompts you with a list of environments you might want to insert. +You can either choose one from the list or type in a new environment name. If +you press on a line which already has a word, then that word is used +instead of prompting. + +See Tex_Env_name [|ls_a_cZ|] for a description of how Latex-Suite uses the word +to form the expansion and how to modify Latex-Suite's behavior. + +The list of environments which Latex-Suite prompts you with (when is +pressed on an empty line) is formed from the Tex_PromptedEnvironments +[|ls_a_dg|] setting. + +In addition to this setting, Latex-Suite also lists environments found in custom +packages as described in the section Package actions. [|ls_a_bL|] + + +Method 2: Using - *ls_3_1_1_2* *ls_a_bi* + *inserting-env-shift-f1* + +The shifted function keys, to can be mapped to insert very +commonly used environments. The environments mapped to each key can be +customized via the g:Tex_HotKeyMappings [|ls_a_dh|] setting. + + +Method 3: Using three letter sequences *ls_3_1_1_3* *ls_a_bj* + *inserting-env-threeletter* + +Environments can also be inserted by pressing a 3 capital letter sequence +starting with an E. The sequence of 3 letters generally tries to follow the +following rules: + + +1. All environment mappings begin with E + +2. If the environment can be broken up into 2 distinct words, such as flushright + (flush + right), then the next 2 letters are the first letters of the 2 + words. Example: > + flushleft (_f_lush + _l_eft) ---> EFL + flushright (_f_lush + _r_ight) ---> EFR + minipage (_m_ini + _p_age) ---> EMP +< If on the other hand, the environment name cannot be broken up into 2 + distinct words, then the next 2 letters are the first 2 letters of the name + of the environment. Example: > + equation (_eq_uation) ---> EEQ +< +Unfortunately there are some environments that cannot be split in two words and +first two letters in name are identical. In this case shortcut is created from +E, first and last letter. Example: > + quote (_q_uot_e_) ---> EQE + quotation (_q_uotatio_n_) ---> EQN +Of course, not every last one of the environments can follow this rule because +of ambiguities. In case of doubt, pull down the Tex-Environments menu. The menu +item should give the hint for the map. + + +Enclosing in Environments *ls_3_1_2* *ls_a_bk* + *enclosing-environments* + +Latex-Suite provides visual-mode mappings which enclose visually selected +portions of text in environments. There are two ways provided to do this. + + + +Method 1: Pressing *ls_3_1_2_1* *ls_a_bl* + *enclosing-env-f5* + +You can also select a portion of text visually and press while still in +visual mode. This will prompt you with a list of environments. (This list can be +customized via the g:Tex_PromptedEnvironments [|ls_a_dg|] setting). You can +either choose from this list or type in a new environment name. Once the +selection is done, Latex-Suite encloses the visually selected portion in the +chosen environment. + + +Method 2: Using three letter mappings *ls_3_1_2_2* *ls_a_bm* + *enclosing-env-threeletter* + +You can also select text visually and press a sequence of three characters +beginning with , (the single comma character) and the selected text will be +enclosed in the chosen environment. The three letter sequence follows directly +from the three letter sequence used to insert environments as described here +[|ls_a_bj|]. The following example describes the rule used: + +If ECE inserts a \begin{center}...\end{center} environment, then to enclose a +block of selected text in \begin{center}...\end{center}, simply select the text +and press ,ce. The rule simply says that the leading E is converted to , and the +next 2 letters are small case. +Some of the visual mode mappings are sensitive to whether you choose line-wise +or character-wise. For example, if you choose a word and press ,ce, then you get +{\centering word}, whereas if you press ,ce on a line-wise selection, you get: > + \begin{center} + line + \end{center} + + + +Changing Environments *ls_3_1_3* *ls_a_bn* + *changing-environments* + +Pressing in normal mode detects which environment the cursor is presently +located in and prompts you to replace it with a new one. The innermost +environment is detected. For example, in the following source: > + \begin{equation} + \begin{array}{ccc} + 2 & 3 & 4 + \end{array} + \end{equation} +if you are located in the middle "2 & 3 & 4" line, then pressing will +prompt you to change the array environment, not the equation environment. In +addition, Latex-Suite will also try to change lines within the environment to be +consistent with the new environment. For example, if the original environment +was an equation environment with a \label command, then changing it to an +equation* environment will delete the \label. + +Pressing in normal mode has the same effect as pressing in +insert-mode, namely you will be prompted to choose an environment to insert. + +-------------------------------------------------------------------------------- +Command Mappings *ls_3_2* *ls_a_bo* + *latex-command-maps* + +Latex-Suite provides a rich set of mappings to insert, enclose and modify LaTeX +commands. + +Inserting LaTeX commands *ls_3_2_1* *ls_a_bp* + *inserting-commands* + + *ls-imap-f7* *ls_a_ei* + *ls-imap-s-f7* *ls_a_ej* +Pressing in insert or normal mode while the cursor is touching a word will +insert a command formed from the word touching the cursor. + +For certain common commands, Latex-Suite will expand them to include additional +arguments as needed. For example, frac becomes \frac{<++>}{<++>}<++>. Otherwise, +it will simply change the word under the cursor as follows > + word --> \word{<++>}<++> +You can define custom expansions of commands using the Tex_Com_{name} setting as +described in here [|ls_a_dj|]. + +If is pressed when the cursor is on white-space, then Latex-Suite will +prompt you to choose a command and insert that instead.The list of commands is +constructed from the g:Tex_PromptedCommands [|ls_a_dl|] setting and also from +commands which Latex-Suite finds while scanning custom packages which +Latex-Suite finds. See the Package actions [|ls_a_bL|] section for details on +which files are scanned etc. + + +Enclosing in a command *ls_3_2_2* *ls_a_bq* + *enclosing-commands* + +You can select a portion of text visually and press while still in visual +mode. This will prompt you with a list of commands. (This list can be customized +via the g:Tex_PromptedCommands [|ls_a_dl|] setting). You can either choose from +this list or type in a new command name. Once the selection is done, Latex-Suite +encloses the visually selected portion in the chosen command. + + +Changing commands *ls_3_2_3* *ls_a_br* + *changing-commands* + + *ls-vmap-f7* *ls_a_ek* +In both insert and normal mode will find out if you are presently within +an environment and then prompt you with a list of commands to change it to. + +-------------------------------------------------------------------------------- +Font Mappings *ls_3_3* *ls_a_bs* *font-maps* + +These mappings insert font descriptions such as: \textsf{<++>}<++> with the +cursor left in place of the first placeholder [|ls_a_eO|] (the <++> characters). + +Mnemonic: +1. first letter is always F (F for font) + +2. next 2 letters are the 2 letters describing the font. + +Example: Typing FEM in insert-mode expands to \emph{<++>}<++>. + +Just like environment mappings, you can visually select an area and press `sf to +have it enclosed in: \textsf{word} or > + {\sffamily + line + } +depending on character-wise or line-wise selection. + +-------------------------------------------------------------------------------- +Section Mappings *ls_3_4* *ls_a_bt* + *section-mappings* + +These maps insert LaTeX sections such as: > + \section{<++>}<++> +etc. Just as in the case of environments and fonts, can be enclosed with a +visual selection. The enclosing is not sensitive to character or line-wise +selection. + +Mnemonic: (make your own!) > + SPA for part + SCH for chapter + SSE for section + SSS for subsection + SS2 for subsubsection + SPG for paragraph + SSP for subparagraph + + +Example: SSE in insert mode inserts > + \section{<++>}<++> +If you select a word or line and press ,se, then you get > + \section{section name} +The menu item in Tex-Environments.Sections have a sub-menu called 'Advanced'. +Choosing an item from this sub-menu asks a couple of questions (whether you want +to include the section in the table of contents, whether there is a shorter name +for the table of contents) and then creates a more intelligent template. + +-------------------------------------------------------------------------------- +Greek Letter Mappings *ls_3_5* *ls_a_bu* + *greek-letter-mappings* + +Lower case + +`a through `z expand to \alpha through \zeta. + +NOTE: In the LaTex list of lowercase letters there is no \omicron because it + would be identical in appearance to Latin o. So inserting \omicron in + default LaTex would result an error. But we still expand `o to \omicron to + make the plugin behave consistently. And for those who really need to + distinguish between Latin o and \omicron, you may enable the command by + including package unicode-math or simply setting \newcommand\omicron{o} in + your document. + + +Upper case: + +`A through `Z expand to \Alpha through \Zeta. + +NOTE: Same as what happens to the Lower case, LaTeX does not support upper case + for all greek alphabets. And only the following expansions are valid in + default. In order to use the rest of expansions, you may want to manually + configure them by either including packages or defining corresponding + commands. + + +Valid Upper case Greek Letters in default: + + > + + `D = \Delta + `F = \Phi + `G = \Gamma + `Q = \Theta + `L = \Lambda + `X = \Xi + `Y = \Psi + `S = \Sigma + `U = \Upsilon + `W = \Omega +Just like other Latex-Suite mappings, these mappings are not created using the +standard imap command. Thus you can type slowly, correct using etc. + +-------------------------------------------------------------------------------- +Auc-Tex Key Bindings *ls_3_6* *ls_a_bv* + *auc-tex-mappings* + +These are simple 2 key expansions for some very commonly used LaTeX elements: + + > + `^ Expands To \Hat{<++>}<++> + `_ expands to \bar{<++>}<++> + `6 expands to \partial + `8 expands to \infty + `/ expands to \frac{<++>}{<++>}<++> + `% expands to \frac{<++>}{<++>}<++> + `@ expands to \circ + `0 expands to ^\circ + `= expands to \equiv + `\ expands to \setminus + `. expands to \cdot + `* expands to \times + `& expands to \wedge + `- expands to \bigcap + `+ expands to \bigcup + `( expands to \subset + `) expands to \supset + `< expands to \le + `> expands to \ge + `, expands to \nonumber + `~ expands to \tilde{<++>}<++> + `; expands to \dot{<++>}<++> + `: expands to \ddot{<++>}<++> + `2 expands to \sqrt{<++>}<++> + `| expands to \Big| + `I expands to \int_{<++>}^{<++>}<++> +(again, notice the convenient place-holders) + +In addition the visual mode macros are provided: + + > + `( encloses selection in \left( and \right) + `[ encloses selection in \left[ and \right] + `{ encloses selection in \left\{ and \right\} + `$ encloses selection in $$ or \[ \] depending on characterwise or + linewise selection + + +-------------------------------------------------------------------------------- +Diacritics *ls_3_7* *ls_a_bw* + *diacritic-mappings* + +These mappings speed up typing European languages which contain diacritic +characters such as a-umlaut etc. > + + expands to \v{} + = expands to \'{} +where is an alphabet. + + > + +} expands to \"{a} + +: expands to \^{o} +Latex-Suite also ships with smart backspacing [|ls_a_el|] functionality which +provides another convenience while editing languages with diacritics. + +NOTE: Diacritics are disabled by default in Latex-Suite because they can + sometimes be a little too intrusive. Moreover, most European users can + nowadays use font encodings which display diacritic characters directly + instead of having to rely on Latex-Suite's method of displaying + diacritics. + + Set the g:Tex_Diacritics [|ls_a_dq|] variable to enable diacritics. + + + +-------------------------------------------------------------------------------- +BibTeX Shortcuts *ls_3_8* *ls_a_bx* + *bibtex-bindings* + +Latex-Suite provides an easy way of entering bibliographic entries. Four +insert-mode mappings: BBB, BBL, BBH and BBX are provided, all of which +essentially act in the same manner. When you type any of these in insert-mode, +you will get a prompt asking you to choose a entry type for the bibliographic +entry. + +When you choose an entry type, a bibliographic entry template will be inserted. +For example, if you choose the option 'book' via the map BBB, then the following +template will be inserted: > + @BOOK{<+key+>, + author = {<++>}, + editor = {<++>}, + title = {<++>}, + publisher = {<++>}, + year = {<++>}, + otherinfo = {<++>} + }<++> + + +<+key+> will be highlighted in select-mode and you can type in the bib-key. +After that you can use to navigate to successive locations in the +template and enter new values. + +BBB inserts a template with only the fields mandatorily required for a given +entry type. BBL inserts a template with commonly used extra options. BBH inserts +a template with more options which are not as commonly used. BBX inserts a +template with all the fields which the entry type supports. + +NOTE: Mnemonic + -------- + B for Bibliographic entry, L for Large entry, H for Huge entry, and X + stands for all eXtras. + + + + +Customizing Bib-TeX fields *ls_3_8_1* *ls_a_by* + *adding-bib-options* + +If you wish the BBB command to insert a few additional fields in addition to the +fields it creates, then you will need to define global variables of the form > + g:Bib_{type}_options +in you $VIM/ftplugin/bib.vim file, where {type} is a string like 'article', +'book' etc. This variable should contain one of the letters defined in the +following table + +Character Field Type~ +w address +a author +b booktitle +c chapter +d edition +e editor +h howpublished +i institution +k isbn +j journal +m month +z note +n number +o organization +p pages +q publisher +r school +s series +t title +u type +v volume +y year + +For example, by default, choosing 'article' via BBB inserts the following +template by default > + @ARTICLE{<+key+>, + author = {<++>}, + title = {<++>}, + journal = {<++>}, + year = {<++>}, + otherinfo = {<++>} + }<++> +However, if g:Bib_article_options is defined as 'mnp', then 'article' will +insert the following template > + @ARTICLE{<+key+>, + author = {<++>}, + title = {<++>}, + journal = {<++>}, + year = {<++>}, + month = {<++>}, + number = {<++>}, + pages = {<++>}, + otherinfo = {<++>} + }<++> + + +If you have some other fields you wish to associate with an article which are +not listed above, then you will have to use the Bib_{type}_extrafields option. +This is a newline separated string of complete field names which will be +included in the template. For example, if you define > + let g:Bib_article_extrafields = "crossref\nabstract" +then the article template will include the lines > + crossref = {<++>}, + abstract = {<++>}, + + +NOTE: You will need to define Bib_* settings in your + $VIMRUNTIME/ftplugin/bib.vim file. + + + +-------------------------------------------------------------------------------- +Smart Key Mappings *ls_3_9* *ls_a_bz* + *smart-keys* + +Latex-Suite ships with the following smart keys: + +Smart Backspace +--------------- + *smart-backspace* *ls_a_el* +Pressing in insert mode checks to see whether we are just after something +like \'{a} and if so, deletes all of it. i.e, diacritics are treated as single +characters for backspacing. + +You might want to disable this feature, if you are editing Chinese, Japanese or +Korean text. + +Smart Quotes +------------ +Pressing " (English double quote) will insert `` or '' by making an intelligent +guess about whether we intended to open or close a quote. + +Smart Space +----------- +Latex-Suite maps the key in such a way that $ characters are not broken +across lines. It does this by first setting tw=0 so that Vim will not +automatically break lines and then maps the key to insert newlines +keeping $$'s on the same line. + +Smart Dots +---------- +Pressing ... (3 dots) results in \ldots outside math mode and \cdots in math +mode. + +-------------------------------------------------------------------------------- +Alt Key Macros *ls_3_10* *ls_a_bA* + *altkey-mappings* + +Latex-Suite utilizes a set of macros originally created by Carl Mueller in +auctex.vim to make inserting all the \left ... \right stuff very easy and to +also make some use of the heavily under-utilized key. + +NOTE: By default, the mappings involving the key are turned off for + compatibility with inserting non-ASCII characters. It can be enabled by + setting > + let g:Tex_AdvancedMath = 1 +< in your $VIM/ftplugin/tex.vim. + + +NOTE: By default, typing Alt- in Vim takes focus to the menu bar if a menu + with the hotkey exists. If in your case, there are conflicts due to + this behavior, you will need to set > + set winaltkeys=no +< in your $VIM/ftplugin/tex.vim in order to use these maps. + + +NOTE: Customizing the maps + -------------------- + If for some reason, you wish to not map the keys, (some European + users need to use the key to enter diacritics), you can change these + maps to other keys as described in the section Customizing Alt-key maps + [|ls_a_cv|]. + + + + + *ls_3_10_1* *ls_a_bB* *Alt-L* + +This is a polymorphic insert-mode mapping which expands to one of the following +depending on the character just before the cursor location. + +Character before cursor Expansion~ +( \left( <++> \right) +[ \left[ <++> \right] +| \left| <++> \right| +{ \left\{ <++> \right\} +< \langle <++> \rangle +q \lefteqn{<++>}<++> + +If the character before the cursor is none of the above, then it will simply +insert a \label{<++>}<++>. + + + *ls_3_10_2* *ls_a_bC* *Alt-B* + +This insert-mode mapping encloses the previous character in \mathbf{}. + + + *ls_3_10_3* *ls_a_bD* *Alt-C* + +In insert mode, this key is polymorphic as follows: + + +1. If the previous character is a letter or number, then capitalize it and + enclose it in \mathcal{}. + +2. otherwise insert \cite{}. +In visual mode, it will simply enclose the selection in \mathcal{} + + + *ls_3_10_4* *ls_a_bE* *Alt-I* + +This mapping inserts an \item command at the current cursor location depending +on which environment the cursor is enclosed in. The style of the \item command +is dependent on the enclosing environment. By default, has styles +defined forthe following environments: + +Environment Style~ +itemize \item +enumerate \item +theindex \item +thebibliography \item[<+biblabel+>]{<+bibkey+>} <++> +description \item[<+label+>] <++> + + is intelligent enough to account for nested environments. For example, > + \begin{itemize} + \item first item + \item second item + \begin{description} + \item[label1] first desc + \item[label2] second + % will insert "\item[<+label+>] <++>" if + % used here + \end{description} + \item third item + % will insert "\item " when if used here. + \end{itemize} + % will insert nothing ("") if used here +< + +The style used by can be customized using the +g:Tex_ItemStyle_environment [|ls_a_dm|] variable. + +-------------------------------------------------------------------------------- +Custom Macros *ls_3_11* *ls_a_bF* + *custom-macros-menu* + +This functionality available via the TeX-Suite.Macros menu, provides a way of +inserting customized macros into the current file via the menu. + +When Latex-Suite starts up, it scans the $VIM/ftplugin/latex-suite/macros/ +directory and creates a menu from the files found there. Each file is considered +as a single macro. You can place your own macros in this directory, using +placeholders [|ls_a_eO|] if wanted. + +When you choose a macro from the menu, the corresponding file is read into the +current buffer after the current cursor position. In non-gui mode, you can use +the |TMacro| command instead of choosing from the menu. This command takes the +macro file name as an argument. When called without arguments (preferred usage), +then a list of available macro files is displayed and the user is prompted to +choose one of them). + +There are some other tools provided in this menu, namely: + + +{New} Creates a new (unnamed) buffer in the latex-suite/macros/ directory. + Use the command :TexMacroNew in non-gui mode. +{Edit} Opens up the corresponding macro file for editing. Use |:TexMacroEdit| + in non-gui mode. When you try to edit {macro} not from local directory + Latex-Suite will copy it to your local directory with suffix "-local". + If local copy already exists Latex-Suite prompt for overwriting it. +{Delete} Deletes the corresponding macro. Use the prefixed numbers for fast + navigation of menus. Use |:TexMacroDelete| in non-gui mode. When you + choose to delete {macro} which is not in your local directory + Latex-Suite will refuse to delete it. +{Redraw} Rescans the macros/ directories and refreshes the macros list. + +-------------------------------------------------------------------------------- +Making your own Macros via IMAP() *ls_3_12* *ls_a_bG* + *ls-new-macros* + +If you find the need to create your own macros, then you can use the IMAP() +function provided with Latex-Suite. See [|ls_a_bH|] for a short explanation of +why you might prefer IMAP() over Vim's standard :imap command. An example best +explains the usage: > + :call IMAP('NOM', '\nomenclature{<++>}<++>', 'tex') +This will create a Latex-Suite-style mapping, where if you type NOM in insert +mode, you will get \nomenclature{<++>}<++> with the cursor left in place of the +first <++> characters. See [|ls_a_bI|] for a detailed explanation of the IMAP() +command. + +For maps which are triggered for a given filetype, the IMAP() command above +should be put in the filetype plugin script for that file. For example, for +tex-specific mappings, the IMAP() calls should go in $VIM/ftplugin/tex.vim. For +globally visible maps, you will need to use the following in either your +~/.vimrc or a file in your $VIM/plugin directory. > + augroup MyIMAPs + au! + au VimEnter * call IMAP('Foo', 'foo', '') + augroup END + + +IMAP mappings can be removed by IUNMAP, e.g., > + call IUNMAP('FEM','tex') + + + + +Why use IMAP() *ls_3_12_1* *ls_a_bH* + *why-IMAP* + +Using IMAP instead of Vim's built-in :imap command has a couple of advantages: +1. The 'ttimeout' option will generally limit how easily you can type the left + hand side for a normal :imap. if you type the left hand side too slowly, then + the mapping will not be activated. + +2. If you mistype one of the letters of the lhs, then the mapping is deactivated + as soon as you backspace to correct the mistake. + +3. The characters in lhs are shown on top of each other. This is fairly + distracting. This becomes a real annoyance when a lot of characters initiate + mappings. + + +IMAP() syntax *ls_3_12_2* *ls_a_bI* + *ls-imaps-syntax* + +Formally, the syntax which is used for the IMAP function is: > + call IMAP (lhs, rhs, ft [, phs, phe]) + + +Argument Explanation~ +lhs This is the "left-hand-side" of the mapping. When you use IMAP, only + the last character of this word is actually mapped, although the + effect is that the whole word is mapped. + + If you have two mappings which end in a common lhs, then the mapping + with the longer lhs is used. For example, if you do > + call IMAP('BarFoo', 'something', 'tex') + call IMAP('Foo', 'something else', 'tex') +< Then typing BarFoo inserts "something", whereas Foo by itself inserts + "something else". + + Also, the nature of IMAP() makes creating certain combination of + mappings impossible. For example if you have > + call IMAP('foo', 'something', 'tex') + call IMAP('foobar', 'something else', 'tex') +< Then you will never be able to trigger "foobar" because typing "foo" + will immediately insert "something". This is the "cost" which you + incur over the normal :imap command for the convenience of no + 'timeout' problems, the ability to correct lhs etc. + + +rhs The "right-hand-side" of the mapping. This is the expansion you will + get when you type lhs. + + This string can also contain special characters such as etc. + To do this, you will need to specify the second argument in + double-quotes as follows: > + :call IMAP('EFE', "\\begin{figure}\<++>\\end{figure}<++>", 'tex') +< With this, typing EFE is equivalent to typing in the right-hand side + with all the special characters in insert-mode. This has the advantage + that if you have filetype indentation set up, then the right hand side + will also be indented just as if you had typed it in normally. + + *IMAP_PutTextWithMovement* *ls_a_em* + You can also set up a Latex-Suite style mapping which calls a custom + function as follows: > + :call IMAP('FOO', "\=MyFoonction()\", 'tex') +< where MyFoonction is a custom function you have written. If + MyFoonction also has to return a string containing <++> characters, + then you will need to use the function IMAP_PutTextWithMovement(). An + example best explains the usage: + + > + call IMAP('FOO', "\=AskVimFunc()\", 'vim') + " Askvimfunc: Asks For Function Name And Sets Up Template + " Description: + function! AskVimFunc() + let name = input('Name of the function : ') + if name == '' + let name = "<+Function Name+>" + end + let islocal = input('Is this function scriptlocal ? [y]/n : ', 'y') + if islocal == 'y' + let sidstr = '' + else + let sidstr = '' + endif + return IMAP_PutTextWithMovement( + \ "\" ".name.": <+short description+> \" . + \ "Description: <+long description+>\" . + \ "\function! ".name."(<+arguments+>)<++>\" . + \ "<+function body+>\" . + \ "endfunction \" " + \ ) + endfunction +< + + +ft The file type for which this mapping is active. When this string is + left empty, the mapping applies for all file-types. A filetype + specific mapping will always take precedence. + + +phs, phe If you prefer to write the rhs with characters other than <+ and +> to + denote place-holders, you can use the last 2 arguments to specify + which characters in the rhs specify place-holders. By default, these + are <+ and +> respectively. + + Note that the phs and phe arguments do not control what characters + will be displayed for the placeholders when the mapping is actually + triggered. What characters are used to display place-holders when you + trigger an IMAP are controlled by the Imap_PlaceHolderStart + [|ls_a_cT|] and Imap_PlaceHolderEnd [|ls_a_eC|] settings. + + + +================================================================================ +Package Handling *ls_4* *ls_a_bJ* + *latex-packages* + +|ls_4_1| Inserting package commands +|ls_4_2| Actions taken for supported packages +|ls_4_3| Automatic Package detection +|ls_4_4| Writing supporting for a package + + +Latex-Suite has a lot of functionality written to ease working with packages. +Packages here refers to files which you include into the LaTeX document using +the \usepackage command. + + +-------------------------------------------------------------------------------- +Inserting package commands *ls_4_1* *ls_a_bK* + *inserting-packages* + +When you first invoke Latex-Suite, it scans the +$VIM/ftplugin/latex-suite/packages directory for package script files and +creates a menu from all the files found there. This menu is created under +TeX-Suite > Packages > Supported. This menu contains a list of packages +"supported" by Latex-Suite. When you choose one of the packages from this menu +(for example the amsmath package), then a line of the form > + \usepackage[<++>]{amsmath}<++> +will be inserted into the current file. + +The \usepackage line can also be inserted in an easy manner in the current file +by pressing while in the preamble of the current document. This will set up +a prompt from the supported packages and ask you to choose from one of them. If +you do not find the package you want to insert in the list, you can type in a +package-name and it will use that. Pressing in the preamble on a line +containing a single word will construct a \usepackage line from that word. + +You can also use the TPackage [|ls_a_cB|] to insert the \usepackage line. + +Once you have inserted a \usepackage line, for supported packages, you can use +the Options and Commands menus described in the next section [|ls_a_bL|]. + +-------------------------------------------------------------------------------- +Actions taken for supported packages *ls_4_2* *ls_a_bL* + *package-actions* + +Latex-Suite takes the following actions for packages detected when a file is +loaded, or a new \usepackage line is inserted using one of the methods described +in the previous section [|ls_a_bK|]. + +If you are using the GUI and you have g:Tex_Menus [|ls_a_dR|] set to 1, +Latex-Suite will create the following sub-menus +TeX-Suite > Packages > Options + +TeX-Suite > Packages > Commands + +where is the package you just inserted (or was detected). You can use +these menus to insert commands, environments and options which Latex-Suite +recognizes as belonging to this package. + +NOTE: While inserting an option, you need to position yourself in the + appropriate place in the document, most commonly inside the square braces + in the \usepackage[]{packname} command. Latex-Suite will not navigate to + that location. + + +In addition to creating these sub-menus, Latex-Suite will also scan the +$VIM/ftplugin/latex-suite/dictionaries directory and if a dictionary file +corresponding to the package file is found, then it will add the file to the +'dict' setting in Vim so you can use the command to complete words +from that file. + +For example, the SIUnits package has a custom dictionary. + + *latex-package-scanning* *ls_a_en* +If a package detected at startup is found by Latex-Suite in the current +directory or in a location specified by the g:Tex_TEXINPUTS [|ls_a_ed|] +variable, Latex-Suite will scan the package for \newenvironment and newcommand +lines and also append any commands and environments found to the list of +commands and environments which you are prompted with when you press +[|ls_a_bh|] or [|ls_a_ei|] in insert mode. +In addition, the TeX-Suite > Packages menu also contains the following submenus + +Update +------ +This command is to be invoked with the cursor placed on the package name. If the +corresponding package is found, then a sub-menu with the supported commands and +options is created. + +Update All +---------- +This function reads the preamble of the document for \usepackage lines and if +Latex-Suite supports the detected packages, then sub-menus containing the +package options and commands are created. + + +-------------------------------------------------------------------------------- +Automatic Package detection *ls_4_3* *ls_a_bM* + *automatic-package-detection* + +Whenever Latex-Suite begins editing a new LaTeX file, it scans it for +\usepackage{name} lines, and if a supported package is found, then it will +create sub-menus and add to the 'dict' setting as described above. + +If a master-file [|ls_a_cr|] has been specified, then it will scan that file +instead of the current file. See the section Custom Packages [|ls_a_bN|] to see +which files Latex-Suite will scan in more detail. + +For all the packages detected in this manner, Latex-Suite will take certain +actions as described in the section package support. [|ls_a_bL|]. + + + +Custom Packages *ls_4_3_1* *ls_a_bN* + *custom-packages* + +Often times, the preamble can become too long, and some people prefer to put +most of their personalization in a custom package and include that using a +\usepackage line. Latex-Suite tries to search such customs package for other +\usepackage lines, so that supported packages included in this indirect manner +can also be used to create sub-menus, extend the 'dict' setting etc. The most +obvious place to place such custom packages is in the same directory as the +edited file. In addition, LaTeX also supports placing custom packages in places +pointed to by the $TEXINPUTS environment variable. + +If you use the $TEXINPUTS variable in LaTeX, and you wish Latex-Suite to search +these custom packages for \usepackage lines, then you need to initialize the +g:Tex_TEXINPUTS [|ls_a_ed|] variable. + +The g:Tex_TEXINPUTS variable needs to be set in the same format which Vim uses +for the 'path' setting. This format is explained in detail if you do > + :help file-searching +from within Vim. + +Therefore the value of g:Tex_TEXINPUTS will most probably be different from +$TEXINPUTS which your native LaTeX distribution uses. + +Example: > + let g:Tex_TEXINPUTS = '~/texmf/mypackages/**,./**' +The ** indicates that all directories below the directory ~/texmf/mypackages and +./ are to be scanned for custom packages. + +NOTE: The present directory '.' is always searched. You need not include that in + g:Tex_TEXINPUTS. + + + +-------------------------------------------------------------------------------- +Writing supporting for a package *ls_4_4* *ls_a_bO* + *supporting-packages* + +Supporting a package is easy and consists of writing a vim script with the same +name as the package and placing it in the $VIM/ftplugin/latex-suite/packages +directory. A package script should define two variables as described in the next +two sections. In addition to these two variables, you can also define any +functions, environment definitions etc. in this file. + + + +g:Tex_package_option_ *ls_4_4_1* *ls_a_bP* + +This setting is a string containing a comma separated list of options supported +by this package. + +Example: > + g:Tex_package_option_mypack = 'opt1,opt2=,sbr:group1,opt3,opt4' +The = suffix means that the option takes a value. Use sbr:group name to separate +options into sub-menus. All successive options will be clubbed into the group1 +sub-menu till the next sbr: option is encountered. + + +g:Tex_package_ *ls_4_4_2* *ls_a_bQ* + + > + + g:TeX_package_ = "pre:Command,pre:Command1" + More detailed example is in latex-suite/packages/exmpl file (slightly + outdated). + Here is short summary of prefixes which can be used in package files: + (x - place with cursor, <++> - |placeholder|) + + {env:command} Environment: creates simple environment template + \begin{command} + x + \end{command}<++> + {eno:command} Environment with option: + \begin[x]{command} + <++> + \end{command}<++> + {ens:command[<