first commit
David Blume

David Blume commited on 2015-11-27 14:48:06
Showing 63 changed files, with 17969 additions and 0 deletions.

... ...
@@ -0,0 +1,12 @@
1
+# ~/.bash_profile: executed by bash for login shells.
2
+
3
+# source the system wide bashrc if it exists
4
+if [ -e /etc/bash.bashrc ] ; then
5
+  source /etc/bash.bashrc
6
+fi
7
+
8
+# source the users bashrc if it exists
9
+if [ -e "${HOME}/.bashrc" ] ; then
10
+  source "${HOME}/.bashrc"
11
+fi
12
+
... ...
@@ -0,0 +1,39 @@
1
+export PS1="\W\$ "
2
+
3
+add_to_path() {
4
+    if [ -d "$1" ] && [[ ! $PATH =~ (^|:)$1(:|$) ]]; then
5
+        PATH+=:$1
6
+    fi
7
+}
8
+
9
+# if this is a CygWin .bashrc, then set CygWin's commands first in PATH
10
+# because link.exe and find.exe exist in Windows's path.
11
+# Add /usr/lib/lapack at the end so python's numpy can find lapack_lite
12
+# (Note: BSD bash, used by OS X doesn't have the "substr" test for expr.)
13
+if [[ $(uname -s) == CYGWIN* ]]; then
14
+        PATH=/usr/local/bin:/usr/bin:$PATH
15
+	PATH=${PATH//":/usr/local/bin:/usr/bin"/} # delete any instances in middle
16
+	add_to_path /usr/lib/lapack
17
+	ulimit -n 1024 # for "duplicity"
18
+	alias ls='ls --color=auto'
19
+elif [[ $(uname -s) == Darwin* ]]; then
20
+	export LSCOLORS=gxfxcxdxbxegedabagacad
21
+	export CLICOLOR=1
22
+fi
23
+
24
+# change the color of directories in the ls command 
25
+#
26
+# After executing: dircolors -p > .dircolors
27
+# And changing the following line in .dircolors:
28
+# DIR 00;36 # directory
29
+if [ "$TERM" != "dumb" ]; then
30
+	[ -e "$HOME/.dircolors" ] && DIR_COLORS="$HOME/.dircolors"
31
+	[ -e "$DIR_COLORS" ] || DIR_COLORS=""
32
+	eval "`dircolors -b $DIR_COLORS`"
33
+fi
34
+
35
+# Add to PATH only if not already in PATH.
36
+add_to_path $HOME/bin
37
+
38
+alias findinchppfiles="find . -type f \( -name \*.[ch]pp -or -name \*.[ch] \) -print0 | xargs -0 grep -nI"
39
+alias findinpyfiles="find . -name \*.py -print0 | xargs -0 grep -nI"
... ...
@@ -0,0 +1,5 @@
1
+[user]
2
+	name = David Blume
3
+	email = david.blume@gmail.com
4
+[push]
5
+	default = simple
... ...
@@ -0,0 +1,254 @@
1
+" pathogen.vim - path option manipulation
2
+" Maintainer:   Tim Pope <http://tpo.pe/>
3
+" Version:      2.0
4
+
5
+" Install in ~/.vim/autoload (or ~\vimfiles\autoload).
6
+"
7
+" For management of individually installed plugins in ~/.vim/bundle (or
8
+" ~\vimfiles\bundle), adding `call pathogen#infect()` to your .vimrc
9
+" prior to `filetype plugin indent on` is the only other setup necessary.
10
+"
11
+" The API is documented inline below.  For maximum ease of reading,
12
+" :set foldmethod=marker
13
+
14
+if exists("g:loaded_pathogen") || &cp
15
+  finish
16
+endif
17
+let g:loaded_pathogen = 1
18
+
19
+" Point of entry for basic default usage.  Give a directory name to invoke
20
+" pathogen#runtime_append_all_bundles() (defaults to "bundle"), or a full path
21
+" to invoke pathogen#runtime_prepend_subdirectories().  Afterwards,
22
+" pathogen#cycle_filetype() is invoked.
23
+function! pathogen#infect(...) abort " {{{1
24
+  let source_path = a:0 ? a:1 : 'bundle'
25
+  if source_path =~# '[\\/]'
26
+    call pathogen#runtime_prepend_subdirectories(source_path)
27
+  else
28
+    call pathogen#runtime_append_all_bundles(source_path)
29
+  endif
30
+  call pathogen#cycle_filetype()
31
+endfunction " }}}1
32
+
33
+" Split a path into a list.
34
+function! pathogen#split(path) abort " {{{1
35
+  if type(a:path) == type([]) | return a:path | endif
36
+  let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,')
37
+  return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")')
38
+endfunction " }}}1
39
+
40
+" Convert a list to a path.
41
+function! pathogen#join(...) abort " {{{1
42
+  if type(a:1) == type(1) && a:1
43
+    let i = 1
44
+    let space = ' '
45
+  else
46
+    let i = 0
47
+    let space = ''
48
+  endif
49
+  let path = ""
50
+  while i < a:0
51
+    if type(a:000[i]) == type([])
52
+      let list = a:000[i]
53
+      let j = 0
54
+      while j < len(list)
55
+        let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g')
56
+        let path .= ',' . escaped
57
+        let j += 1
58
+      endwhile
59
+    else
60
+      let path .= "," . a:000[i]
61
+    endif
62
+    let i += 1
63
+  endwhile
64
+  return substitute(path,'^,','','')
65
+endfunction " }}}1
66
+
67
+" Convert a list to a path with escaped spaces for 'path', 'tag', etc.
68
+function! pathogen#legacyjoin(...) abort " {{{1
69
+  return call('pathogen#join',[1] + a:000)
70
+endfunction " }}}1
71
+
72
+" Remove duplicates from a list.
73
+function! pathogen#uniq(list) abort " {{{1
74
+  let i = 0
75
+  let seen = {}
76
+  while i < len(a:list)
77
+    if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i])
78
+      call remove(a:list,i)
79
+    elseif a:list[i] ==# ''
80
+      let i += 1
81
+      let empty = 1
82
+    else
83
+      let seen[a:list[i]] = 1
84
+      let i += 1
85
+    endif
86
+  endwhile
87
+  return a:list
88
+endfunction " }}}1
89
+
90
+" \ on Windows unless shellslash is set, / everywhere else.
91
+function! pathogen#separator() abort " {{{1
92
+  return !exists("+shellslash") || &shellslash ? '/' : '\'
93
+endfunction " }}}1
94
+
95
+" Convenience wrapper around glob() which returns a list.
96
+function! pathogen#glob(pattern) abort " {{{1
97
+  let files = split(glob(a:pattern),"\n")
98
+  return map(files,'substitute(v:val,"[".pathogen#separator()."/]$","","")')
99
+endfunction "}}}1
100
+
101
+" Like pathogen#glob(), only limit the results to directories.
102
+function! pathogen#glob_directories(pattern) abort " {{{1
103
+  return filter(pathogen#glob(a:pattern),'isdirectory(v:val)')
104
+endfunction "}}}1
105
+
106
+" Turn filetype detection off and back on again if it was already enabled.
107
+function! pathogen#cycle_filetype() " {{{1
108
+  if exists('g:did_load_filetypes')
109
+    filetype off
110
+    filetype on
111
+  endif
112
+endfunction " }}}1
113
+
114
+" Checks if a bundle is 'disabled'. A bundle is considered 'disabled' if
115
+" its 'basename()' is included in g:pathogen_disabled[]' or ends in a tilde.
116
+function! pathogen#is_disabled(path) " {{{1
117
+  if a:path =~# '\~$'
118
+    return 1
119
+  elseif !exists("g:pathogen_disabled")
120
+    return 0
121
+  endif
122
+  let sep = pathogen#separator()
123
+  return index(g:pathogen_disabled, strpart(a:path, strridx(a:path, sep)+1)) != -1
124
+endfunction "}}}1
125
+
126
+" Prepend all subdirectories of path to the rtp, and append all 'after'
127
+" directories in those subdirectories.
128
+function! pathogen#runtime_prepend_subdirectories(path) " {{{1
129
+  let sep    = pathogen#separator()
130
+  let before = filter(pathogen#glob_directories(a:path.sep."*"), '!pathogen#is_disabled(v:val)')
131
+  let after  = filter(pathogen#glob_directories(a:path.sep."*".sep."after"), '!pathogen#is_disabled(v:val[0:-7])')
132
+  let rtp = pathogen#split(&rtp)
133
+  let path = expand(a:path)
134
+  call filter(rtp,'v:val[0:strlen(path)-1] !=# path')
135
+  let &rtp = pathogen#join(pathogen#uniq(before + rtp + after))
136
+  return &rtp
137
+endfunction " }}}1
138
+
139
+" For each directory in rtp, check for a subdirectory named dir.  If it
140
+" exists, add all subdirectories of that subdirectory to the rtp, immediately
141
+" after the original directory.  If no argument is given, 'bundle' is used.
142
+" Repeated calls with the same arguments are ignored.
143
+function! pathogen#runtime_append_all_bundles(...) " {{{1
144
+  let sep = pathogen#separator()
145
+  let name = a:0 ? a:1 : 'bundle'
146
+  if "\n".s:done_bundles =~# "\\M\n".name."\n"
147
+    return ""
148
+  endif
149
+  let s:done_bundles .= name . "\n"
150
+  let list = []
151
+  for dir in pathogen#split(&rtp)
152
+    if dir =~# '\<after$'
153
+      let list +=  filter(pathogen#glob_directories(substitute(dir,'after$',name,'').sep.'*[^~]'.sep.'after'), '!pathogen#is_disabled(v:val[0:-7])') + [dir]
154
+    else
155
+      let list +=  [dir] + filter(pathogen#glob_directories(dir.sep.name.sep.'*[^~]'), '!pathogen#is_disabled(v:val)')
156
+    endif
157
+  endfor
158
+  let &rtp = pathogen#join(pathogen#uniq(list))
159
+  return 1
160
+endfunction
161
+
162
+let s:done_bundles = ''
163
+" }}}1
164
+
165
+" Invoke :helptags on all non-$VIM doc directories in runtimepath.
166
+function! pathogen#helptags() " {{{1
167
+  let sep = pathogen#separator()
168
+  for dir in pathogen#split(&rtp)
169
+    if (dir.sep)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir.sep.'doc') == 2 && !empty(filter(split(glob(dir.sep.'doc'.sep.'*'),"\n>"),'!isdirectory(v:val)')) && (!filereadable(dir.sep.'doc'.sep.'tags') || filewritable(dir.sep.'doc'.sep.'tags'))
170
+      helptags `=dir.'/doc'`
171
+    endif
172
+  endfor
173
+endfunction " }}}1
174
+
175
+command! -bar Helptags :call pathogen#helptags()
176
+
177
+" Like findfile(), but hardcoded to use the runtimepath.
178
+function! pathogen#runtime_findfile(file,count) "{{{1
179
+  let rtp = pathogen#join(1,pathogen#split(&rtp))
180
+  let file = findfile(a:file,rtp,a:count)
181
+  if file ==# ''
182
+    return ''
183
+  else
184
+    return fnamemodify(file,':p')
185
+  endif
186
+endfunction " }}}1
187
+
188
+" Backport of fnameescape().
189
+function! pathogen#fnameescape(string) " {{{1
190
+  if exists('*fnameescape')
191
+    return fnameescape(a:string)
192
+  elseif a:string ==# '-'
193
+    return '\-'
194
+  else
195
+    return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','')
196
+  endif
197
+endfunction " }}}1
198
+
199
+if exists(':Vedit')
200
+  finish
201
+endif
202
+
203
+function! s:find(count,cmd,file,lcd) " {{{1
204
+  let rtp = pathogen#join(1,pathogen#split(&runtimepath))
205
+  let file = pathogen#runtime_findfile(a:file,a:count)
206
+  if file ==# ''
207
+    return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'"
208
+  elseif a:lcd
209
+    let path = file[0:-strlen(a:file)-2]
210
+    execute 'lcd `=path`'
211
+    return a:cmd.' '.pathogen#fnameescape(a:file)
212
+  else
213
+    return a:cmd.' '.pathogen#fnameescape(file)
214
+  endif
215
+endfunction " }}}1
216
+
217
+function! s:Findcomplete(A,L,P) " {{{1
218
+  let sep = pathogen#separator()
219
+  let cheats = {
220
+        \'a': 'autoload',
221
+        \'d': 'doc',
222
+        \'f': 'ftplugin',
223
+        \'i': 'indent',
224
+        \'p': 'plugin',
225
+        \'s': 'syntax'}
226
+  if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0])
227
+    let request = cheats[a:A[0]].a:A[1:-1]
228
+  else
229
+    let request = a:A
230
+  endif
231
+  let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*'
232
+  let found = {}
233
+  for path in pathogen#split(&runtimepath)
234
+    let path = expand(path, ':p')
235
+    let matches = split(glob(path.sep.pattern),"\n")
236
+    call map(matches,'isdirectory(v:val) ? v:val.sep : v:val')
237
+    call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]')
238
+    for match in matches
239
+      let found[match] = 1
240
+    endfor
241
+  endfor
242
+  return sort(keys(found))
243
+endfunction " }}}1
244
+
245
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve       :execute s:find(<count>,'edit<bang>',<q-args>,0)
246
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit    :execute s:find(<count>,'edit<bang>',<q-args>,0)
247
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen    :execute s:find(<count>,'edit<bang>',<q-args>,1)
248
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit   :execute s:find(<count>,'split',<q-args>,<bang>1)
249
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit  :execute s:find(<count>,'vsplit',<q-args>,<bang>1)
250
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(<count>,'tabedit',<q-args>,<bang>1)
251
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit   :execute s:find(<count>,'pedit',<q-args>,<bang>1)
252
+command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread    :execute s:find(<count>,'read',<q-args>,<bang>1)
253
+
254
+" vim:set et sw=2:
... ...
@@ -0,0 +1,16 @@
1
+## 1.0.1 (Jul 23, 2013)
2
+- Fixes `:Bdelete`ing via buffer number. Finally, perfect!
3
+
4
+## 1.0.0 (Jul 23, 2013)
5
+- Hides the empty buffer from buffer explorers and tabbars.
6
+- Handles `:Bdelete!`ing buffers which are set to auto-delete via `&bufhidden`.
7
+- Wipes empty buffers after hiding to reduce the amount of unlisted buffers after using Bbye for a while.
8
+- Handles buffer explorers and tabbars better that remove or add windows mid-flight.
9
+- Improves an edge-case where the empty buffer might get listed and show up in buffer explorers.
10
+- Perfect for v1.0.0.
11
+
12
+## 0.9.1 (Jul 21, 2013)
13
+- Removes an innocent but forgotten debugging line. Now even more perfect.
14
+
15
+## 0.9.0 (Jul 21, 2013)
16
+- First release. It's perfect.
... ...
@@ -0,0 +1,20 @@
1
+Bbye
2
+Copyright (C) 2013 Andri Möll
3
+
4
+This program is free software: you can redistribute it and/or modify it under
5
+the terms of the GNU Affero General Public License as published by the Free
6
+Software Foundation, either version 3 of the License, or any later version.
7
+
8
+Additional permission under the GNU Affero GPL version 3 section 7:
9
+If you modify this Program, or any covered work, by linking or
10
+combining it with other code, such other code is not for that reason
11
+alone subject to any of the requirements of the GNU Affero GPL version 3.
12
+
13
+In summary:
14
+- You can use this program for no cost.
15
+- You can use this program for both personal and commercial reasons.
16
+- You do not have to share your own program's code which uses this program.
17
+- You have to share modifications (e.g bug-fixes) you've made to this program.
18
+
19
+For the full copy of the GNU Affero General Public License see:
20
+http://www.gnu.org/licenses.
... ...
@@ -0,0 +1,15 @@
1
+VERSION := 1.0.1
2
+
3
+love:
4
+	@echo "Feel like makin' love."
5
+
6
+pack:
7
+	zip -r "vim-bbye-$(VERSION).zip" * --exclude Makefile --exclude "*.zip"
8
+
9
+publish:
10
+	open "http://www.vim.org/scripts/add_script_version.php?script_id=4664"
11
+
12
+tag:
13
+	git tag "v$(VERSION)"
14
+	
15
+.PHONY: love pack publish tag
... ...
@@ -0,0 +1,85 @@
1
+Bbye (Buffer Bye) for Vim
2
+==========================
3
+Bbye allows you to do delete buffers (close files) without closing your windows or messing up your layout.
4
+
5
+Vim by default closes all windows that have the buffer (file) open when you do `:bdelete`.  If you've just got your splits and columns perfectly tuned, having them messed up equals a punch in the face and that's no way to tango.
6
+
7
+Bbye gives you a `:Bdelete` command that behaves like a well designed citizen:
8
+
9
+- Closes and removes the buffer.
10
+- Shows another file in that window.
11
+- Shows an empty file if you've got no other files open.
12
+- Does not leave useless `[no file]` buffers if you decide to edit another file in that window.
13
+- Works even if a file's open in multiple windows.
14
+- Works a-okay with various buffer explorers and tabbars.
15
+
16
+Regain your throne as king of buffers!
17
+
18
+
19
+Installing
20
+----------
21
+The easiest and most modular way is to download Bbye to `~/.vim/bundle`:
22
+```
23
+mkdir -p ~/.vim/bundle/bbye
24
+```
25
+
26
+Using Git:
27
+```
28
+git clone https://github.com/moll/vim-bbye.git ~/.vim/bundle/bbye
29
+```
30
+
31
+Using Wget:
32
+```
33
+wget https://github.com/moll/vim-bbye/archive/master.tar.gz -O- | tar -xf- --strip-components 1 -C ~/.vim/bundle/bbye
34
+```
35
+
36
+Then prepend that directory to Vim's `&runtimepath` (or use [Pathogen](https://github.com/tpope/vim-pathogen)):
37
+```
38
+set runtimepath^=~/.vim/bundle/bbye
39
+```
40
+
41
+
42
+Using
43
+-----
44
+Instead of using `:bdelete`, use `:Bdelete`.
45
+Fortunately autocomplete helps by sorting `:Bdelete` before its lowercase brother.
46
+
47
+As it's likely you'll be using `:Bdelete` often, make a shortcut to `\q`, for example, to save time. Throw this to your `vimrc`:
48
+```
49
+:nnoremap <Leader>q :Bdelete<CR>
50
+```
51
+
52
+### Closing all open buffers and files
53
+
54
+Occasionally you'll want to close all open buffers and files while leaving your pristine window setup as is. That's easy. Just do:
55
+```
56
+:bufdo :Bdelete
57
+```
58
+
59
+### Aliasing to :Bclose
60
+
61
+If you've used any `Bclose.vim` scripts before and for some reason need the `:Bclose` command to exist, you may make an alias:
62
+```
63
+command! -bang -complete=buffer -nargs=? Bclose Bdelete<bang> <args>
64
+```
65
+
66
+
67
+License
68
+-------
69
+Bbye is released under a *Lesser GNU Affero General Public License*, which in summary means:
70
+
71
+- You **can** use this program for **no cost**.
72
+- You **can** use this program for **both personal and commercial reasons**.
73
+- You **do not have to share your own program's code** which uses this program.
74
+- You **have to share modifications** (e.g bug-fixes) you've made to this program.
75
+
76
+For more convoluted language, see the `LICENSE` file.
77
+
78
+
79
+About
80
+-----
81
+**[Andri Möll](http://themoll.com)** authored this in SublemacslipseMate++.  
82
+[Monday Calendar](https://mondayapp.com) supported the engineering work.  
83
+Inspired by [Bclose.vim](http://vim.wikia.com/wiki/VimTip165), but rewritten to be perfect.
84
+
85
+If you find Bbye needs improving or you've got a question, please don't hesitate to email me anytime at andri@dot.ee or [create an issue online](https://github.com/moll/vim-bbye/issues).
... ...
@@ -0,0 +1,84 @@
1
+if exists("g:loaded_bbye") || &cp | finish | endif
2
+let g:loaded_bbye = 1
3
+
4
+function! s:bdelete(bang, buffer_name)
5
+	let buffer = s:str2bufnr(a:buffer_name)
6
+	let w:bbye_back = 1
7
+
8
+	if buffer < 0
9
+		return s:warn("E516: No buffers were deleted. No match for ".a:buffer_name)
10
+	endif
11
+
12
+	if getbufvar(buffer, "&modified") && empty(a:bang)
13
+		let error = "E89: No write since last change for buffer "
14
+		return s:warn(error . buffer . " (add ! to override)")
15
+	endif
16
+
17
+	" If the buffer is set to delete and it contains changes, we can't switch
18
+	" away from it. Hide it before eventual deleting:
19
+	if getbufvar(buffer, "&modified") && !empty(a:bang)
20
+		call setbufvar(buffer, "&bufhidden", "hide")
21
+	endif
22
+
23
+	" For cases where adding buffers causes new windows to appear or hiding some
24
+	" causes windows to disappear and thereby decrement, loop backwards.
25
+	for window in reverse(range(1, winnr("$")))
26
+		" For invalid window numbers, winbufnr returns -1.
27
+		if winbufnr(window) != buffer | continue | endif
28
+		execute window . "wincmd w"
29
+
30
+		" Bprevious also wraps around the buffer list, if necessary:
31
+		try | exe bufnr("#") > 0 && buflisted(bufnr("#")) ? "buffer #" : "bprevious"
32
+		catch /^Vim([^)]*):E85:/ " E85: There is no listed buffer
33
+		endtry
34
+
35
+		" If found a new buffer for this window, mission accomplished:
36
+		if bufnr("%") != buffer | continue | endif
37
+
38
+		call s:new(a:bang) 
39
+	endfor
40
+
41
+	" Because tabbars and other appearing/disappearing windows change
42
+	" the window numbers, find where we were manually:
43
+	let back = filter(range(1, winnr("$")), "getwinvar(v:val, 'bbye_back')")[0]
44
+	if back | exe back . "wincmd w" | unlet w:bbye_back | endif
45
+
46
+	" If it hasn't been already deleted by &bufhidden, end its pains now.
47
+	" Unless it previously was an unnamed buffer and :enew returned it again.
48
+	if bufexists(buffer) && buffer != bufnr("%")
49
+		exe "bdelete" . a:bang . " " . buffer
50
+	endif
51
+endfunction
52
+
53
+function! s:str2bufnr(buffer)
54
+	if empty(a:buffer)
55
+		return bufnr("%")
56
+	elseif a:buffer =~ '^\d\+$'
57
+		return bufnr(str2nr(a:buffer))
58
+	else
59
+		return bufnr(a:buffer)
60
+	endif
61
+endfunction
62
+
63
+function! s:new(bang)
64
+	exe "enew" . a:bang
65
+
66
+	setl noswapfile
67
+	" If empty and out of sight, delete it right away:
68
+	setl bufhidden=wipe
69
+	" Regular buftype warns people if they have unsaved text there.  Wouldn't
70
+	" want to lose someone's data:
71
+	setl buftype=
72
+	" Hide the buffer from buffer explorers and tabbars:
73
+	setl nobuflisted
74
+endfunction
75
+
76
+" Using the built-in :echoerr prints a stacktrace, which isn't that nice.
77
+function! s:warn(msg)
78
+	echohl ErrorMsg
79
+	echomsg a:msg
80
+	echohl NONE
81
+endfunction
82
+
83
+command! -bang -complete=buffer -nargs=? Bdelete
84
+	\ :call s:bdelete(<q-bang>, <q-args>)
... ...
@@ -0,0 +1,3 @@
1
+*~
2
+*.swp
3
+tags
... ...
@@ -0,0 +1,104 @@
1
+The NERD Tree
2
+=============
3
+
4
+Intro
5
+-----
6
+
7
+The NERD tree allows you to explore your filesystem and to open files and
8
+directories. It presents the filesystem to you in the form of a tree which you
9
+manipulate with the keyboard and/or mouse. It also allows you to perform
10
+simple filesystem operations.
11
+
12
+The following features and functionality are provided by the NERD tree:
13
+
14
+  * Files and directories are displayed in a hierarchical tree structure
15
+  * Different highlighting is provided for the following types of nodes:
16
+    * files
17
+    * directories
18
+    * sym-links
19
+    * windows .lnk files
20
+    * read-only files
21
+    * executable files
22
+  * Many (customisable) mappings are provided to manipulate the tree:
23
+    * Mappings to open/close/explore directory nodes
24
+    * Mappings to open files in new/existing windows/tabs
25
+    * Mappings to change the current root of the tree
26
+    * Mappings to navigate around the tree
27
+    * ...
28
+  * Directories and files can be bookmarked.
29
+  * Most NERD tree navigation can also be done with the mouse
30
+  * Filtering of tree content (can be toggled at runtime)
31
+    * custom file filters to prevent e.g. vim backup files being displayed
32
+    * optional displaying of hidden files (. files)
33
+    * files can be "turned off" so that only directories are displayed
34
+  * The position and size of the NERD tree window can be customised
35
+  * The order in which the nodes in the tree are listed can be customised.
36
+  * A model of your filesystem is created/maintained as you explore it. This
37
+    has several advantages:
38
+    * All filesystem information is cached and is only re-read on demand
39
+    * If you revisit a part of the tree that you left earlier in your
40
+      session, the directory nodes will be opened/closed as you left them
41
+  * The script remembers the cursor position and window position in the NERD
42
+    tree so you can toggle it off (or just close the tree window) and then
43
+    reopen it (with NERDTreeToggle) the NERD tree window will appear exactly
44
+    as you left it
45
+  * You can have a separate NERD tree for each tab, share trees across tabs,
46
+    or a mix of both.
47
+  * By default the script overrides the default file browser (netw), so if
48
+    you :edit a directory a (slighly modified) NERD tree will appear in the
49
+    current window
50
+  * A programmable menu system is provided (simulates right clicking on a node)
51
+    * one default menu plugin is provided to perform basic filesytem
52
+      operations (create/delete/move/copy files/directories)
53
+  * There's an API for adding your own keymappings
54
+
55
+Installation
56
+------------
57
+
58
+[pathogen.vim](https://github.com/tpope/vim-pathogen) is the recommended way to install nerdtree.
59
+
60
+    cd ~/.vim/bundle
61
+    git clone https://github.com/scrooloose/nerdtree.git
62
+
63
+Then reload vim, run `:helptags`, and check out `:help NERD_tree.txt`.
64
+
65
+
66
+Faq
67
+---
68
+
69
+__Q. Can I have the nerdtree on every tab automatically?__
70
+
71
+A. Nope. If this is something you want then chances are you aren't using tabs
72
+   and buffers as they were intended to be used. Read this
73
+   http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers
74
+
75
+   If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs)
76
+
77
+__Q. How can I open a NERDTree automatically when vim starts up?__
78
+
79
+A. Stick this in your vimrc: `autocmd vimenter * NERDTree`
80
+
81
+__Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__
82
+
83
+A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif`
84
+
85
+__Q. How can I close vim if the only window left open is a NERDTree?__
86
+
87
+A. Stick this in your vimrc:
88
+
89
+   `autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif`
90
+
91
+
92
+Changelog
93
+---------
94
+
95
+4.2.0 (2011-12-28)
96
+
97
+ * Add NERDTreeDirArrows option to make the UI use pretty arrow chars instead of the old +~| chars to define the tree structure (sickill)
98
+ * shift the syntax highlighting out into its own syntax file (gnap) * add some mac specific options to the filesystem menu - for macvim only (andersonfreitas)
99
+ * Add NERDTreeMinimalUI option to remove some non functional parts of the nerdtree ui (camthompson)
100
+ * tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the new behaviour (benjamingeiger)
101
+ * if no name is given to :Bookmark, make it default to the name of the target file/dir (minyoung)
102
+ * use 'file' completion when doing copying, create, and move operations (EvanDotPro)
103
+ * lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)
104
+
... ...
@@ -0,0 +1,1362 @@
1
+*NERD_tree.txt*   A tree explorer plugin that owns your momma!
2
+
3
+
4
+
5
+    omg its ... ~
6
+
7
+    ________  ________   _   ____________  ____     __________  ____________~
8
+   /_  __/ / / / ____/  / | / / ____/ __ \/ __ \   /_  __/ __ \/ ____/ ____/~
9
+    / / / /_/ / __/    /  |/ / __/ / /_/ / / / /    / / / /_/ / __/ / __/   ~
10
+   / / / __  / /___   / /|  / /___/ _, _/ /_/ /    / / / _, _/ /___/ /___   ~
11
+  /_/ /_/ /_/_____/  /_/ |_/_____/_/ |_/_____/    /_/ /_/ |_/_____/_____/   ~
12
+
13
+
14
+                              Reference Manual~
15
+
16
+
17
+
18
+
19
+==============================================================================
20
+CONTENTS                                                   *NERDTree-contents*
21
+
22
+    1.Intro...................................|NERDTree|
23
+    2.Functionality provided..................|NERDTreeFunctionality|
24
+        2.1.Global commands...................|NERDTreeGlobalCommands|
25
+        2.2.Bookmarks.........................|NERDTreeBookmarks|
26
+            2.2.1.The bookmark table..........|NERDTreeBookmarkTable|
27
+            2.2.2.Bookmark commands...........|NERDTreeBookmarkCommands|
28
+            2.2.3.Invalid bookmarks...........|NERDTreeInvalidBookmarks|
29
+        2.3.NERD tree mappings................|NERDTreeMappings|
30
+        2.4.The NERD tree menu................|NERDTreeMenu|
31
+    3.Options.................................|NERDTreeOptions|
32
+        3.1.Option summary....................|NERDTreeOptionSummary|
33
+        3.2.Option details....................|NERDTreeOptionDetails|
34
+    4.The NERD tree API.......................|NERDTreeAPI|
35
+        4.1.Key map API.......................|NERDTreeKeymapAPI|
36
+        4.2.Menu API..........................|NERDTreeMenuAPI|
37
+    5.About...................................|NERDTreeAbout|
38
+    6.Changelog...............................|NERDTreeChangelog|
39
+    7.Credits.................................|NERDTreeCredits|
40
+    8.License.................................|NERDTreeLicense|
41
+
42
+==============================================================================
43
+1. Intro                                                            *NERDTree*
44
+
45
+What is this "NERD tree"??
46
+
47
+The NERD tree allows you to explore your filesystem and to open files and
48
+directories. It presents the filesystem to you in the form of a tree which you
49
+manipulate with the keyboard and/or mouse. It also allows you to perform
50
+simple filesystem operations.
51
+
52
+The following features and functionality are provided by the NERD tree:
53
+    * Files and directories are displayed in a hierarchical tree structure
54
+    * Different highlighting is provided for the following types of nodes:
55
+        * files
56
+        * directories
57
+        * sym-links
58
+        * windows .lnk files
59
+        * read-only files
60
+        * executable files
61
+    * Many (customisable) mappings are provided to manipulate the tree:
62
+        * Mappings to open/close/explore directory nodes
63
+        * Mappings to open files in new/existing windows/tabs
64
+        * Mappings to change the current root of the tree
65
+        * Mappings to navigate around the tree
66
+        * ...
67
+    * Directories and files can be bookmarked.
68
+    * Most NERD tree navigation can also be done with the mouse
69
+    * Filtering of tree content (can be toggled at runtime)
70
+        * custom file filters to prevent e.g. vim backup files being displayed
71
+        * optional displaying of hidden files (. files)
72
+        * files can be "turned off" so that only directories are displayed
73
+    * The position and size of the NERD tree window can be customised
74
+    * The order in which the nodes in the tree are listed can be customised.
75
+    * A model of your filesystem is created/maintained as you explore it. This
76
+      has several advantages:
77
+        * All filesystem information is cached and is only re-read on demand
78
+        * If you revisit a part of the tree that you left earlier in your
79
+          session, the directory nodes will be opened/closed as you left them
80
+    * The script remembers the cursor position and window position in the NERD
81
+      tree so you can toggle it off (or just close the tree window) and then
82
+      reopen it (with NERDTreeToggle) the NERD tree window will appear exactly
83
+      as you left it
84
+    * You can have a separate NERD tree for each tab, share trees across tabs,
85
+      or a mix of both.
86
+    * By default the script overrides the default file browser (netw), so if
87
+      you :edit a directory a (slighly modified) NERD tree will appear in the
88
+      current window
89
+    * A programmable menu system is provided (simulates right clicking on a
90
+      node)
91
+        * one default menu plugin is provided to perform basic filesytem
92
+          operations (create/delete/move/copy files/directories)
93
+    * There's an API for adding your own keymappings
94
+
95
+
96
+==============================================================================
97
+2. Functionality provided                              *NERDTreeFunctionality*
98
+
99
+------------------------------------------------------------------------------
100
+2.1. Global Commands                                  *NERDTreeGlobalCommands*
101
+
102
+:NERDTree [<start-directory> | <bookmark>]                         *:NERDTree*
103
+    Opens a fresh NERD tree. The root of the tree depends on the argument
104
+    given. There are 3 cases: If no argument is given, the current directory
105
+    will be used.  If a directory is given, that will be used. If a bookmark
106
+    name is given, the corresponding directory will be used.  For example: >
107
+        :NERDTree /home/marty/vim7/src
108
+        :NERDTree foo   (foo is the name of a bookmark)
109
+<
110
+:NERDTreeFromBookmark <bookmark>                       *:NERDTreeFromBookmark*
111
+    Opens a fresh NERD tree with the root initialized to the dir for
112
+    <bookmark>.  This only reason to use this command over :NERDTree is for
113
+    the completion (which is for bookmarks rather than directories).
114
+
115
+:NERDTreeToggle [<start-directory> | <bookmark>]             *:NERDTreeToggle*
116
+    If a NERD tree already exists for this tab, it is reopened and rendered
117
+    again.  If no NERD tree exists for this tab then this command acts the
118
+    same as the |:NERDTree| command.
119
+
120
+:NERDTreeMirror                                              *:NERDTreeMirror*
121
+    Shares an existing NERD tree, from another tab, in the current tab.
122
+    Changes made to one tree are reflected in both as they are actually the
123
+    same buffer.
124
+
125
+    If only one other NERD tree exists, that tree is automatically mirrored. If
126
+    more than one exists, the script will ask which tree to mirror.
127
+
128
+:NERDTreeClose                                                *:NERDTreeClose*
129
+    Close the NERD tree in this tab.
130
+
131
+:NERDTreeFind                                                  *:NERDTreeFind*
132
+    Find the current file in the tree.
133
+
134
+    If not tree exists and the current file is under vim's CWD, then init a
135
+    tree at the CWD and reveal the file. Otherwise init a tree in the current
136
+    file's directory.
137
+
138
+    In any case, the current file is revealed and the cursor is placed on it.
139
+
140
+:NERDTreeCWD                                                    *:NERDTreeCWD*
141
+    Change tree root to current directory. If no NERD tree exists for this
142
+    tab, a new tree will be opened.
143
+
144
+------------------------------------------------------------------------------
145
+2.2. Bookmarks                                             *NERDTreeBookmarks*
146
+
147
+Bookmarks in the NERD tree are a way to tag files or directories of interest.
148
+For example, you could use bookmarks to tag all of your project directories.
149
+
150
+------------------------------------------------------------------------------
151
+2.2.1. The Bookmark Table                              *NERDTreeBookmarkTable*
152
+
153
+If the bookmark table is active (see |NERDTree-B| and
154
+|'NERDTreeShowBookmarks'|), it will be rendered above the tree. You can double
155
+click bookmarks or use the |NERDTree-o| mapping to activate them. See also,
156
+|NERDTree-t| and |NERDTree-T|
157
+
158
+------------------------------------------------------------------------------
159
+2.2.2. Bookmark commands                            *NERDTreeBookmarkCommands*
160
+
161
+Note that the following commands are only available in the NERD tree buffer.
162
+
163
+:Bookmark <name>
164
+    Bookmark the current node as <name>. If there is already a <name>
165
+    bookmark, it is overwritten. <name> must not contain spaces.
166
+    If <name> is not provided, it defaults to the file or directory name.
167
+    For directories, a trailing slash is present.
168
+
169
+:BookmarkToRoot <bookmark>
170
+    Make the directory corresponding to <bookmark> the new root. If a treenode
171
+    corresponding to <bookmark> is already cached somewhere in the tree then
172
+    the current tree will be used, otherwise a fresh tree will be opened.
173
+    Note that if <bookmark> points to a file then its parent will be used
174
+    instead.
175
+
176
+:RevealBookmark <bookmark>
177
+    If the node is cached under the current root then it will be revealed
178
+    (i.e. directory nodes above it will be opened) and the cursor will be
179
+    placed on it.
180
+
181
+:OpenBookmark <bookmark>
182
+    <bookmark> must point to a file. The file is opened as though |NERDTree-o|
183
+    was applied. If the node is cached under the current root then it will be
184
+    revealed and the cursor will be placed on it.
185
+
186
+:ClearBookmarks [<bookmarks>]
187
+    Remove all the given bookmarks. If no bookmarks are given then remove all
188
+    bookmarks on the current node.
189
+
190
+:ClearAllBookmarks
191
+    Remove all bookmarks.
192
+
193
+:ReadBookmarks
194
+    Re-read the bookmarks in the |'NERDTreeBookmarksFile'|.
195
+
196
+See also |:NERDTree| and |:NERDTreeFromBookmark|.
197
+
198
+------------------------------------------------------------------------------
199
+2.2.3. Invalid Bookmarks                            *NERDTreeInvalidBookmarks*
200
+
201
+If invalid bookmarks are detected, the script will issue an error message and
202
+the invalid bookmarks will become unavailable for use.
203
+
204
+These bookmarks will still be stored in the bookmarks file (see
205
+|'NERDTreeBookmarksFile'|), down the bottom. There will always be a blank line
206
+after the valid bookmarks but before the invalid ones.
207
+
208
+Each line in the bookmarks file represents one bookmark. The proper format is:
209
+<bookmark name><space><full path to the bookmark location>
210
+
211
+After you have corrected any invalid bookmarks, either restart vim, or go
212
+:ReadBookmarks from the NERD tree window.
213
+
214
+------------------------------------------------------------------------------
215
+2.3. NERD tree Mappings                                     *NERDTreeMappings*
216
+
217
+Default  Description~                                             help-tag~
218
+Key~
219
+
220
+o.......Open files, directories and bookmarks....................|NERDTree-o|
221
+go......Open selected file, but leave cursor in the NERDTree.....|NERDTree-go|
222
+t.......Open selected node/bookmark in a new tab.................|NERDTree-t|
223
+T.......Same as 't' but keep the focus on the current tab........|NERDTree-T|
224
+i.......Open selected file in a split window.....................|NERDTree-i|
225
+gi......Same as i, but leave the cursor on the NERDTree..........|NERDTree-gi|
226
+s.......Open selected file in a new vsplit.......................|NERDTree-s|
227
+gs......Same as s, but leave the cursor on the NERDTree..........|NERDTree-gs|
228
+O.......Recursively open the selected directory..................|NERDTree-O|
229
+x.......Close the current nodes parent...........................|NERDTree-x|
230
+X.......Recursively close all children of the current node.......|NERDTree-X|
231
+e.......Edit the current dif.....................................|NERDTree-e|
232
+
233
+<CR>...............same as |NERDTree-o|.
234
+double-click.......same as the |NERDTree-o| map.
235
+middle-click.......same as |NERDTree-i| for files, same as
236
+                   |NERDTree-e| for dirs.
237
+
238
+D.......Delete the current bookmark .............................|NERDTree-D|
239
+
240
+P.......Jump to the root node....................................|NERDTree-P|
241
+p.......Jump to current nodes parent.............................|NERDTree-p|
242
+K.......Jump up inside directories at the current tree depth.....|NERDTree-K|
243
+J.......Jump down inside directories at the current tree depth...|NERDTree-J|
244
+<C-J>...Jump down to the next sibling of the current directory...|NERDTree-C-J|
245
+<C-K>...Jump up to the previous sibling of the current directory.|NERDTree-C-K|
246
+
247
+C.......Change the tree root to the selected dir.................|NERDTree-C|
248
+u.......Move the tree root up one directory......................|NERDTree-u|
249
+U.......Same as 'u' except the old root node is left open........|NERDTree-U|
250
+r.......Recursively refresh the current directory................|NERDTree-r|
251
+R.......Recursively refresh the current root.....................|NERDTree-R|
252
+m.......Display the NERD tree menu...............................|NERDTree-m|
253
+cd......Change the CWD to the dir of the selected node...........|NERDTree-cd|
254
+CD......Change tree root to the CWD..............................|NERDTree-CD|
255
+
256
+I.......Toggle whether hidden files displayed....................|NERDTree-I|
257
+f.......Toggle whether the file filters are used.................|NERDTree-f|
258
+F.......Toggle whether files are displayed.......................|NERDTree-F|
259
+B.......Toggle whether the bookmark table is displayed...........|NERDTree-B|
260
+
261
+q.......Close the NERDTree window................................|NERDTree-q|
262
+A.......Zoom (maximize/minimize) the NERDTree window.............|NERDTree-A|
263
+?.......Toggle the display of the quick help.....................|NERDTree-?|
264
+
265
+------------------------------------------------------------------------------
266
+                                                                  *NERDTree-o*
267
+Default key: o
268
+Map option: NERDTreeMapActivateNode
269
+Applies to: files and directories.
270
+
271
+If a file node is selected, it is opened in the previous window.
272
+
273
+If a directory is selected it is opened or closed depending on its current
274
+state.
275
+
276
+If a bookmark that links to a directory is selected then that directory
277
+becomes the new root.
278
+
279
+If a bookmark that links to a file is selected then that file is opened in the
280
+previous window.
281
+
282
+------------------------------------------------------------------------------
283
+                                                                 *NERDTree-go*
284
+Default key: go
285
+Map option: None
286
+Applies to: files.
287
+
288
+If a file node is selected, it is opened in the previous window, but the
289
+cursor does not move.
290
+
291
+The key combo for this mapping is always "g" + NERDTreeMapActivateNode (see
292
+|NERDTree-o|).
293
+
294
+------------------------------------------------------------------------------
295
+                                                                  *NERDTree-t*
296
+Default key: t
297
+Map option: NERDTreeMapOpenInTab
298
+Applies to: files and directories.
299
+
300
+Opens the selected file in a new tab. If a directory is selected, a fresh
301
+NERD Tree for that directory is opened in a new tab.
302
+
303
+If a bookmark which points to a directory is selected, open a NERD tree for
304
+that directory in a new tab. If the bookmark points to a file, open that file
305
+in a new tab.
306
+
307
+------------------------------------------------------------------------------
308
+                                                                  *NERDTree-T*
309
+Default key: T
310
+Map option: NERDTreeMapOpenInTabSilent
311
+Applies to: files and directories.
312
+
313
+The same as |NERDTree-t| except that the focus is kept in the current tab.
314
+
315
+------------------------------------------------------------------------------
316
+                                                                  *NERDTree-i*
317
+Default key: i
318
+Map option: NERDTreeMapOpenSplit
319
+Applies to: files.
320
+
321
+Opens the selected file in a new split window and puts the cursor in the new
322
+window.
323
+
324
+------------------------------------------------------------------------------
325
+                                                                 *NERDTree-gi*
326
+Default key: gi
327
+Map option: None
328
+Applies to: files.
329
+
330
+The same as |NERDTree-i| except that the cursor is not moved.
331
+
332
+The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see
333
+|NERDTree-i|).
334
+
335
+------------------------------------------------------------------------------
336
+                                                                  *NERDTree-s*
337
+Default key: s
338
+Map option: NERDTreeMapOpenVSplit
339
+Applies to: files.
340
+
341
+Opens the selected file in a new vertically split window and puts the cursor in
342
+the new window.
343
+
344
+------------------------------------------------------------------------------
345
+                                                                 *NERDTree-gs*
346
+Default key: gs
347
+Map option: None
348
+Applies to: files.
349
+
350
+The same as |NERDTree-s| except that the cursor is not moved.
351
+
352
+The key combo for this mapping is always "g" + NERDTreeMapOpenVSplit (see
353
+|NERDTree-s|).
354
+
355
+------------------------------------------------------------------------------
356
+                                                                  *NERDTree-O*
357
+Default key: O
358
+Map option: NERDTreeMapOpenRecursively
359
+Applies to: directories.
360
+
361
+Recursively opens the selelected directory.
362
+
363
+All files and directories are cached, but if a directory would not be
364
+displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the
365
+hidden file filter (see |'NERDTreeShowHidden'|) then its contents are not
366
+cached. This is handy, especially if you have .svn directories.
367
+
368
+------------------------------------------------------------------------------
369
+                                                                  *NERDTree-x*
370
+Default key: x
371
+Map option: NERDTreeMapCloseDir
372
+Applies to: files and directories.
373
+
374
+Closes the parent of the selected node.
375
+
376
+------------------------------------------------------------------------------
377
+                                                                  *NERDTree-X*
378
+Default key: X
379
+Map option: NERDTreeMapCloseChildren
380
+Applies to: directories.
381
+
382
+Recursively closes all children of the selected directory.
383
+
384
+Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping.
385
+
386
+------------------------------------------------------------------------------
387
+                                                                  *NERDTree-e*
388
+Default key: e
389
+Map option: NERDTreeMapOpenExpl
390
+Applies to: files and directories.
391
+
392
+|:edit|s the selected directory, or the selected file's directory. This could
393
+result in a NERD tree or a netrw being opened, depending on
394
+|'NERDTreeHijackNetrw'|.
395
+
396
+------------------------------------------------------------------------------
397
+                                                                  *NERDTree-D*
398
+Default key: D
399
+Map option: NERDTreeMapDeleteBookmark
400
+Applies to: lines in the bookmarks table
401
+
402
+Deletes the currently selected bookmark.
403
+
404
+------------------------------------------------------------------------------
405
+                                                                  *NERDTree-P*
406
+Default key: P
407
+Map option: NERDTreeMapJumpRoot
408
+Applies to: no restrictions.
409
+
410
+Jump to the tree root.
411
+
412
+------------------------------------------------------------------------------
413
+                                                                  *NERDTree-p*
414
+Default key: p
415
+Map option: NERDTreeMapJumpParent
416
+Applies to: files and directories.
417
+
418
+Jump to the parent node of the selected node.
419
+
420
+------------------------------------------------------------------------------
421
+                                                                  *NERDTree-K*
422
+Default key: K
423
+Map option: NERDTreeMapJumpFirstChild
424
+Applies to: files and directories.
425
+
426
+Jump to the first child of the current nodes parent.
427
+
428
+If the cursor is already on the first node then do the following:
429
+    * loop back thru the siblings of the current nodes parent until we find an
430
+      open dir with children
431
+    * go to the first child of that node
432
+
433
+------------------------------------------------------------------------------
434
+                                                                  *NERDTree-J*
435
+Default key: J
436
+Map option: NERDTreeMapJumpLastChild
437
+Applies to: files and directories.
438
+
439
+Jump to the last child of the current nodes parent.
440
+
441
+If the cursor is already on the last node then do the following:
442
+    * loop forward thru the siblings of the current nodes parent until we find
443
+      an open dir with children
444
+    * go to the last child of that node
445
+
446
+------------------------------------------------------------------------------
447
+                                                                *NERDTree-C-J*
448
+Default key: <C-J>
449
+Map option: NERDTreeMapJumpNextSibling
450
+Applies to: files and directories.
451
+
452
+Jump to the next sibling of the selected node.
453
+
454
+------------------------------------------------------------------------------
455
+                                                                *NERDTree-C-K*
456
+Default key: <C-K>
457
+Map option: NERDTreeMapJumpPrevSibling
458
+Applies to: files and directories.
459
+
460
+Jump to the previous sibling of the selected node.
461
+
462
+------------------------------------------------------------------------------
463
+                                                                  *NERDTree-C*
464
+Default key: C
465
+Map option: NERDTreeMapChdir
466
+Applies to: directories.
467
+
468
+Make the selected directory node the new tree root. If a file is selected, its
469
+parent is used.
470
+
471
+------------------------------------------------------------------------------
472
+                                                                  *NERDTree-u*
473
+Default key: u
474
+Map option: NERDTreeMapUpdir
475
+Applies to: no restrictions.
476
+
477
+Move the tree root up a dir (like doing a "cd ..").
478
+
479
+------------------------------------------------------------------------------
480
+                                                                  *NERDTree-U*
481
+Default key: U
482
+Map option: NERDTreeMapUpdirKeepOpen
483
+Applies to: no restrictions.
484
+
485
+Like |NERDTree-u| except that the old tree root is kept open.
486
+
487
+------------------------------------------------------------------------------
488
+                                                                  *NERDTree-r*
489
+Default key: r
490
+Map option: NERDTreeMapRefresh
491
+Applies to: files and directories.
492
+
493
+If a dir is selected, recursively refresh that dir, i.e. scan the filesystem
494
+for changes and represent them in the tree.
495
+
496
+If a file node is selected then the above is done on it's parent.
497
+
498
+------------------------------------------------------------------------------
499
+                                                                  *NERDTree-R*
500
+Default key: R
501
+Map option: NERDTreeMapRefreshRoot
502
+Applies to: no restrictions.
503
+
504
+Recursively refresh the tree root.
505
+
506
+------------------------------------------------------------------------------
507
+                                                                  *NERDTree-m*
508
+Default key: m
509
+Map option: NERDTreeMapMenu
510
+Applies to: files and directories.
511
+
512
+Display the NERD tree menu. See |NERDTreeMenu| for details.
513
+
514
+------------------------------------------------------------------------------
515
+                                                                 *NERDTree-cd*
516
+Default key: cd
517
+Map option: NERDTreeMapChdir
518
+Applies to: files and directories.
519
+
520
+Change vims current working directory to that of the selected node.
521
+
522
+------------------------------------------------------------------------------
523
+                                                                 *NERDTree-CD*
524
+Default key: CD
525
+Map option: NERDTreeMapCWD
526
+Applies to: no restrictions.
527
+
528
+Change tree root to vims current working directory.
529
+
530
+------------------------------------------------------------------------------
531
+                                                                  *NERDTree-I*
532
+Default key: I
533
+Map option: NERDTreeMapToggleHidden
534
+Applies to: no restrictions.
535
+
536
+Toggles whether hidden files (i.e. "dot files") are displayed.
537
+
538
+------------------------------------------------------------------------------
539
+                                                                  *NERDTree-f*
540
+Default key: f
541
+Map option: NERDTreeMapToggleFilters
542
+Applies to: no restrictions.
543
+
544
+Toggles whether file filters are used. See |'NERDTreeIgnore'| for details.
545
+
546
+------------------------------------------------------------------------------
547
+                                                                  *NERDTree-F*
548
+Default key: F
549
+Map option: NERDTreeMapToggleFiles
550
+Applies to: no restrictions.
551
+
552
+Toggles whether file nodes are displayed.
553
+
554
+------------------------------------------------------------------------------
555
+                                                                  *NERDTree-B*
556
+Default key: B
557
+Map option: NERDTreeMapToggleBookmarks
558
+Applies to: no restrictions.
559
+
560
+Toggles whether the bookmarks table is displayed.
561
+
562
+------------------------------------------------------------------------------
563
+                                                                  *NERDTree-q*
564
+Default key: q
565
+Map option: NERDTreeMapQuit
566
+Applies to: no restrictions.
567
+
568
+Closes the NERDtree window.
569
+
570
+------------------------------------------------------------------------------
571
+                                                                  *NERDTree-A*
572
+Default key: A
573
+Map option: NERDTreeMapToggleZoom
574
+Applies to: no restrictions.
575
+
576
+Maximize (zoom) and minimize the NERDtree window.
577
+
578
+------------------------------------------------------------------------------
579
+                                                                  *NERDTree-?*
580
+Default key: ?
581
+Map option: NERDTreeMapHelp
582
+Applies to: no restrictions.
583
+
584
+Toggles whether the quickhelp is displayed.
585
+
586
+------------------------------------------------------------------------------
587
+2.3. The NERD tree menu                                         *NERDTreeMenu*
588
+
589
+The NERD tree has a menu that can be programmed via the an API (see
590
+|NERDTreeMenuAPI|). The idea is to simulate the "right click" menus that most
591
+file explorers have.
592
+
593
+The script comes with two default menu plugins: exec_menuitem.vim and
594
+fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for
595
+creating/deleting/moving/copying files and dirs. exec_menuitem.vim provides a
596
+menu item to execute executable files.
597
+
598
+Related tags: |NERDTree-m| |NERDTreeApi|
599
+
600
+==============================================================================
601
+3. Customisation                                             *NERDTreeOptions*
602
+
603
+
604
+------------------------------------------------------------------------------
605
+3.1. Customisation summary                             *NERDTreeOptionSummary*
606
+
607
+The script provides the following options that can customise the behaviour the
608
+NERD tree. These options should be set in your vimrc.
609
+
610
+|'loaded_nerd_tree'|            Turns off the script.
611
+
612
+|'NERDChristmasTree'|           Tells the NERD tree to make itself colourful
613
+                                and pretty.
614
+
615
+|'NERDTreeAutoCenter'|          Controls whether the NERD tree window centers
616
+                                when the cursor moves within a specified
617
+                                distance to the top/bottom of the window.
618
+|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering.
619
+
620
+|'NERDTreeCaseSensitiveSort'|   Tells the NERD tree whether to be case
621
+                                sensitive or not when sorting nodes.
622
+
623
+|'NERDTreeChDirMode'|           Tells the NERD tree if/when it should change
624
+                                vim's current working directory.
625
+
626
+|'NERDTreeHighlightCursorline'| Tell the NERD tree whether to highlight the
627
+                                current cursor line.
628
+
629
+|'NERDTreeHijackNetrw'|         Tell the NERD tree whether to replace the netrw
630
+                                autocommands for exploring local directories.
631
+
632
+|'NERDTreeIgnore'|              Tells the NERD tree which files to ignore.
633
+
634
+|'NERDTreeBookmarksFile'|       Where the bookmarks are stored.
635
+
636
+|'NERDTreeMouseMode'|           Tells the NERD tree how to handle mouse
637
+                                clicks.
638
+
639
+|'NERDTreeQuitOnOpen'|          Closes the tree window after opening a file.
640
+
641
+|'NERDTreeShowBookmarks'|       Tells the NERD tree whether to display the
642
+                                bookmarks table on startup.
643
+
644
+|'NERDTreeShowFiles'|           Tells the NERD tree whether to display files
645
+                                in the tree on startup.
646
+
647
+|'NERDTreeShowHidden'|          Tells the NERD tree whether to display hidden
648
+                                files on startup.
649
+
650
+|'NERDTreeShowLineNumbers'|     Tells the NERD tree whether to display line
651
+                                numbers in the tree window.
652
+
653
+|'NERDTreeSortOrder'|           Tell the NERD tree how to sort the nodes in
654
+                                the tree.
655
+
656
+|'NERDTreeStatusline'|          Set a statusline for NERD tree windows.
657
+
658
+|'NERDTreeWinPos'|              Tells the script where to put the NERD tree
659
+                                window.
660
+
661
+|'NERDTreeWinSize'|             Sets the window size when the NERD tree is
662
+                                opened.
663
+
664
+|'NERDTreeMinimalUI'|           Disables display of the 'Bookmarks' label and 
665
+                                'Press ? for help' text.
666
+
667
+|'NERDTreeDirArrows'|           Tells the NERD tree to use arrows instead of
668
+                                + ~ chars when displaying directories.
669
+
670
+|'NERDTreeCasadeOpenSingleChildDir'|
671
+                                Casade open while selected directory has only
672
+                                one child that also is a directory.
673
+
674
+|'NERDTreeAutoDeleteBuffer'|    Tells the NERD tree to automatically remove 
675
+                                a buffer when a file is being deleted or renamed
676
+                                via a context menu command.
677
+
678
+------------------------------------------------------------------------------
679
+3.2. Customisation details                             *NERDTreeOptionDetails*
680
+
681
+To enable any of the below options you should put the given line in your
682
+~/.vimrc
683
+
684
+                                                          *'loaded_nerd_tree'*
685
+If this plugin is making you feel homicidal, it may be a good idea to turn it
686
+off with this line in your vimrc: >
687
+    let loaded_nerd_tree=1
688
+<
689
+------------------------------------------------------------------------------
690
+                                                         *'NERDChristmasTree'*
691
+Values: 0 or 1.
692
+Default: 1.
693
+
694
+If this option is set to 1 then some extra syntax highlighting elements are
695
+added to the nerd tree to make it more colourful.
696
+
697
+Set it to 0 for a more vanilla looking tree.
698
+
699
+------------------------------------------------------------------------------
700
+                                                        *'NERDTreeAutoCenter'*
701
+Values: 0 or 1.
702
+Default: 1
703
+
704
+If set to 1, the NERD tree window will center around the cursor if it moves to
705
+within |'NERDTreeAutoCenterThreshold'| lines of the top/bottom of the window.
706
+
707
+This is ONLY done in response to tree navigation mappings,
708
+i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-C-K| |NERDTree-p|
709
+|NERDTree-P|
710
+
711
+The centering is done with a |zz| operation.
712
+
713
+------------------------------------------------------------------------------
714
+                                               *'NERDTreeAutoCenterThreshold'*
715
+Values: Any natural number.
716
+Default: 3
717
+
718
+This option controls the "sensitivity" of the NERD tree auto centering. See
719
+|'NERDTreeAutoCenter'| for details.
720
+
721
+------------------------------------------------------------------------------
722
+                                                 *'NERDTreeCaseSensitiveSort'*
723
+Values: 0 or 1.
724
+Default: 0.
725
+
726
+By default the NERD tree does not sort nodes case sensitively, i.e. nodes
727
+could appear like this: >
728
+    bar.c
729
+    Baz.c
730
+    blarg.c
731
+    boner.c
732
+    Foo.c
733
+<
734
+But, if you set this option to 1 then the case of the nodes will be taken into
735
+account. The above nodes would then be sorted like this: >
736
+    Baz.c
737
+    Foo.c
738
+    bar.c
739
+    blarg.c
740
+    boner.c
741
+<
742
+------------------------------------------------------------------------------
743
+                                                         *'NERDTreeChDirMode'*
744
+
745
+Values: 0, 1 or 2.
746
+Default: 0.
747
+
748
+Use this option to tell the script when (if at all) to change the current
749
+working directory (CWD) for vim.
750
+
751
+If it is set to 0 then the CWD is never changed by the NERD tree.
752
+
753
+If set to 1 then the CWD is changed when the NERD tree is first loaded to the
754
+directory it is initialized in. For example, if you start the NERD tree with >
755
+    :NERDTree /home/marty/foobar
756
+<
757
+then the CWD will be changed to /home/marty/foobar and will not be changed
758
+again unless you init another NERD tree with a similar command.
759
+
760
+If the option is set to 2 then it behaves the same as if set to 1 except that
761
+the CWD is changed whenever the tree root is changed. For example, if the CWD
762
+is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new
763
+root then the CWD will become /home/marty/foobar/baz.
764
+
765
+------------------------------------------------------------------------------
766
+                                               *'NERDTreeHighlightCursorline'*
767
+Values: 0 or 1.
768
+Default: 1.
769
+
770
+If set to 1, the current cursor line in the NERD tree buffer will be
771
+highlighted. This is done using the |'cursorline'| option.
772
+
773
+------------------------------------------------------------------------------
774
+                                                       *'NERDTreeHijackNetrw'*
775
+Values: 0 or 1.
776
+Default: 1.
777
+
778
+If set to 1, doing a >
779
+    :edit <some directory>
780
+<
781
+will open up a "secondary" NERD tree instead of a netrw in the target window.
782
+
783
+Secondary NERD trees behaves slighly different from a regular trees in the
784
+following respects:
785
+    1. 'o' will open the selected file in the same window as the tree,
786
+       replacing it.
787
+    2. you can have as many secondary tree as you want in the same tab.
788
+
789
+------------------------------------------------------------------------------
790
+                                                            *'NERDTreeIgnore'*
791
+Values: a list of regular expressions.
792
+Default: ['\~$'].
793
+
794
+This option is used to specify which files the NERD tree should ignore.  It
795
+must be a list of regular expressions. When the NERD tree is rendered, any
796
+files/dirs that match any of the regex's in 'NERDTreeIgnore' wont be
797
+displayed.
798
+
799
+For example if you put the following line in your vimrc: >
800
+    let NERDTreeIgnore=['\.vim$', '\~$']
801
+<
802
+then all files ending in .vim or ~ will be ignored.
803
+
804
+There are 2 magic flags that can be appended to the end of each regular
805
+expression to specify that the regex should match only files or only dirs.
806
+These flags are "[[dir]]" and "[[file]]". Example: >
807
+    let NERDTreeIgnore=['.d$[[dir]]', '.o$[[file]]']
808
+<
809
+This will cause all dirs ending in ".d" to be ignored and all files ending in
810
+".o" to be ignored.
811
+
812
+Note: to tell the NERD tree not to ignore any files you must use the following
813
+line: >
814
+    let NERDTreeIgnore=[]
815
+<
816
+
817
+The file filters can be turned on and off dynamically with the |NERDTree-f|
818
+mapping.
819
+
820
+------------------------------------------------------------------------------
821
+                                                     *'NERDTreeBookmarksFile'*
822
+Values: a path
823
+Default: $HOME/.NERDTreeBookmarks
824
+
825
+This is where bookmarks are saved. See |NERDTreeBookmarkCommands|.
826
+
827
+------------------------------------------------------------------------------
828
+                                                       *'NERDTreeMouseMode'*
829
+Values: 1, 2 or 3.
830
+Default: 1.
831
+
832
+If set to 1 then a double click on a node is required to open it.
833
+If set to 2 then a single click will open directory nodes, while a double
834
+click will still be required for file nodes.
835
+If set to 3 then a single click will open any node.
836
+
837
+Note: a double click anywhere on a line that a tree node is on will
838
+activate it, but all single-click activations must be done on name of the node
839
+itself. For example, if you have the following node: >
840
+    | | |-application.rb
841
+<
842
+then (to single click activate it) you must click somewhere in
843
+'application.rb'.
844
+
845
+------------------------------------------------------------------------------
846
+                                                        *'NERDTreeQuitOnOpen'*
847
+
848
+Values: 0 or 1.
849
+Default: 0
850
+
851
+If set to 1, the NERD tree window will close after opening a file with the
852
+|NERDTree-o|, |NERDTree-i|, |NERDTree-t| and |NERDTree-T| mappings.
853
+
854
+------------------------------------------------------------------------------
855
+                                                     *'NERDTreeShowBookmarks'*
856
+Values: 0 or 1.
857
+Default: 0.
858
+
859
+If this option is set to 1 then the bookmarks table will be displayed.
860
+
861
+This option can be toggled dynamically, per tree, with the |NERDTree-B|
862
+mapping.
863
+
864
+------------------------------------------------------------------------------
865
+                                                         *'NERDTreeShowFiles'*
866
+Values: 0 or 1.
867
+Default: 1.
868
+
869
+If this option is set to 1 then files are displayed in the NERD tree. If it is
870
+set to 0 then only directories are displayed.
871
+
872
+This option can be toggled dynamically, per tree, with the |NERDTree-F|
873
+mapping and is useful for drastically shrinking the tree when you are
874
+navigating to a different part of the tree.
875
+
876
+------------------------------------------------------------------------------
877
+                                                        *'NERDTreeShowHidden'*
878
+Values: 0 or 1.
879
+Default: 0.
880
+
881
+This option tells vim whether to display hidden files by default. This option
882
+can be dynamically toggled, per tree, with the |NERDTree-I| mapping.  Use one
883
+of the follow lines to set this option: >
884
+    let NERDTreeShowHidden=0
885
+    let NERDTreeShowHidden=1
886
+<
887
+
888
+------------------------------------------------------------------------------
889
+                                                   *'NERDTreeShowLineNumbers'*
890
+Values: 0 or 1.
891
+Default: 0.
892
+
893
+This option tells vim whether to display line numbers for the NERD tree
894
+window.  Use one of the follow lines to set this option: >
895
+    let NERDTreeShowLineNumbers=0
896
+    let NERDTreeShowLineNumbers=1
897
+<
898
+
899
+------------------------------------------------------------------------------
900
+                                                         *'NERDTreeSortOrder'*
901
+Values: a list of regular expressions.
902
+Default: ['\/$', '*', '\.swp$',  '\.bak$', '\~$']
903
+
904
+This option is set to a list of regular expressions which are used to
905
+specify the order of nodes under their parent.
906
+
907
+For example, if the option is set to: >
908
+    ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
909
+<
910
+then all .vim files will be placed at the top, followed by all .c files then
911
+all .h files. All files containing the string 'foobar' will be placed at the
912
+end.  The star is a special flag: it tells the script that every node that
913
+doesnt match any of the other regexps should be placed here.
914
+
915
+If no star is present in 'NERDTreeSortOrder' then one is automatically
916
+appended to the array.
917
+
918
+The regex '\/$' should be used to match directory nodes.
919
+
920
+After this sorting is done, the files in each group are sorted alphabetically.
921
+
922
+Other examples: >
923
+    (1) ['*', '\/$']
924
+    (2) []
925
+    (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$',  '\.bak$', '\~$']
926
+<
927
+1. Directories will appear last, everything else will appear above.
928
+2. Everything will simply appear in alphabetical order.
929
+3. Dirs will appear first, then ruby and php. Swap files, bak files and vim
930
+   backup files will appear last with everything else preceding them.
931
+
932
+------------------------------------------------------------------------------
933
+                                                        *'NERDTreeStatusline'*
934
+Values: Any valid statusline setting.
935
+Default: %{b:NERDTreeRoot.path.strForOS(0)}
936
+
937
+Tells the script what to use as the |'statusline'| setting for NERD tree
938
+windows.
939
+
940
+Note that the statusline is set using |:let-&| not |:set| so escaping spaces
941
+isn't necessary.
942
+
943
+Setting this option to -1 will will deactivate it so that your global
944
+statusline setting is used instead.
945
+
946
+------------------------------------------------------------------------------
947
+                                                            *'NERDTreeWinPos'*
948
+Values: "left" or "right"
949
+Default: "left".
950
+
951
+This option is used to determine where NERD tree window is placed on the
952
+screen.
953
+
954
+This option makes it possible to use two different explorer plugins
955
+simultaneously. For example, you could have the taglist plugin on the left of
956
+the window and the NERD tree on the right.
957
+
958
+------------------------------------------------------------------------------
959
+                                                           *'NERDTreeWinSize'*
960
+Values: a positive integer.
961
+Default: 31.
962
+
963
+This option is used to change the size of the NERD tree when it is loaded.
964
+
965
+------------------------------------------------------------------------------
966
+                                                         *'NERDTreeMinimalUI'*
967
+Values: 0 or 1
968
+Default: 0
969
+
970
+This options disables the 'Bookmarks' label 'Press ? for help' text. Use one
971
+of the following lines to set this option: >
972
+    let NERDTreeMinimalUI=0
973
+    let NERDTreeMinimalUI=1
974
+<
975
+
976
+------------------------------------------------------------------------------
977
+                                                           *'NERDTreeDirArrows'*
978
+Values: 0 or 1
979
+Default: 0.
980
+
981
+This option is used to change the default look of directory nodes displayed in
982
+the tree. When set to 0 it shows old-school bars (|), + and ~ chars. If set to
983
+1 it shows right and down arrows.  Use one of the follow lines to set this
984
+option: >
985
+    let NERDTreeDirArrows=0
986
+    let NERDTreeDirArrows=1
987
+<
988
+
989
+------------------------------------------------------------------------------
990
+                                          *'NERDTreeCasadeOpenSingleChildDir'*
991
+Values: 0 or 1
992
+Default: 1.
993
+
994
+When opening dir nodes, this option tells NERDTree to recursively open dirs
995
+that have only one child which is also a dir. NERDTree will stop when it finds
996
+a dir that contains anything but another single dir. This option may be useful
997
+for Java projects.  Use one of the follow lines to set this option: >
998
+    let NERDTreeCasadeOpenSingleChildDir=0
999
+    let NERDTreeCasadeOpenSingleChildDir=1
1000
+<
1001
+
1002
+------------------------------------------------------------------------------
1003
+                                          *'NERDTreeAutoDeleteBuffer'*
1004
+Values: 0 or 1
1005
+Default: 0.
1006
+
1007
+When using a context menu to delete or rename a file you may also want to delete
1008
+the buffer which is no more valid. If the option is not set you will see a
1009
+confirmation if you really want to delete an old buffer. If you always press 'y'
1010
+then it worths to set this option to 1. Use one of the follow lines to set this
1011
+option: >
1012
+    let NERDTreeAutoDeleteBuffer=0
1013
+    let NERDTreeAutoDeleteBuffer=1
1014
+<
1015
+
1016
+==============================================================================
1017
+4. The NERD tree API                                             *NERDTreeAPI*
1018
+
1019
+The NERD tree script allows you to add custom key mappings and menu items via
1020
+a set of API calls. Any scripts that use this API should be placed in
1021
+~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows).
1022
+
1023
+The script exposes some prototype objects that can be used to manipulate the
1024
+tree and/or get information from it: >
1025
+    g:NERDTreePath
1026
+    g:NERDTreeDirNode
1027
+    g:NERDTreeFileNode
1028
+    g:NERDTreeBookmark
1029
+<
1030
+See the code/comments in NERD_tree.vim to find how to use these objects. The
1031
+following code conventions are used:
1032
+    * class members start with a capital letter
1033
+    * instance members start with a lower case letter
1034
+    * private members start with an underscore
1035
+
1036
+See this blog post for more details:
1037
+ http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html
1038
+
1039
+------------------------------------------------------------------------------
1040
+4.1. Key map API                                           *NERDTreeKeymapAPI*
1041
+
1042
+NERDTreeAddKeyMap({options})                             *NERDTreeAddKeyMap()*
1043
+    Adds a new keymapping for all NERD tree buffers.
1044
+    {options} must be a dictionary, and must contain the following keys:
1045
+    "key" - the trigger key for the new mapping
1046
+    "callback" - the function the new mapping will be bound to
1047
+    "quickhelpText" - the text that will appear in the quickhelp (see
1048
+    |NERDTree-?|)
1049
+
1050
+    Additionally, a "scope" argument may be supplied. This constrains the
1051
+    mapping so that it is only activated if the cursor is on a certain object.
1052
+    That object is then passed into the handling method. Possible values are:
1053
+        "FileNode" - a file node
1054
+        "DirNode" - a directory node
1055
+        "Node" - a file or directory node
1056
+        "Bookmark" - A bookmark
1057
+        "all" - the keymap is not constrained to any scope (default). When
1058
+        thei is used, the handling function is not passed any arguments.
1059
+
1060
+
1061
+    Example: >
1062
+        call NERDTreeAddKeyMap({
1063
+               \ 'key': 'foo',
1064
+               \ 'callback': 'NERDTreeCDHandler',
1065
+               \ 'quickhelpText': 'echo full path of current node' })
1066
+               \ 'scope': 'DirNode'
1067
+
1068
+        function! NERDTreeCDHandler(dirnode)
1069
+            call a:dirnode.changeToDir()
1070
+        endfunction
1071
+<
1072
+    This code should sit in a file like ~/.vim/nerdtree_plugin/mymapping.vim.
1073
+    It adds a (redundant) mapping on 'foo' which changes vim's CWD to that of
1074
+    the current dir node. Note this mapping will only fire when the cursor is
1075
+    on a directory node.
1076
+
1077
+------------------------------------------------------------------------------
1078
+4.2. Menu API                                                *NERDTreeMenuAPI*
1079
+
1080
+NERDTreeAddSubmenu({options})                           *NERDTreeAddSubmenu()*
1081
+    Creates and returns a new submenu.
1082
+
1083
+    {options} must be a dictionary and must contain the following keys:
1084
+    "text" - the text of the submenu that the user will see
1085
+    "shortcut" - a shortcut key for the submenu (need not be unique)
1086
+
1087
+    The following keys are optional:
1088
+    "isActiveCallback" - a function that will be called to determine whether
1089
+    this submenu item will be displayed or not. The callback function must return
1090
+    0 or 1.
1091
+    "parent" - the parent submenu of the new submenu (returned from a previous
1092
+    invocation of NERDTreeAddSubmenu()). If this key is left out then the new
1093
+    submenu will sit under the top level menu.
1094
+
1095
+    See below for an example.
1096
+
1097
+NERDTreeAddMenuItem({options})                         *NERDTreeAddMenuItem()*
1098
+    Adds a new menu item to the NERD tree menu (see |NERDTreeMenu|).
1099
+
1100
+    {options} must be a dictionary and must contain the
1101
+    following keys:
1102
+    "text" - the text of the menu item which the user will see
1103
+    "shortcut" - a shortcut key for the menu item (need not be unique)
1104
+    "callback" - the function that will be called when the user activates the
1105
+    menu item.
1106
+
1107
+    The following keys are optional:
1108
+    "isActiveCallback" - a function that will be called to determine whether
1109
+    this menu item will be displayed or not. The callback function must return
1110
+    0 or 1.
1111
+    "parent" - if the menu item belongs under a submenu then this key must be
1112
+    specified. This value for this key will be the object that
1113
+    was returned when the submenu was created with |NERDTreeAddSubmenu()|.
1114
+
1115
+    See below for an example.
1116
+
1117
+NERDTreeAddMenuSeparator([{options}])             *NERDTreeAddMenuSeparator()*
1118
+    Adds a menu separator (a row of dashes).
1119
+
1120
+    {options} is an optional dictionary that may contain the following keys:
1121
+    "isActiveCallback" - see description in |NERDTreeAddMenuItem()|.
1122
+
1123
+Below is an example of the menu API in action. >
1124
+    call NERDTreeAddMenuSeparator()
1125
+
1126
+    call NERDTreeAddMenuItem({
1127
+                \ 'text': 'a (t)op level menu item',
1128
+                \ 'shortcut': 't',
1129
+                \ 'callback': 'SomeFunction' })
1130
+
1131
+    let submenu = NERDTreeAddSubmenu({
1132
+                \ 'text': 'a (s)ub menu',
1133
+                \ 'shortcut': 's' })
1134
+
1135
+    call NERDTreeAddMenuItem({
1136
+                \ 'text': '(n)ested item 1',
1137
+                \ 'shortcut': 'n',
1138
+                \ 'callback': 'SomeFunction',
1139
+                \ 'parent': submenu })
1140
+
1141
+    call NERDTreeAddMenuItem({
1142
+                \ 'text': '(n)ested item 2',
1143
+                \ 'shortcut': 'n',
1144
+                \ 'callback': 'SomeFunction',
1145
+                \ 'parent': submenu })
1146
+<
1147
+This will create the following menu: >
1148
+  --------------------
1149
+  a (t)op level menu item
1150
+  a (s)ub menu
1151
+<
1152
+Where selecting "a (s)ub menu" will lead to a second menu: >
1153
+  (n)ested item 1
1154
+  (n)ested item 2
1155
+<
1156
+When any of the 3 concrete menu items are selected the function "SomeFunction"
1157
+will be called.
1158
+
1159
+------------------------------------------------------------------------------
1160
+NERDTreeRender()                                            *NERDTreeRender()*
1161
+    Re-renders the NERD tree buffer. Useful if you change the state of the
1162
+    tree and you want to it to be reflected in the UI.
1163
+
1164
+==============================================================================
1165
+5. About                                                       *NERDTreeAbout*
1166
+
1167
+The author of the NERD tree is a terrible terrible monster called Martyzilla
1168
+who gobbles up small children with milk and sugar for breakfast.
1169
+
1170
+He can be reached at martin.grenfell at gmail dot com. He would love to hear
1171
+from you, so feel free to send him suggestions and/or comments about this
1172
+plugin.  Don't be shy --- the worst he can do is slaughter you and stuff you in
1173
+the fridge for later ;)
1174
+
1175
+The latest stable versions can be found at
1176
+    http://www.vim.org/scripts/script.php?script_id=1658
1177
+
1178
+The latest dev versions are on github
1179
+    http://github.com/scrooloose/nerdtree
1180
+
1181
+
1182
+==============================================================================
1183
+6. Changelog                                               *NERDTreeChangelog*
1184
+
1185
+Next
1186
+    - add 'scope' argument to the key map API
1187
+    - add NERDTreeCustomIgnoreFilter hook - needs doc
1188
+    - add magic [[dir]] and [[file]] flags to NERDTreeIgnore
1189
+
1190
+4.2.0
1191
+    - Add NERDTreeDirArrows option to make the UI use pretty arrow chars
1192
+      instead of the old +~| chars to define the tree structure (sickill)
1193
+    - shift the syntax highlighting out into its own syntax file (gnap)
1194
+    - add some mac specific options to the filesystem menu - for macvim
1195
+      only (andersonfreitas)
1196
+    - Add NERDTreeMinimalUI option to remove some non functional parts of the
1197
+      nerdtree ui (camthompson)
1198
+    - tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the
1199
+      new behaviour (benjamingeiger)
1200
+    - if no name is given to :Bookmark, make it default to the name of the
1201
+      target file/dir (minyoung)
1202
+    - use 'file' completion when doing copying, create, and move
1203
+      operations (EvanDotPro)
1204
+    - lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly
1205
+      Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!)
1206
+
1207
+4.1.0
1208
+    features:
1209
+    - NERDTreeFind to reveal the node for the current buffer in the tree,
1210
+      see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by
1211
+      Doug McInnes) into the script.
1212
+    - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan
1213
+      Ritter and Rémi Prévost.
1214
+    - truncate the root node if wider than the tree window. Thanks to Victor
1215
+      Gonzalez.
1216
+
1217
+    bugfixes:
1218
+    - really fix window state restoring
1219
+    - fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky,
1220
+      jfilip1024, and Chris Chambers
1221
+
1222
+4.0.0
1223
+    - add a new programmable menu system (see :help NERDTreeMenu).
1224
+    - add new APIs to add menus/menu-items to the menu system as well as
1225
+      custom key mappings to the NERD tree buffer (see :help NERDTreeAPI).
1226
+    - removed the old API functions
1227
+    - added a mapping to maximize/restore the size of nerd tree window, thanks
1228
+      to Guillaume Duranceau for the patch. See :help NERDTree-A for details.
1229
+
1230
+    - fix a bug where secondary nerd trees (netrw hijacked trees) and
1231
+      NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey.
1232
+    - fix a bug where the script ignored directories whose name ended in a dot,
1233
+      thanks to Aggelos Orfanakos for the patch.
1234
+    - fix a bug when using the x mapping on the tree root, thanks to Bryan
1235
+      Venteicher for the patch.
1236
+    - fix a bug where the cursor position/window size of the nerd tree buffer
1237
+      wasnt being stored on closing the window, thanks to Richard Hart.
1238
+    - fix a bug where NERDTreeMirror would mirror the wrong tree
1239
+
1240
+3.1.1
1241
+    - fix a bug where a non-listed no-name buffer was getting created every
1242
+      time the tree windows was created, thanks to Derek Wyatt and owen1
1243
+    - make <CR> behave the same as the 'o' mapping
1244
+    - some helptag fixes in the doc, thanks strull
1245
+    - fix a bug when using :set nohidden and opening a file where the previous
1246
+      buf was modified. Thanks iElectric
1247
+    - other minor fixes
1248
+
1249
+3.1.0
1250
+    New features:
1251
+    - add mappings to open files in a vsplit, see :help NERDTree-s and :help
1252
+      NERDTree-gs
1253
+    - make the statusline for the nerd tree window default to something
1254
+      hopefully more useful. See :help 'NERDTreeStatusline'
1255
+    Bugfixes:
1256
+    - make the hijack netrw functionality work when vim is started with "vim
1257
+      <some dir>" (thanks to Alf Mikula for the patch).
1258
+    - fix a bug where the CWD wasnt being changed for some operations even when
1259
+      NERDTreeChDirMode==2 (thanks to Lucas S. Buchala)
1260
+    - add -bar to all the nerd tree :commands so they can chain with other
1261
+      :commands (thanks to tpope)
1262
+    - fix bugs when ignorecase was set (thanks to nach)
1263
+    - fix a bug with the relative path code (thanks to nach)
1264
+    - fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach)
1265
+
1266
+
1267
+3.0.1
1268
+    Bugfixes:
1269
+    - fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden
1270
+      was not set
1271
+    - fix a bug where :NERDTree <path> would fail if <path> was relative and
1272
+      didnt start with a ./ or ../  Thanks to James Kanze.
1273
+    - make the q mapping work with secondary (:e <dir>  style) trees,
1274
+      thanks to jamessan
1275
+    - fix a bunch of small bugs with secondary trees
1276
+
1277
+    More insane refactoring.
1278
+
1279
+3.0.0
1280
+    - hijack netrw so that doing an :edit <directory>  will put a NERD tree in
1281
+      the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw'
1282
+    - allow sharing of trees across tabs, see :help :NERDTreeMirror
1283
+    - remove "top" and "bottom" as valid settings for NERDTreeWinPos
1284
+    - change the '<tab>' mapping to 'i'
1285
+    - change the 'H' mapping to 'I'
1286
+    - lots of refactoring
1287
+
1288
+==============================================================================
1289
+7. Credits                                                   *NERDTreeCredits*
1290
+
1291
+Thanks to the following people for testing, bug reports, ideas etc. Without
1292
+you I probably would have got bored of the hacking the NERD tree and
1293
+just downloaded pr0n instead.
1294
+
1295
+    Tim Carey-Smith (halorgium)
1296
+    Vigil
1297
+    Nick Brettell
1298
+    Thomas Scott Urban
1299
+    Terrance Cohen
1300
+    Yegappan Lakshmanan
1301
+    Jason Mills
1302
+    Michael Geddes (frogonwheels)
1303
+    Yu Jun
1304
+    Michael Madsen
1305
+    AOYAMA Shotaro
1306
+    Zhang Weiwu
1307
+    Niels Aan de Brugh
1308
+    Olivier Yiptong
1309
+    Zhang Shuhan
1310
+    Cory Echols
1311
+    Piotr Czachur
1312
+    Yuan Jiang
1313
+    Matan Nassau
1314
+    Maxim Kim
1315
+    Charlton Wang
1316
+    Matt Wozniski (godlygeek)
1317
+    knekk
1318
+    Sean Chou
1319
+    Ryan Penn
1320
+    Simon Peter Nicholls
1321
+    Michael Foobar
1322
+    Tomasz Chomiuk
1323
+    Denis Pokataev
1324
+    Tim Pope (tpope)
1325
+    James Kanze
1326
+    James Vega (jamessan)
1327
+    Frederic Chanal (nach)
1328
+    Alf Mikula
1329
+    Lucas S. Buchala
1330
+    Curtis Harvey
1331
+    Guillaume Duranceau
1332
+    Richard Hart (hates)
1333
+    Doug McInnes
1334
+    Stefan Ritter
1335
+    Rémi Prévost
1336
+    Victor Gonzalez
1337
+    Stephan Baumeister
1338
+    Ricky
1339
+    jfilip1024
1340
+    Chris Chambers
1341
+    Vitaly Bogdanov
1342
+    Patrick O'Loughlin (paddyoloughlin)
1343
+    Cam Thompson (camthompson)
1344
+    Marcin Kulik (sickill)
1345
+    Steve DeWald (sdewald)
1346
+    Ivan Necas (iNecas)
1347
+    George Ang (gnap)
1348
+    Evan Coury (EvanDotPro)
1349
+    Andrew Radev (AndrewRadev)
1350
+    Matt Gauger (mathias)
1351
+    Scott Stevenson (scottstvnsn)
1352
+    Anderson Freitas (andersonfreitas)
1353
+    Kamil K. Lemański (kml)
1354
+    Yehuda Katz (wycats)
1355
+    Min-Young Wu (minyoung)
1356
+    Benjamin Geiger (benjamingeiger)
1357
+
1358
+==============================================================================
1359
+8. License                                                   *NERDTreeLicense*
1360
+
1361
+The NERD tree is released under the wtfpl.
1362
+See http://sam.zoy.org/wtfpl/COPYING.
... ...
@@ -0,0 +1,41 @@
1
+" ============================================================================
2
+" File:        exec_menuitem.vim
3
+" Description: plugin for NERD Tree that provides an execute file menu item
4
+" Maintainer:  Martin Grenfell <martin.grenfell at gmail dot com>
5
+" Last Change: 22 July, 2009
6
+" License:     This program is free software. It comes without any warranty,
7
+"              to the extent permitted by applicable law. You can redistribute
8
+"              it and/or modify it under the terms of the Do What The Fuck You
9
+"              Want To Public License, Version 2, as published by Sam Hocevar.
10
+"              See http://sam.zoy.org/wtfpl/COPYING for more details.
11
+"
12
+" ============================================================================
13
+if exists("g:loaded_nerdtree_exec_menuitem")
14
+    finish
15
+endif
16
+let g:loaded_nerdtree_exec_menuitem = 1
17
+
18
+call NERDTreeAddMenuItem({
19
+            \ 'text': '(!)Execute file',
20
+            \ 'shortcut': '!',
21
+            \ 'callback': 'NERDTreeExecFile',
22
+            \ 'isActiveCallback': 'NERDTreeExecFileActive' })
23
+
24
+function! NERDTreeExecFileActive()
25
+    let node = g:NERDTreeFileNode.GetSelected()
26
+    return !node.path.isDirectory && node.path.isExecutable
27
+endfunction
28
+
29
+function! NERDTreeExecFile()
30
+    let treenode = g:NERDTreeFileNode.GetSelected()
31
+    echo "==========================================================\n"
32
+    echo "Complete the command to execute (add arguments etc):\n"
33
+    let cmd = treenode.path.str({'escape': 1})
34
+    let cmd = input(':!', cmd . ' ')
35
+
36
+    if cmd != ''
37
+        exec ':!' . cmd
38
+    else
39
+        echo "Aborted"
40
+    endif
41
+endfunction
... ...
@@ -0,0 +1,262 @@
1
+" ============================================================================
2
+" File:        fs_menu.vim
3
+" Description: plugin for the NERD Tree that provides a file system menu
4
+" Maintainer:  Martin Grenfell <martin.grenfell at gmail dot com>
5
+" Last Change: 17 July, 2009
6
+" License:     This program is free software. It comes without any warranty,
7
+"              to the extent permitted by applicable law. You can redistribute
8
+"              it and/or modify it under the terms of the Do What The Fuck You
9
+"              Want To Public License, Version 2, as published by Sam Hocevar.
10
+"              See http://sam.zoy.org/wtfpl/COPYING for more details.
11
+"
12
+" ============================================================================
13
+if exists("g:loaded_nerdtree_fs_menu")
14
+    finish
15
+endif
16
+let g:loaded_nerdtree_fs_menu = 1
17
+
18
+"Automatically delete the buffer after deleting or renaming a file
19
+if !exists("g:NERDTreeAutoDeleteBuffer")
20
+    let g:NERDTreeAutoDeleteBuffer = 0
21
+endif
22
+
23
+call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'})
24
+call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'})
25
+call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'})
26
+
27
+if has("gui_mac") || has("gui_macvim") 
28
+    call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'})
29
+    call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'})
30
+    call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'})
31
+endif
32
+
33
+if g:NERDTreePath.CopyingSupported()
34
+    call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
35
+endif
36
+
37
+"FUNCTION: s:echo(msg){{{1
38
+function! s:echo(msg)
39
+    redraw
40
+    echomsg "NERDTree: " . a:msg
41
+endfunction
42
+
43
+"FUNCTION: s:echoWarning(msg){{{1
44
+function! s:echoWarning(msg)
45
+    echohl warningmsg
46
+    call s:echo(a:msg)
47
+    echohl normal
48
+endfunction
49
+
50
+"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1
51
+"prints out the given msg and, if the user responds by pushing 'y' then the
52
+"buffer with the given bufnum is deleted
53
+"
54
+"Args:
55
+"bufnum: the buffer that may be deleted
56
+"msg: a message that will be echoed to the user asking them if they wish to
57
+"     del the buffer
58
+function! s:promptToDelBuffer(bufnum, msg)
59
+    echo a:msg
60
+    if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
61
+        " 1. ensure that all windows which display the just deleted filename
62
+        " now display an empty buffer (so a layout is preserved).
63
+        " Is not it better to close single tabs with this file only ?
64
+        let s:originalTabNumber = tabpagenr()
65
+        let s:originalWindowNumber = winnr()
66
+        exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif"
67
+        exec "tabnext " . s:originalTabNumber
68
+        exec s:originalWindowNumber . "wincmd w"
69
+        " 3. We don't need a previous buffer anymore
70
+        exec "bwipeout! " . a:bufnum
71
+    endif
72
+endfunction
73
+
74
+"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1
75
+"prints out the given msg and, if the user responds by pushing 'y' then the
76
+"buffer with the given bufnum is replaced with a new one
77
+"
78
+"Args:
79
+"bufnum: the buffer that may be deleted
80
+"msg: a message that will be echoed to the user asking them if they wish to
81
+"     del the buffer
82
+function! s:promptToRenameBuffer(bufnum, msg, newFileName)
83
+    echo a:msg
84
+    if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
85
+        " 1. ensure that a new buffer is loaded
86
+        exec "badd " . a:newFileName
87
+        " 2. ensure that all windows which display the just deleted filename
88
+        " display a buffer for a new filename. 
89
+        let s:originalTabNumber = tabpagenr()
90
+        let s:originalWindowNumber = winnr()
91
+        exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif"
92
+        exec "tabnext " . s:originalTabNumber
93
+        exec s:originalWindowNumber . "wincmd w"
94
+        " 3. We don't need a previous buffer anymore
95
+        exec "bwipeout! " . a:bufnum
96
+    endif
97
+endfunction
98
+"FUNCTION: NERDTreeAddNode(){{{1
99
+function! NERDTreeAddNode()
100
+    let curDirNode = g:NERDTreeDirNode.GetSelected()
101
+
102
+    let newNodeName = input("Add a childnode\n".
103
+                          \ "==========================================================\n".
104
+                          \ "Enter the dir/file name to be created. Dirs end with a '/'\n" .
105
+                          \ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file")
106
+
107
+    if newNodeName ==# ''
108
+        call s:echo("Node Creation Aborted.")
109
+        return
110
+    endif
111
+
112
+    try
113
+        let newPath = g:NERDTreePath.Create(newNodeName)
114
+        let parentNode = b:NERDTreeRoot.findNode(newPath.getParent())
115
+
116
+        let newTreeNode = g:NERDTreeFileNode.New(newPath)
117
+        if parentNode.isOpen || !empty(parentNode.children)
118
+            call parentNode.addChild(newTreeNode, 1)
119
+            call NERDTreeRender()
120
+            call newTreeNode.putCursorHere(1, 0)
121
+        endif
122
+    catch /^NERDTree/
123
+        call s:echoWarning("Node Not Created.")
124
+    endtry
125
+endfunction
126
+
127
+"FUNCTION: NERDTreeMoveNode(){{{1
128
+function! NERDTreeMoveNode()
129
+    let curNode = g:NERDTreeFileNode.GetSelected()
130
+    let newNodePath = input("Rename the current node\n" .
131
+                          \ "==========================================================\n" .
132
+                          \ "Enter the new path for the node:                          \n" .
133
+                          \ "", curNode.path.str(), "file")
134
+
135
+    if newNodePath ==# ''
136
+        call s:echo("Node Renaming Aborted.")
137
+        return
138
+    endif
139
+
140
+    try
141
+        let bufnum = bufnr(curNode.path.str())
142
+
143
+        call curNode.rename(newNodePath)
144
+        call NERDTreeRender()
145
+
146
+        "if the node is open in a buffer, ask the user if they want to
147
+        "close that buffer
148
+        if bufnum != -1
149
+            let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with a new file? (yN)"
150
+            call s:promptToRenameBuffer(bufnum,  prompt, newNodePath)
151
+        endif
152
+
153
+        call curNode.putCursorHere(1, 0)
154
+
155
+        redraw
156
+    catch /^NERDTree/
157
+        call s:echoWarning("Node Not Renamed.")
158
+    endtry
159
+endfunction
160
+
161
+" FUNCTION: NERDTreeDeleteNode() {{{1
162
+function! NERDTreeDeleteNode()
163
+    let currentNode = g:NERDTreeFileNode.GetSelected()
164
+    let confirmed = 0
165
+
166
+    if currentNode.path.isDirectory
167
+        let choice =input("Delete the current node\n" .
168
+                         \ "==========================================================\n" .
169
+                         \ "STOP! To delete this entire directory, type 'yes'\n" .
170
+                         \ "" . currentNode.path.str() . ": ")
171
+        let confirmed = choice ==# 'yes'
172
+    else
173
+        echo "Delete the current node\n" .
174
+           \ "==========================================================\n".
175
+           \ "Are you sure you wish to delete the node:\n" .
176
+           \ "" . currentNode.path.str() . " (yN):"
177
+        let choice = nr2char(getchar())
178
+        let confirmed = choice ==# 'y'
179
+    endif
180
+
181
+
182
+    if confirmed
183
+        try
184
+            call currentNode.delete()
185
+            call NERDTreeRender()
186
+
187
+            "if the node is open in a buffer, ask the user if they want to
188
+            "close that buffer
189
+            let bufnum = bufnr(currentNode.path.str())
190
+            if buflisted(bufnum)
191
+                let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)"
192
+                call s:promptToDelBuffer(bufnum, prompt)
193
+            endif
194
+
195
+            redraw
196
+        catch /^NERDTree/
197
+            call s:echoWarning("Could not remove node")
198
+        endtry
199
+    else
200
+        call s:echo("delete aborted")
201
+    endif
202
+
203
+endfunction
204
+
205
+" FUNCTION: NERDTreeCopyNode() {{{1
206
+function! NERDTreeCopyNode()
207
+    let currentNode = g:NERDTreeFileNode.GetSelected()
208
+    let newNodePath = input("Copy the current node\n" .
209
+                          \ "==========================================================\n" .
210
+                          \ "Enter the new path to copy the node to:                   \n" .
211
+                          \ "", currentNode.path.str(), "file")
212
+
213
+    if newNodePath != ""
214
+        "strip trailing slash
215
+        let newNodePath = substitute(newNodePath, '\/$', '', '')
216
+
217
+        let confirmed = 1
218
+        if currentNode.path.copyingWillOverwrite(newNodePath)
219
+            call s:echo("Warning: copying may overwrite files! Continue? (yN)")
220
+            let choice = nr2char(getchar())
221
+            let confirmed = choice ==# 'y'
222
+        endif
223
+
224
+        if confirmed
225
+            try
226
+                let newNode = currentNode.copy(newNodePath)
227
+                if !empty(newNode)
228
+                    call NERDTreeRender()
229
+                    call newNode.putCursorHere(0, 0)
230
+                endif
231
+            catch /^NERDTree/
232
+                call s:echoWarning("Could not copy node")
233
+            endtry
234
+        endif
235
+    else
236
+        call s:echo("Copy aborted.")
237
+    endif
238
+    redraw
239
+endfunction
240
+
241
+function! NERDTreeQuickLook()
242
+    let treenode = g:NERDTreeFileNode.GetSelected()
243
+    if treenode != {}
244
+        call system("qlmanage -p 2>/dev/null '" . treenode.path.str() . "'")
245
+    endif
246
+endfunction
247
+
248
+function! NERDTreeRevealInFinder()
249
+    let treenode = g:NERDTreeFileNode.GetSelected()
250
+    if treenode != {}
251
+        let x = system("open -R '" . treenode.path.str() . "'")
252
+    endif
253
+endfunction
254
+
255
+function! NERDTreeExecuteFile()
256
+    let treenode = g:NERDTreeFileNode.GetSelected()
257
+    if treenode != {}
258
+        let x = system("open '" . treenode.path.str() . "'")
259
+    endif
260
+endfunction
261
+
262
+" vim: set sw=4 sts=4 et fdm=marker:
... ...
@@ -0,0 +1,4444 @@
1
+" ============================================================================
2
+" File:        NERD_tree.vim
3
+" Description: vim global plugin that provides a nice tree explorer
4
+" Maintainer:  Martin Grenfell <martin.grenfell at gmail dot com>
5
+" Last Change: 28 December, 2011
6
+" License:     This program is free software. It comes without any warranty,
7
+"              to the extent permitted by applicable law. You can redistribute
8
+"              it and/or modify it under the terms of the Do What The Fuck You
9
+"              Want To Public License, Version 2, as published by Sam Hocevar.
10
+"              See http://sam.zoy.org/wtfpl/COPYING for more details.
11
+"
12
+" ============================================================================
13
+let s:NERD_tree_version = '4.2.0'
14
+
15
+" SECTION: Script init stuff {{{1
16
+"============================================================
17
+if exists("loaded_nerd_tree")
18
+    finish
19
+endif
20
+if v:version < 700
21
+    echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!"
22
+    finish
23
+endif
24
+let loaded_nerd_tree = 1
25
+
26
+"for line continuation - i.e dont want C in &cpo
27
+let s:old_cpo = &cpo
28
+set cpo&vim
29
+
30
+let s:running_windows = has("win16") || has("win32") || has("win64")
31
+
32
+"Function: s:initVariable() function {{{2
33
+"This function is used to initialise a given variable to a given value. The
34
+"variable is only initialised if it does not exist prior
35
+"
36
+"Args:
37
+"var: the name of the var to be initialised
38
+"value: the value to initialise var to
39
+"
40
+"Returns:
41
+"1 if the var is set, 0 otherwise
42
+function! s:initVariable(var, value)
43
+    if !exists(a:var)
44
+        exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'"
45
+        return 1
46
+    endif
47
+    return 0
48
+endfunction
49
+
50
+"SECTION: Init variable calls and other random constants {{{2
51
+call s:initVariable("g:NERDChristmasTree", 1)
52
+call s:initVariable("g:NERDTreeAutoCenter", 1)
53
+call s:initVariable("g:NERDTreeAutoCenterThreshold", 3)
54
+call s:initVariable("g:NERDTreeCaseSensitiveSort", 0)
55
+call s:initVariable("g:NERDTreeChDirMode", 0)
56
+call s:initVariable("g:NERDTreeMinimalUI", 0)
57
+if !exists("g:NERDTreeIgnore")
58
+    let g:NERDTreeIgnore = ['\~$']
59
+endif
60
+call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks')
61
+call s:initVariable("g:NERDTreeHighlightCursorline", 1)
62
+call s:initVariable("g:NERDTreeHijackNetrw", 1)
63
+call s:initVariable("g:NERDTreeMouseMode", 1)
64
+call s:initVariable("g:NERDTreeNotificationThreshold", 100)
65
+call s:initVariable("g:NERDTreeQuitOnOpen", 0)
66
+call s:initVariable("g:NERDTreeShowBookmarks", 0)
67
+call s:initVariable("g:NERDTreeShowFiles", 1)
68
+call s:initVariable("g:NERDTreeShowHidden", 0)
69
+call s:initVariable("g:NERDTreeShowLineNumbers", 0)
70
+call s:initVariable("g:NERDTreeSortDirs", 1)
71
+call s:initVariable("g:NERDTreeDirArrows", !s:running_windows)
72
+call s:initVariable("g:NERDTreeCasadeOpenSingleChildDir", 1)
73
+
74
+if !exists("g:NERDTreeSortOrder")
75
+    let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$',  '\.bak$', '\~$']
76
+else
77
+    "if there isnt a * in the sort sequence then add one
78
+    if count(g:NERDTreeSortOrder, '*') < 1
79
+        call add(g:NERDTreeSortOrder, '*')
80
+    endif
81
+endif
82
+
83
+"we need to use this number many times for sorting... so we calculate it only
84
+"once here
85
+let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
86
+
87
+if !exists('g:NERDTreeStatusline')
88
+
89
+    "the exists() crap here is a hack to stop vim spazzing out when
90
+    "loading a session that was created with an open nerd tree. It spazzes
91
+    "because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash)
92
+    let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}"
93
+
94
+endif
95
+call s:initVariable("g:NERDTreeWinPos", "left")
96
+call s:initVariable("g:NERDTreeWinSize", 31)
97
+
98
+"init the shell commands that will be used to copy nodes, and remove dir trees
99
+"
100
+"Note: the space after the command is important
101
+if s:running_windows
102
+    call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ')
103
+else
104
+    call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ')
105
+    call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ')
106
+endif
107
+
108
+
109
+"SECTION: Init variable calls for key mappings {{{2
110
+call s:initVariable("g:NERDTreeMapActivateNode", "o")
111
+call s:initVariable("g:NERDTreeMapChangeRoot", "C")
112
+call s:initVariable("g:NERDTreeMapChdir", "cd")
113
+call s:initVariable("g:NERDTreeMapCloseChildren", "X")
114
+call s:initVariable("g:NERDTreeMapCloseDir", "x")
115
+call s:initVariable("g:NERDTreeMapDeleteBookmark", "D")
116
+call s:initVariable("g:NERDTreeMapMenu", "m")
117
+call s:initVariable("g:NERDTreeMapHelp", "?")
118
+call s:initVariable("g:NERDTreeMapJumpFirstChild", "K")
119
+call s:initVariable("g:NERDTreeMapJumpLastChild", "J")
120
+call s:initVariable("g:NERDTreeMapJumpNextSibling", "<C-j>")
121
+call s:initVariable("g:NERDTreeMapJumpParent", "p")
122
+call s:initVariable("g:NERDTreeMapJumpPrevSibling", "<C-k>")
123
+call s:initVariable("g:NERDTreeMapJumpRoot", "P")
124
+call s:initVariable("g:NERDTreeMapOpenExpl", "e")
125
+call s:initVariable("g:NERDTreeMapOpenInTab", "t")
126
+call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T")
127
+call s:initVariable("g:NERDTreeMapOpenRecursively", "O")
128
+call s:initVariable("g:NERDTreeMapOpenSplit", "i")
129
+call s:initVariable("g:NERDTreeMapOpenVSplit", "s")
130
+call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode)
131
+call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit)
132
+call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit)
133
+call s:initVariable("g:NERDTreeMapQuit", "q")
134
+call s:initVariable("g:NERDTreeMapRefresh", "r")
135
+call s:initVariable("g:NERDTreeMapRefreshRoot", "R")
136
+call s:initVariable("g:NERDTreeMapToggleBookmarks", "B")
137
+call s:initVariable("g:NERDTreeMapToggleFiles", "F")
138
+call s:initVariable("g:NERDTreeMapToggleFilters", "f")
139
+call s:initVariable("g:NERDTreeMapToggleHidden", "I")
140
+call s:initVariable("g:NERDTreeMapToggleZoom", "A")
141
+call s:initVariable("g:NERDTreeMapUpdir", "u")
142
+call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U")
143
+call s:initVariable("g:NERDTreeMapCWD", "CD")
144
+
145
+"SECTION: Script level variable declaration{{{2
146
+if s:running_windows
147
+    let s:escape_chars =  " `\|\"#%&,?()\*^<>"
148
+else
149
+    let s:escape_chars =  " \\`\|\"#%&,?()\*^<>[]"
150
+endif
151
+let s:NERDTreeBufName = 'NERD_tree_'
152
+
153
+let s:tree_wid = 2
154
+
155
+if g:NERDTreeDirArrows
156
+    let s:tree_markup_reg = '^\([▾▸] \| \+[▾▸] \| \+\)'
157
+else
158
+    let s:tree_markup_reg = '^[ `|]*[\-+~]'
159
+endif
160
+let s:tree_up_dir_line = '.. (up a dir)'
161
+
162
+"the number to add to the nerd tree buffer name to make the buf name unique
163
+let s:next_buffer_number = 1
164
+
165
+" SECTION: Commands {{{1
166
+"============================================================
167
+"init the command that users start the nerd tree with
168
+command! -n=? -complete=dir -bar NERDTree :call s:initNerdTree('<args>')
169
+command! -n=? -complete=dir -bar NERDTreeToggle :call s:toggle('<args>')
170
+command! -n=0 -bar NERDTreeClose :call s:closeTreeIfOpen()
171
+command! -n=1 -complete=customlist,s:completeBookmarks -bar NERDTreeFromBookmark call s:initNerdTree('<args>')
172
+command! -n=0 -bar NERDTreeMirror call s:initNerdTreeMirror()
173
+command! -n=0 -bar NERDTreeFind call s:findAndRevealPath()
174
+command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
175
+command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
176
+" SECTION: Auto commands {{{1
177
+"============================================================
178
+augroup NERDTree
179
+    "Save the cursor position whenever we close the nerd tree
180
+    exec "autocmd BufWinLeave ". s:NERDTreeBufName ."* call <SID>saveScreenState()"
181
+
182
+    "disallow insert mode in the NERDTree
183
+    exec "autocmd BufEnter ". s:NERDTreeBufName ."* stopinsert"
184
+augroup END
185
+
186
+if g:NERDTreeHijackNetrw
187
+    augroup NERDTreeHijackNetrw
188
+        autocmd VimEnter * silent! autocmd! FileExplorer
189
+        au BufEnter,VimEnter * call s:checkForBrowse(expand("<amatch>"))
190
+    augroup END
191
+endif
192
+
193
+"SECTION: Classes {{{1
194
+"============================================================
195
+"CLASS: Bookmark {{{2
196
+"============================================================
197
+let s:Bookmark = {}
198
+" FUNCTION: Bookmark.activate() {{{3
199
+function! s:Bookmark.activate(...)
200
+    call self.open(a:0 ? a:1 : {})
201
+endfunction
202
+" FUNCTION: Bookmark.AddBookmark(name, path) {{{3
203
+" Class method to add a new bookmark to the list, if a previous bookmark exists
204
+" with the same name, just update the path for that bookmark
205
+function! s:Bookmark.AddBookmark(name, path)
206
+    for i in s:Bookmark.Bookmarks()
207
+        if i.name ==# a:name
208
+            let i.path = a:path
209
+            return
210
+        endif
211
+    endfor
212
+    call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
213
+    call s:Bookmark.Sort()
214
+endfunction
215
+" Function: Bookmark.Bookmarks()   {{{3
216
+" Class method to get all bookmarks. Lazily initializes the bookmarks global
217
+" variable
218
+function! s:Bookmark.Bookmarks()
219
+    if !exists("g:NERDTreeBookmarks")
220
+        let g:NERDTreeBookmarks = []
221
+    endif
222
+    return g:NERDTreeBookmarks
223
+endfunction
224
+" Function: Bookmark.BookmarkExistsFor(name)   {{{3
225
+" class method that returns 1 if a bookmark with the given name is found, 0
226
+" otherwise
227
+function! s:Bookmark.BookmarkExistsFor(name)
228
+    try
229
+        call s:Bookmark.BookmarkFor(a:name)
230
+        return 1
231
+    catch /^NERDTree.BookmarkNotFoundError/
232
+        return 0
233
+    endtry
234
+endfunction
235
+" Function: Bookmark.BookmarkFor(name)   {{{3
236
+" Class method to get the bookmark that has the given name. {} is return if no
237
+" bookmark is found
238
+function! s:Bookmark.BookmarkFor(name)
239
+    for i in s:Bookmark.Bookmarks()
240
+        if i.name ==# a:name
241
+            return i
242
+        endif
243
+    endfor
244
+    throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name  .'"'
245
+endfunction
246
+" Function: Bookmark.BookmarkNames()   {{{3
247
+" Class method to return an array of all bookmark names
248
+function! s:Bookmark.BookmarkNames()
249
+    let names = []
250
+    for i in s:Bookmark.Bookmarks()
251
+        call add(names, i.name)
252
+    endfor
253
+    return names
254
+endfunction
255
+" FUNCTION: Bookmark.CacheBookmarks(silent) {{{3
256
+" Class method to read all bookmarks from the bookmarks file intialize
257
+" bookmark objects for each one.
258
+"
259
+" Args:
260
+" silent - dont echo an error msg if invalid bookmarks are found
261
+function! s:Bookmark.CacheBookmarks(silent)
262
+    if filereadable(g:NERDTreeBookmarksFile)
263
+        let g:NERDTreeBookmarks = []
264
+        let g:NERDTreeInvalidBookmarks = []
265
+        let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
266
+        let invalidBookmarksFound = 0
267
+        for i in bookmarkStrings
268
+
269
+            "ignore blank lines
270
+            if i != ''
271
+
272
+                let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
273
+                let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
274
+
275
+                try
276
+                    let bookmark = s:Bookmark.New(name, s:Path.New(path))
277
+                    call add(g:NERDTreeBookmarks, bookmark)
278
+                catch /^NERDTree.InvalidArgumentsError/
279
+                    call add(g:NERDTreeInvalidBookmarks, i)
280
+                    let invalidBookmarksFound += 1
281
+                endtry
282
+            endif
283
+        endfor
284
+        if invalidBookmarksFound
285
+            call s:Bookmark.Write()
286
+            if !a:silent
287
+                call s:echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.")
288
+            endif
289
+        endif
290
+        call s:Bookmark.Sort()
291
+    endif
292
+endfunction
293
+" FUNCTION: Bookmark.compareTo(otherbookmark) {{{3
294
+" Compare these two bookmarks for sorting purposes
295
+function! s:Bookmark.compareTo(otherbookmark)
296
+    return a:otherbookmark.name < self.name
297
+endfunction
298
+" FUNCTION: Bookmark.ClearAll() {{{3
299
+" Class method to delete all bookmarks.
300
+function! s:Bookmark.ClearAll()
301
+    for i in s:Bookmark.Bookmarks()
302
+        call i.delete()
303
+    endfor
304
+    call s:Bookmark.Write()
305
+endfunction
306
+" FUNCTION: Bookmark.delete() {{{3
307
+" Delete this bookmark. If the node for this bookmark is under the current
308
+" root, then recache bookmarks for its Path object
309
+function! s:Bookmark.delete()
310
+    let node = {}
311
+    try
312
+        let node = self.getNode(1)
313
+    catch /^NERDTree.BookmarkedNodeNotFoundError/
314
+    endtry
315
+    call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
316
+    if !empty(node)
317
+        call node.path.cacheDisplayString()
318
+    endif
319
+    call s:Bookmark.Write()
320
+endfunction
321
+" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{3
322
+" Gets the treenode for this bookmark
323
+"
324
+" Args:
325
+" searchFromAbsoluteRoot: specifies whether we should search from the current
326
+" tree root, or the highest cached node
327
+function! s:Bookmark.getNode(searchFromAbsoluteRoot)
328
+    let searchRoot = a:searchFromAbsoluteRoot ? s:TreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot
329
+    let targetNode = searchRoot.findNode(self.path)
330
+    if empty(targetNode)
331
+        throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name
332
+    endif
333
+    return targetNode
334
+endfunction
335
+" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{3
336
+" Class method that finds the bookmark with the given name and returns the
337
+" treenode for it.
338
+function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot)
339
+    let bookmark = s:Bookmark.BookmarkFor(a:name)
340
+    return bookmark.getNode(a:searchFromAbsoluteRoot)
341
+endfunction
342
+" FUNCTION: Bookmark.GetSelected() {{{3
343
+" returns the Bookmark the cursor is over, or {}
344
+function! s:Bookmark.GetSelected()
345
+    let line = getline(".")
346
+    let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '')
347
+    if name != line
348
+        try
349
+            return s:Bookmark.BookmarkFor(name)
350
+        catch /^NERDTree.BookmarkNotFoundError/
351
+            return {}
352
+        endtry
353
+    endif
354
+    return {}
355
+endfunction
356
+
357
+" Function: Bookmark.InvalidBookmarks()   {{{3
358
+" Class method to get all invalid bookmark strings read from the bookmarks
359
+" file
360
+function! s:Bookmark.InvalidBookmarks()
361
+    if !exists("g:NERDTreeInvalidBookmarks")
362
+        let g:NERDTreeInvalidBookmarks = []
363
+    endif
364
+    return g:NERDTreeInvalidBookmarks
365
+endfunction
366
+" FUNCTION: Bookmark.mustExist() {{{3
367
+function! s:Bookmark.mustExist()
368
+    if !self.path.exists()
369
+        call s:Bookmark.CacheBookmarks(1)
370
+        throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"".
371
+            \ self.name ."\" points to a non existing location: \"". self.path.str()
372
+    endif
373
+endfunction
374
+" FUNCTION: Bookmark.New(name, path) {{{3
375
+" Create a new bookmark object with the given name and path object
376
+function! s:Bookmark.New(name, path)
377
+    if a:name =~# ' '
378
+        throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name
379
+    endif
380
+
381
+    let newBookmark = copy(self)
382
+    let newBookmark.name = a:name
383
+    let newBookmark.path = a:path
384
+    return newBookmark
385
+endfunction
386
+" FUNCTION: Bookmark.open([options]) {{{3
387
+"Args:
388
+"A dictionary containing the following keys (all optional):
389
+"  'where': Specifies whether the node should be opened in new split/tab or in
390
+"           the previous window. Can be either 'v' (vertical split), 'h'
391
+"           (horizontal split), 't' (new tab) or 'p' (previous window).
392
+"  'reuse': if a window is displaying the file then jump the cursor there
393
+"  'keepopen': dont close the tree window
394
+"  'stay': open the file, but keep the cursor in the tree win
395
+"
396
+function! s:Bookmark.open(...)
397
+    let opts = a:0 ? a:1 : {}
398
+
399
+    if self.path.isDirectory && !has_key(opts, 'where')
400
+        call self.toRoot()
401
+    else
402
+        let opener = s:Opener.New(self.path, opts)
403
+        call opener.open(self)
404
+    endif
405
+endfunction
406
+" FUNCTION: Bookmark.openInNewTab(options) {{{3
407
+" Create a new bookmark object with the given name and path object
408
+function! s:Bookmark.openInNewTab(options)
409
+    call s:deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead')
410
+    call self.open(a:options)
411
+endfunction
412
+" Function: Bookmark.setPath(path)   {{{3
413
+" makes this bookmark point to the given path
414
+function! s:Bookmark.setPath(path)
415
+    let self.path = a:path
416
+endfunction
417
+" Function: Bookmark.Sort()   {{{3
418
+" Class method that sorts all bookmarks
419
+function! s:Bookmark.Sort()
420
+    let CompareFunc = function("s:compareBookmarks")
421
+    call sort(s:Bookmark.Bookmarks(), CompareFunc)
422
+endfunction
423
+" Function: Bookmark.str()   {{{3
424
+" Get the string that should be rendered in the view for this bookmark
425
+function! s:Bookmark.str()
426
+    let pathStrMaxLen = winwidth(s:getTreeWinNum()) - 4 - len(self.name)
427
+    if &nu
428
+        let pathStrMaxLen = pathStrMaxLen - &numberwidth
429
+    endif
430
+
431
+    let pathStr = self.path.str({'format': 'UI'})
432
+    if len(pathStr) > pathStrMaxLen
433
+        let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
434
+    endif
435
+    return '>' . self.name . ' ' . pathStr
436
+endfunction
437
+" FUNCTION: Bookmark.toRoot() {{{3
438
+" Make the node for this bookmark the new tree root
439
+function! s:Bookmark.toRoot()
440
+    if self.validate()
441
+        try
442
+            let targetNode = self.getNode(1)
443
+        catch /^NERDTree.BookmarkedNodeNotFoundError/
444
+            let targetNode = s:TreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
445
+        endtry
446
+        call targetNode.makeRoot()
447
+        call s:renderView()
448
+        call targetNode.putCursorHere(0, 0)
449
+    endif
450
+endfunction
451
+" FUNCTION: Bookmark.ToRoot(name) {{{3
452
+" Make the node for this bookmark the new tree root
453
+function! s:Bookmark.ToRoot(name)
454
+    let bookmark = s:Bookmark.BookmarkFor(a:name)
455
+    call bookmark.toRoot()
456
+endfunction
457
+
458
+
459
+"FUNCTION: Bookmark.validate() {{{3
460
+function! s:Bookmark.validate()
461
+    if self.path.exists()
462
+        return 1
463
+    else
464
+        call s:Bookmark.CacheBookmarks(1)
465
+        call s:renderView()
466
+        call s:echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
467
+        return 0
468
+    endif
469
+endfunction
470
+
471
+" Function: Bookmark.Write()   {{{3
472
+" Class method to write all bookmarks to the bookmarks file
473
+function! s:Bookmark.Write()
474
+    let bookmarkStrings = []
475
+    for i in s:Bookmark.Bookmarks()
476
+        call add(bookmarkStrings, i.name . ' ' . i.path.str())
477
+    endfor
478
+
479
+    "add a blank line before the invalid ones
480
+    call add(bookmarkStrings, "")
481
+
482
+    for j in s:Bookmark.InvalidBookmarks()
483
+        call add(bookmarkStrings, j)
484
+    endfor
485
+    call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
486
+endfunction
487
+"CLASS: KeyMap {{{2
488
+"============================================================
489
+let s:KeyMap = {}
490
+"FUNCTION: KeyMap.All() {{{3
491
+function! s:KeyMap.All()
492
+    if !exists("s:keyMaps")
493
+        let s:keyMaps = []
494
+    endif
495
+    return s:keyMaps
496
+endfunction
497
+
498
+"FUNCTION: KeyMap.FindFor(key, scope) {{{3
499
+function! s:KeyMap.FindFor(key, scope)
500
+    for i in s:KeyMap.All()
501
+         if i.key ==# a:key && i.scope ==# a:scope
502
+            return i
503
+        endif
504
+    endfor
505
+    return {}
506
+endfunction
507
+
508
+"FUNCTION: KeyMap.BindAll() {{{3
509
+function! s:KeyMap.BindAll()
510
+    for i in s:KeyMap.All()
511
+        call i.bind()
512
+    endfor
513
+endfunction
514
+
515
+"FUNCTION: KeyMap.bind() {{{3
516
+function! s:KeyMap.bind()
517
+    " If the key sequence we're trying to map contains any '<>' notation, we
518
+    " must replace each of the '<' characters with '<lt>' to ensure the string
519
+    " is not translated into its corresponding keycode during the later part
520
+    " of the map command below
521
+    " :he <>
522
+    let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)'
523
+    if self.key =~# specialNotationRegex
524
+        let keymapInvokeString = substitute(self.key, specialNotationRegex, '<lt>\1', 'g')
525
+    else
526
+        let keymapInvokeString = self.key
527
+    endif
528
+
529
+    let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " "
530
+
531
+    exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call <SID>KeyMap_Invoke("'. keymapInvokeString .'")<cr>'
532
+endfunction
533
+
534
+"FUNCTION: KeyMap.Remove(key, scope) {{{3
535
+function! s:KeyMap.Remove(key, scope)
536
+    let maps = s:KeyMap.All()
537
+    for i in range(len(maps))
538
+         if maps[i].key ==# a:key && maps[i].scope ==# a:scope
539
+            return remove(maps, i)
540
+        endif
541
+    endfor
542
+endfunction
543
+"FUNCTION: KeyMap.invoke() {{{3
544
+"Call the KeyMaps callback function
545
+function! s:KeyMap.invoke(...)
546
+    let Callback = function(self.callback)
547
+    if a:0
548
+        call Callback(a:1)
549
+    else
550
+        call Callback()
551
+    endif
552
+endfunction
553
+
554
+
555
+"FUNCTION: KeyMap.Invoke() {{{3
556
+"Find a keymapping for a:key and the current scope invoke it.
557
+"
558
+"Scope is determined as follows:
559
+"   * if the cursor is on a dir node then "DirNode"
560
+"   * if the cursor is on a file node then "FileNode"
561
+"   * if the cursor is on a bookmark then "Bookmark"
562
+"
563
+"If a keymap has the scope of "all" then it will be called if no other keymap
564
+"is found for a:key and the scope.
565
+function! s:KeyMap.Invoke(key)
566
+    let node = s:TreeFileNode.GetSelected()
567
+    if !empty(node)
568
+
569
+        "try file node
570
+        if !node.path.isDirectory
571
+            let km = s:KeyMap.FindFor(a:key, "FileNode")
572
+            if !empty(km)
573
+                return km.invoke(node)
574
+            endif
575
+        endif
576
+
577
+        "try dir node
578
+        if node.path.isDirectory
579
+            let km = s:KeyMap.FindFor(a:key, "DirNode")
580
+            if !empty(km)
581
+                return km.invoke(node)
582
+            endif
583
+        endif
584
+
585
+        "try generic node
586
+        let km = s:KeyMap.FindFor(a:key, "Node")
587
+        if !empty(km)
588
+            return km.invoke(node)
589
+        endif
590
+
591
+    endif
592
+
593
+    "try bookmark
594
+    let bm = s:Bookmark.GetSelected()
595
+    if !empty(bm)
596
+        let km = s:KeyMap.FindFor(a:key, "Bookmark")
597
+        if !empty(km)
598
+            return km.invoke(bm)
599
+        endif
600
+    endif
601
+
602
+    "try all
603
+    let km = s:KeyMap.FindFor(a:key, "all")
604
+    if !empty(km)
605
+        return km.invoke()
606
+    endif
607
+endfunction
608
+
609
+"this is needed since I cant figure out how to invoke dict functions from a
610
+"key map
611
+function! s:KeyMap_Invoke(key)
612
+    call s:KeyMap.Invoke(a:key)
613
+endfunction
614
+
615
+"FUNCTION: KeyMap.Create(options) {{{3
616
+function! s:KeyMap.Create(options)
617
+    let newKeyMap = copy(self)
618
+    let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
619
+    let newKeyMap.key = opts['key']
620
+    let newKeyMap.quickhelpText = opts['quickhelpText']
621
+    let newKeyMap.callback = opts['callback']
622
+    let newKeyMap.scope = opts['scope']
623
+
624
+    call s:KeyMap.Add(newKeyMap)
625
+endfunction
626
+
627
+"FUNCTION: KeyMap.Add(keymap) {{{3
628
+function! s:KeyMap.Add(keymap)
629
+    call s:KeyMap.Remove(a:keymap.key, a:keymap.scope)
630
+    call add(s:KeyMap.All(), a:keymap)
631
+endfunction
632
+
633
+"CLASS: MenuController {{{2
634
+"============================================================
635
+let s:MenuController = {}
636
+"FUNCTION: MenuController.New(menuItems) {{{3
637
+"create a new menu controller that operates on the given menu items
638
+function! s:MenuController.New(menuItems)
639
+    let newMenuController =  copy(self)
640
+    if a:menuItems[0].isSeparator()
641
+        let newMenuController.menuItems = a:menuItems[1:-1]
642
+    else
643
+        let newMenuController.menuItems = a:menuItems
644
+    endif
645
+    return newMenuController
646
+endfunction
647
+
648
+"FUNCTION: MenuController.showMenu() {{{3
649
+"start the main loop of the menu and get the user to choose/execute a menu
650
+"item
651
+function! s:MenuController.showMenu()
652
+    call self._saveOptions()
653
+
654
+    try
655
+        let self.selection = 0
656
+
657
+        let done = 0
658
+        while !done
659
+            redraw!
660
+            call self._echoPrompt()
661
+            let key = nr2char(getchar())
662
+            let done = self._handleKeypress(key)
663
+        endwhile
664
+    finally
665
+        call self._restoreOptions()
666
+    endtry
667
+
668
+    if self.selection != -1
669
+        let m = self._current()
670
+        call m.execute()
671
+    endif
672
+endfunction
673
+
674
+"FUNCTION: MenuController._echoPrompt() {{{3
675
+function! s:MenuController._echoPrompt()
676
+    echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated"
677
+    echo "=========================================================="
678
+
679
+    for i in range(0, len(self.menuItems)-1)
680
+        if self.selection == i
681
+            echo "> " . self.menuItems[i].text
682
+        else
683
+            echo "  " . self.menuItems[i].text
684
+        endif
685
+    endfor
686
+endfunction
687
+
688
+"FUNCTION: MenuController._current(key) {{{3
689
+"get the MenuItem that is currently selected
690
+function! s:MenuController._current()
691
+    return self.menuItems[self.selection]
692
+endfunction
693
+
694
+"FUNCTION: MenuController._handleKeypress(key) {{{3
695
+"change the selection (if appropriate) and return 1 if the user has made
696
+"their choice, 0 otherwise
697
+function! s:MenuController._handleKeypress(key)
698
+    if a:key == 'j'
699
+        call self._cursorDown()
700
+    elseif a:key == 'k'
701
+        call self._cursorUp()
702
+    elseif a:key == nr2char(27) "escape
703
+        let self.selection = -1
704
+        return 1
705
+    elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j
706
+        return 1
707
+    else
708
+        let index = self._nextIndexFor(a:key)
709
+        if index != -1
710
+            let self.selection = index
711
+            if len(self._allIndexesFor(a:key)) == 1
712
+                return 1
713
+            endif
714
+        endif
715
+    endif
716
+
717
+    return 0
718
+endfunction
719
+
720
+"FUNCTION: MenuController._allIndexesFor(shortcut) {{{3
721
+"get indexes to all menu items with the given shortcut
722
+function! s:MenuController._allIndexesFor(shortcut)
723
+    let toReturn = []
724
+
725
+    for i in range(0, len(self.menuItems)-1)
726
+        if self.menuItems[i].shortcut == a:shortcut
727
+            call add(toReturn, i)
728
+        endif
729
+    endfor
730
+
731
+    return toReturn
732
+endfunction
733
+
734
+"FUNCTION: MenuController._nextIndexFor(shortcut) {{{3
735
+"get the index to the next menu item with the given shortcut, starts from the
736
+"current cursor location and wraps around to the top again if need be
737
+function! s:MenuController._nextIndexFor(shortcut)
738
+    for i in range(self.selection+1, len(self.menuItems)-1)
739
+        if self.menuItems[i].shortcut == a:shortcut
740
+            return i
741
+        endif
742
+    endfor
743
+
744
+    for i in range(0, self.selection)
745
+        if self.menuItems[i].shortcut == a:shortcut
746
+            return i
747
+        endif
748
+    endfor
749
+
750
+    return -1
751
+endfunction
752
+
753
+"FUNCTION: MenuController._setCmdheight() {{{3
754
+"sets &cmdheight to whatever is needed to display the menu
755
+function! s:MenuController._setCmdheight()
756
+    let &cmdheight = len(self.menuItems) + 3
757
+endfunction
758
+
759
+"FUNCTION: MenuController._saveOptions() {{{3
760
+"set any vim options that are required to make the menu work (saving their old
761
+"values)
762
+function! s:MenuController._saveOptions()
763
+    let self._oldLazyredraw = &lazyredraw
764
+    let self._oldCmdheight = &cmdheight
765
+    set nolazyredraw
766
+    call self._setCmdheight()
767
+endfunction
768
+
769
+"FUNCTION: MenuController._restoreOptions() {{{3
770
+"restore the options we saved in _saveOptions()
771
+function! s:MenuController._restoreOptions()
772
+    let &cmdheight = self._oldCmdheight
773
+    let &lazyredraw = self._oldLazyredraw
774
+endfunction
775
+
776
+"FUNCTION: MenuController._cursorDown() {{{3
777
+"move the cursor to the next menu item, skipping separators
778
+function! s:MenuController._cursorDown()
779
+    let done = 0
780
+    while !done
781
+        if self.selection < len(self.menuItems)-1
782
+            let self.selection += 1
783
+        else
784
+            let self.selection = 0
785
+        endif
786
+
787
+        if !self._current().isSeparator()
788
+            let done = 1
789
+        endif
790
+    endwhile
791
+endfunction
792
+
793
+"FUNCTION: MenuController._cursorUp() {{{3
794
+"move the cursor to the previous menu item, skipping separators
795
+function! s:MenuController._cursorUp()
796
+    let done = 0
797
+    while !done
798
+        if self.selection > 0
799
+            let self.selection -= 1
800
+        else
801
+            let self.selection = len(self.menuItems)-1
802
+        endif
803
+
804
+        if !self._current().isSeparator()
805
+            let done = 1
806
+        endif
807
+    endwhile
808
+endfunction
809
+
810
+"CLASS: MenuItem {{{2
811
+"============================================================
812
+let s:MenuItem = {}
813
+"FUNCTION: MenuItem.All() {{{3
814
+"get all top level menu items
815
+function! s:MenuItem.All()
816
+    if !exists("s:menuItems")
817
+        let s:menuItems = []
818
+    endif
819
+    return s:menuItems
820
+endfunction
821
+
822
+"FUNCTION: MenuItem.AllEnabled() {{{3
823
+"get all top level menu items that are currently enabled
824
+function! s:MenuItem.AllEnabled()
825
+    let toReturn = []
826
+    for i in s:MenuItem.All()
827
+        if i.enabled()
828
+            call add(toReturn, i)
829
+        endif
830
+    endfor
831
+    return toReturn
832
+endfunction
833
+
834
+"FUNCTION: MenuItem.Create(options) {{{3
835
+"make a new menu item and add it to the global list
836
+function! s:MenuItem.Create(options)
837
+    let newMenuItem = copy(self)
838
+
839
+    let newMenuItem.text = a:options['text']
840
+    let newMenuItem.shortcut = a:options['shortcut']
841
+    let newMenuItem.children = []
842
+
843
+    let newMenuItem.isActiveCallback = -1
844
+    if has_key(a:options, 'isActiveCallback')
845
+        let newMenuItem.isActiveCallback = a:options['isActiveCallback']
846
+    endif
847
+
848
+    let newMenuItem.callback = -1
849
+    if has_key(a:options, 'callback')
850
+        let newMenuItem.callback = a:options['callback']
851
+    endif
852
+
853
+    if has_key(a:options, 'parent')
854
+        call add(a:options['parent'].children, newMenuItem)
855
+    else
856
+        call add(s:MenuItem.All(), newMenuItem)
857
+    endif
858
+
859
+    return newMenuItem
860
+endfunction
861
+
862
+"FUNCTION: MenuItem.CreateSeparator(options) {{{3
863
+"make a new separator menu item and add it to the global list
864
+function! s:MenuItem.CreateSeparator(options)
865
+    let standard_options = { 'text': '--------------------',
866
+                \ 'shortcut': -1,
867
+                \ 'callback': -1 }
868
+    let options = extend(a:options, standard_options, "force")
869
+
870
+    return s:MenuItem.Create(options)
871
+endfunction
872
+
873
+"FUNCTION: MenuItem.CreateSubmenu(options) {{{3
874
+"make a new submenu and add it to global list
875
+function! s:MenuItem.CreateSubmenu(options)
876
+    let standard_options = { 'callback': -1 }
877
+    let options = extend(a:options, standard_options, "force")
878
+
879
+    return s:MenuItem.Create(options)
880
+endfunction
881
+
882
+"FUNCTION: MenuItem.enabled() {{{3
883
+"return 1 if this menu item should be displayed
884
+"
885
+"delegates off to the isActiveCallback, and defaults to 1 if no callback was
886
+"specified
887
+function! s:MenuItem.enabled()
888
+    if self.isActiveCallback != -1
889
+        return {self.isActiveCallback}()
890
+    endif
891
+    return 1
892
+endfunction
893
+
894
+"FUNCTION: MenuItem.execute() {{{3
895
+"perform the action behind this menu item, if this menuitem has children then
896
+"display a new menu for them, otherwise deletegate off to the menuitem's
897
+"callback
898
+function! s:MenuItem.execute()
899
+    if len(self.children)
900
+        let mc = s:MenuController.New(self.children)
901
+        call mc.showMenu()
902
+    else
903
+        if self.callback != -1
904
+            call {self.callback}()
905
+        endif
906
+    endif
907
+endfunction
908
+
909
+"FUNCTION: MenuItem.isSeparator() {{{3
910
+"return 1 if this menuitem is a separator
911
+function! s:MenuItem.isSeparator()
912
+    return self.callback == -1 && self.children == []
913
+endfunction
914
+
915
+"FUNCTION: MenuItem.isSubmenu() {{{3
916
+"return 1 if this menuitem is a submenu
917
+function! s:MenuItem.isSubmenu()
918
+    return self.callback == -1 && !empty(self.children)
919
+endfunction
920
+
921
+"CLASS: TreeFileNode {{{2
922
+"This class is the parent of the TreeDirNode class and constitures the
923
+"'Component' part of the composite design pattern between the treenode
924
+"classes.
925
+"============================================================
926
+let s:TreeFileNode = {}
927
+"FUNCTION: TreeFileNode.activate(...) {{{3
928
+function! s:TreeFileNode.activate(...)
929
+    call self.open(a:0 ? a:1 : {})
930
+endfunction
931
+"FUNCTION: TreeFileNode.bookmark(name) {{{3
932
+"bookmark this node with a:name
933
+function! s:TreeFileNode.bookmark(name)
934
+
935
+    "if a bookmark exists with the same name and the node is cached then save
936
+    "it so we can update its display string
937
+    let oldMarkedNode = {}
938
+    try
939
+        let oldMarkedNode = s:Bookmark.GetNodeForName(a:name, 1)
940
+    catch /^NERDTree.BookmarkNotFoundError/
941
+    catch /^NERDTree.BookmarkedNodeNotFoundError/
942
+    endtry
943
+
944
+    call s:Bookmark.AddBookmark(a:name, self.path)
945
+    call self.path.cacheDisplayString()
946
+    call s:Bookmark.Write()
947
+
948
+    if !empty(oldMarkedNode)
949
+        call oldMarkedNode.path.cacheDisplayString()
950
+    endif
951
+endfunction
952
+"FUNCTION: TreeFileNode.cacheParent() {{{3
953
+"initializes self.parent if it isnt already
954
+function! s:TreeFileNode.cacheParent()
955
+    if empty(self.parent)
956
+        let parentPath = self.path.getParent()
957
+        if parentPath.equals(self.path)
958
+            throw "NERDTree.CannotCacheParentError: already at root"
959
+        endif
960
+        let self.parent = s:TreeFileNode.New(parentPath)
961
+    endif
962
+endfunction
963
+"FUNCTION: TreeFileNode.compareNodes {{{3
964
+"This is supposed to be a class level method but i cant figure out how to
965
+"get func refs to work from a dict..
966
+"
967
+"A class level method that compares two nodes
968
+"
969
+"Args:
970
+"n1, n2: the 2 nodes to compare
971
+function! s:compareNodes(n1, n2)
972
+    return a:n1.path.compareTo(a:n2.path)
973
+endfunction
974
+
975
+"FUNCTION: TreeFileNode.clearBookmarks() {{{3
976
+function! s:TreeFileNode.clearBookmarks()
977
+    for i in s:Bookmark.Bookmarks()
978
+        if i.path.equals(self.path)
979
+            call i.delete()
980
+        end
981
+    endfor
982
+    call self.path.cacheDisplayString()
983
+endfunction
984
+"FUNCTION: TreeFileNode.copy(dest) {{{3
985
+function! s:TreeFileNode.copy(dest)
986
+    call self.path.copy(a:dest)
987
+    let newPath = s:Path.New(a:dest)
988
+    let parent = b:NERDTreeRoot.findNode(newPath.getParent())
989
+    if !empty(parent)
990
+        call parent.refresh()
991
+        return parent.findNode(newPath)
992
+    else
993
+        return {}
994
+    endif
995
+endfunction
996
+
997
+"FUNCTION: TreeFileNode.delete {{{3
998
+"Removes this node from the tree and calls the Delete method for its path obj
999
+function! s:TreeFileNode.delete()
1000
+    call self.path.delete()
1001
+    call self.parent.removeChild(self)
1002
+endfunction
1003
+
1004
+"FUNCTION: TreeFileNode.displayString() {{{3
1005
+"
1006
+"Returns a string that specifies how the node should be represented as a
1007
+"string
1008
+"
1009
+"Return:
1010
+"a string that can be used in the view to represent this node
1011
+function! s:TreeFileNode.displayString()
1012
+    return self.path.displayString()
1013
+endfunction
1014
+
1015
+"FUNCTION: TreeFileNode.equals(treenode) {{{3
1016
+"
1017
+"Compares this treenode to the input treenode and returns 1 if they are the
1018
+"same node.
1019
+"
1020
+"Use this method instead of ==  because sometimes when the treenodes contain
1021
+"many children, vim seg faults when doing ==
1022
+"
1023
+"Args:
1024
+"treenode: the other treenode to compare to
1025
+function! s:TreeFileNode.equals(treenode)
1026
+    return self.path.str() ==# a:treenode.path.str()
1027
+endfunction
1028
+
1029
+"FUNCTION: TreeFileNode.findNode(path) {{{3
1030
+"Returns self if this node.path.Equals the given path.
1031
+"Returns {} if not equal.
1032
+"
1033
+"Args:
1034
+"path: the path object to compare against
1035
+function! s:TreeFileNode.findNode(path)
1036
+    if a:path.equals(self.path)
1037
+        return self
1038
+    endif
1039
+    return {}
1040
+endfunction
1041
+"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{3
1042
+"
1043
+"Finds the next sibling for this node in the indicated direction. This sibling
1044
+"must be a directory and may/may not have children as specified.
1045
+"
1046
+"Args:
1047
+"direction: 0 if you want to find the previous sibling, 1 for the next sibling
1048
+"
1049
+"Return:
1050
+"a treenode object or {} if no appropriate sibling could be found
1051
+function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction)
1052
+    "if we have no parent then we can have no siblings
1053
+    if self.parent != {}
1054
+        let nextSibling = self.findSibling(a:direction)
1055
+
1056
+        while nextSibling != {}
1057
+            if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen
1058
+                return nextSibling
1059
+            endif
1060
+            let nextSibling = nextSibling.findSibling(a:direction)
1061
+        endwhile
1062
+    endif
1063
+
1064
+    return {}
1065
+endfunction
1066
+"FUNCTION: TreeFileNode.findSibling(direction) {{{3
1067
+"
1068
+"Finds the next sibling for this node in the indicated direction
1069
+"
1070
+"Args:
1071
+"direction: 0 if you want to find the previous sibling, 1 for the next sibling
1072
+"
1073
+"Return:
1074
+"a treenode object or {} if no sibling could be found
1075
+function! s:TreeFileNode.findSibling(direction)
1076
+    "if we have no parent then we can have no siblings
1077
+    if self.parent != {}
1078
+
1079
+        "get the index of this node in its parents children
1080
+        let siblingIndx = self.parent.getChildIndex(self.path)
1081
+
1082
+        if siblingIndx != -1
1083
+            "move a long to the next potential sibling node
1084
+            let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
1085
+
1086
+            "keep moving along to the next sibling till we find one that is valid
1087
+            let numSiblings = self.parent.getChildCount()
1088
+            while siblingIndx >= 0 && siblingIndx < numSiblings
1089
+
1090
+                "if the next node is not an ignored node (i.e. wont show up in the
1091
+                "view) then return it
1092
+                if self.parent.children[siblingIndx].path.ignore() ==# 0
1093
+                    return self.parent.children[siblingIndx]
1094
+                endif
1095
+
1096
+                "go to next node
1097
+                let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
1098
+            endwhile
1099
+        endif
1100
+    endif
1101
+
1102
+    return {}
1103
+endfunction
1104
+
1105
+"FUNCTION: TreeFileNode.getLineNum(){{{3
1106
+"returns the line number this node is rendered on, or -1 if it isnt rendered
1107
+function! s:TreeFileNode.getLineNum()
1108
+    "if the node is the root then return the root line no.
1109
+    if self.isRoot()
1110
+        return s:TreeFileNode.GetRootLineNum()
1111
+    endif
1112
+
1113
+    let totalLines = line("$")
1114
+
1115
+    "the path components we have matched so far
1116
+    let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
1117
+    "the index of the component we are searching for
1118
+    let curPathComponent = 1
1119
+
1120
+    let fullpath = self.path.str({'format': 'UI'})
1121
+
1122
+
1123
+    let lnum = s:TreeFileNode.GetRootLineNum()
1124
+    while lnum > 0
1125
+        let lnum = lnum + 1
1126
+        "have we reached the bottom of the tree?
1127
+        if lnum ==# totalLines+1
1128
+            return -1
1129
+        endif
1130
+
1131
+        let curLine = getline(lnum)
1132
+
1133
+        let indent = s:indentLevelFor(curLine)
1134
+        if indent ==# curPathComponent
1135
+            let curLine = s:stripMarkupFromLine(curLine, 1)
1136
+
1137
+            let curPath =  join(pathcomponents, '/') . '/' . curLine
1138
+            if stridx(fullpath, curPath, 0) ==# 0
1139
+                if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
1140
+                    let curLine = substitute(curLine, '/ *$', '', '')
1141
+                    call add(pathcomponents, curLine)
1142
+                    let curPathComponent = curPathComponent + 1
1143
+
1144
+                    if fullpath ==# curPath
1145
+                        return lnum
1146
+                    endif
1147
+                endif
1148
+            endif
1149
+        endif
1150
+    endwhile
1151
+    return -1
1152
+endfunction
1153
+
1154
+"FUNCTION: TreeFileNode.GetRootForTab(){{{3
1155
+"get the root node for this tab
1156
+function! s:TreeFileNode.GetRootForTab()
1157
+    if s:treeExistsForTab()
1158
+        return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
1159
+    end
1160
+    return {}
1161
+endfunction
1162
+"FUNCTION: TreeFileNode.GetRootLineNum(){{{3
1163
+"gets the line number of the root node
1164
+function! s:TreeFileNode.GetRootLineNum()
1165
+    let rootLine = 1
1166
+    while getline(rootLine) !~# '^\(/\|<\)'
1167
+        let rootLine = rootLine + 1
1168
+    endwhile
1169
+    return rootLine
1170
+endfunction
1171
+
1172
+"FUNCTION: TreeFileNode.GetSelected() {{{3
1173
+"gets the treenode that the cursor is currently over
1174
+function! s:TreeFileNode.GetSelected()
1175
+    try
1176
+        let path = s:getPath(line("."))
1177
+        if path ==# {}
1178
+            return {}
1179
+        endif
1180
+        return b:NERDTreeRoot.findNode(path)
1181
+    catch /NERDTree/
1182
+        return {}
1183
+    endtry
1184
+endfunction
1185
+"FUNCTION: TreeFileNode.isVisible() {{{3
1186
+"returns 1 if this node should be visible according to the tree filters and
1187
+"hidden file filters (and their on/off status)
1188
+function! s:TreeFileNode.isVisible()
1189
+    return !self.path.ignore()
1190
+endfunction
1191
+"FUNCTION: TreeFileNode.isRoot() {{{3
1192
+"returns 1 if this node is b:NERDTreeRoot
1193
+function! s:TreeFileNode.isRoot()
1194
+    if !s:treeExistsForBuf()
1195
+        throw "NERDTree.NoTreeError: No tree exists for the current buffer"
1196
+    endif
1197
+
1198
+    return self.equals(b:NERDTreeRoot)
1199
+endfunction
1200
+
1201
+"FUNCTION: TreeFileNode.makeRoot() {{{3
1202
+"Make this node the root of the tree
1203
+function! s:TreeFileNode.makeRoot()
1204
+    if self.path.isDirectory
1205
+        let b:NERDTreeRoot = self
1206
+    else
1207
+        call self.cacheParent()
1208
+        let b:NERDTreeRoot = self.parent
1209
+    endif
1210
+
1211
+    call b:NERDTreeRoot.open()
1212
+
1213
+    "change dir to the dir of the new root if instructed to
1214
+    if g:NERDTreeChDirMode ==# 2
1215
+        exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'})
1216
+    endif
1217
+
1218
+    silent doautocmd User NERDTreeNewRoot
1219
+endfunction
1220
+"FUNCTION: TreeFileNode.New(path) {{{3
1221
+"Returns a new TreeNode object with the given path and parent
1222
+"
1223
+"Args:
1224
+"path: a path object representing the full filesystem path to the file/dir that the node represents
1225
+function! s:TreeFileNode.New(path)
1226
+    if a:path.isDirectory
1227
+        return s:TreeDirNode.New(a:path)
1228
+    else
1229
+        let newTreeNode = copy(self)
1230
+        let newTreeNode.path = a:path
1231
+        let newTreeNode.parent = {}
1232
+        return newTreeNode
1233
+    endif
1234
+endfunction
1235
+
1236
+"FUNCTION: TreeFileNode.open() {{{3
1237
+function! s:TreeFileNode.open(...)
1238
+    let opts = a:0 ? a:1 : {}
1239
+    let opener = s:Opener.New(self.path, opts)
1240
+    call opener.open(self)
1241
+endfunction
1242
+
1243
+"FUNCTION: TreeFileNode.openSplit() {{{3
1244
+"Open this node in a new window
1245
+function! s:TreeFileNode.openSplit()
1246
+    call s:deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.')
1247
+    call self.open({'where': 'h'})
1248
+endfunction
1249
+"FUNCTION: TreeFileNode.openVSplit() {{{3
1250
+"Open this node in a new vertical window
1251
+function! s:TreeFileNode.openVSplit()
1252
+    call s:deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.')
1253
+    call self.open({'where': 'v'})
1254
+endfunction
1255
+"FUNCTION: TreeFileNode.openInNewTab(options) {{{3
1256
+function! s:TreeFileNode.openInNewTab(options)
1257
+    echomsg 'TreeFileNode.openInNewTab is deprecated'
1258
+    call self.open(extend({'where': 't'}, a:options))
1259
+endfunction
1260
+"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{3
1261
+"Places the cursor on the line number this node is rendered on
1262
+"
1263
+"Args:
1264
+"isJump: 1 if this cursor movement should be counted as a jump by vim
1265
+"recurseUpward: try to put the cursor on the parent if the this node isnt
1266
+"visible
1267
+function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
1268
+    let ln = self.getLineNum()
1269
+    if ln != -1
1270
+        if a:isJump
1271
+            mark '
1272
+        endif
1273
+        call cursor(ln, col("."))
1274
+    else
1275
+        if a:recurseUpward
1276
+            let node = self
1277
+            while node != {} && node.getLineNum() ==# -1
1278
+                let node = node.parent
1279
+                call node.open()
1280
+            endwhile
1281
+            call s:renderView()
1282
+            call node.putCursorHere(a:isJump, 0)
1283
+        endif
1284
+    endif
1285
+endfunction
1286
+
1287
+"FUNCTION: TreeFileNode.refresh() {{{3
1288
+function! s:TreeFileNode.refresh()
1289
+    call self.path.refresh()
1290
+endfunction
1291
+"FUNCTION: TreeFileNode.rename() {{{3
1292
+"Calls the rename method for this nodes path obj
1293
+function! s:TreeFileNode.rename(newName)
1294
+    let newName = substitute(a:newName, '\(\\\|\/\)$', '', '')
1295
+    call self.path.rename(newName)
1296
+    call self.parent.removeChild(self)
1297
+
1298
+    let parentPath = self.path.getParent()
1299
+    let newParent = b:NERDTreeRoot.findNode(parentPath)
1300
+
1301
+    if newParent != {}
1302
+        call newParent.createChild(self.path, 1)
1303
+        call newParent.refresh()
1304
+    endif
1305
+endfunction
1306
+"FUNCTION: TreeFileNode.renderToString {{{3
1307
+"returns a string representation for this tree to be rendered in the view
1308
+function! s:TreeFileNode.renderToString()
1309
+    return self._renderToString(0, 0, [], self.getChildCount() ==# 1)
1310
+endfunction
1311
+
1312
+
1313
+"Args:
1314
+"depth: the current depth in the tree for this call
1315
+"drawText: 1 if we should actually draw the line for this node (if 0 then the
1316
+"child nodes are rendered only)
1317
+"vertMap: a binary array that indicates whether a vertical bar should be draw
1318
+"for each depth in the tree
1319
+"isLastChild:true if this curNode is the last child of its parent
1320
+function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
1321
+    let output = ""
1322
+    if a:drawText ==# 1
1323
+
1324
+        let treeParts = ''
1325
+
1326
+        "get all the leading spaces and vertical tree parts for this line
1327
+        if a:depth > 1
1328
+            for j in a:vertMap[0:-2]
1329
+                if g:NERDTreeDirArrows
1330
+                    let treeParts = treeParts . '  '
1331
+                else
1332
+                    if j ==# 1
1333
+                        let treeParts = treeParts . '| '
1334
+                    else
1335
+                        let treeParts = treeParts . '  '
1336
+                    endif
1337
+                endif
1338
+            endfor
1339
+        endif
1340
+
1341
+        "get the last vertical tree part for this line which will be different
1342
+        "if this node is the last child of its parent
1343
+        if !g:NERDTreeDirArrows
1344
+            if a:isLastChild
1345
+                let treeParts = treeParts . '`'
1346
+            else
1347
+                let treeParts = treeParts . '|'
1348
+            endif
1349
+        endif
1350
+
1351
+        "smack the appropriate dir/file symbol on the line before the file/dir
1352
+        "name itself
1353
+        if self.path.isDirectory
1354
+            if self.isOpen
1355
+                if g:NERDTreeDirArrows
1356
+                    let treeParts = treeParts . 'â–¾ '
1357
+                else
1358
+                    let treeParts = treeParts . '~'
1359
+                endif
1360
+            else
1361
+                if g:NERDTreeDirArrows
1362
+                    let treeParts = treeParts . 'â–¸ '
1363
+                else
1364
+                    let treeParts = treeParts . '+'
1365
+                endif
1366
+            endif
1367
+        else
1368
+            if g:NERDTreeDirArrows
1369
+                let treeParts = treeParts . '  '
1370
+            else
1371
+                let treeParts = treeParts . '-'
1372
+            endif
1373
+        endif
1374
+        let line = treeParts . self.displayString()
1375
+
1376
+        let output = output . line . "\n"
1377
+    endif
1378
+
1379
+    "if the node is an open dir, draw its children
1380
+    if self.path.isDirectory ==# 1 && self.isOpen ==# 1
1381
+
1382
+        let childNodesToDraw = self.getVisibleChildren()
1383
+        if len(childNodesToDraw) > 0
1384
+
1385
+            "draw all the nodes children except the last
1386
+            let lastIndx = len(childNodesToDraw)-1
1387
+            if lastIndx > 0
1388
+                for i in childNodesToDraw[0:lastIndx-1]
1389
+                    let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0)
1390
+                endfor
1391
+            endif
1392
+
1393
+            "draw the last child, indicating that it IS the last
1394
+            let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
1395
+        endif
1396
+    endif
1397
+
1398
+    return output
1399
+endfunction
1400
+"CLASS: TreeDirNode {{{2
1401
+"This class is a child of the TreeFileNode class and constitutes the
1402
+"'Composite' part of the composite design pattern between the treenode
1403
+"classes.
1404
+"============================================================
1405
+let s:TreeDirNode = copy(s:TreeFileNode)
1406
+"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{3
1407
+"class method that returns the highest cached ancestor of the current root
1408
+function! s:TreeDirNode.AbsoluteTreeRoot()
1409
+    let currentNode = b:NERDTreeRoot
1410
+    while currentNode.parent != {}
1411
+        let currentNode = currentNode.parent
1412
+    endwhile
1413
+    return currentNode
1414
+endfunction
1415
+"FUNCTION: TreeDirNode.activate([options]) {{{3
1416
+unlet s:TreeDirNode.activate
1417
+function! s:TreeDirNode.activate(...)
1418
+    let opts = a:0 ? a:1 : {}
1419
+    call self.toggleOpen(opts)
1420
+    call s:renderView()
1421
+    call self.putCursorHere(0, 0)
1422
+endfunction
1423
+"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{3
1424
+"Adds the given treenode to the list of children for this node
1425
+"
1426
+"Args:
1427
+"-treenode: the node to add
1428
+"-inOrder: 1 if the new node should be inserted in sorted order
1429
+function! s:TreeDirNode.addChild(treenode, inOrder)
1430
+    call add(self.children, a:treenode)
1431
+    let a:treenode.parent = self
1432
+
1433
+    if a:inOrder
1434
+        call self.sortChildren()
1435
+    endif
1436
+endfunction
1437
+
1438
+"FUNCTION: TreeDirNode.close() {{{3
1439
+"Closes this directory
1440
+function! s:TreeDirNode.close()
1441
+    let self.isOpen = 0
1442
+endfunction
1443
+
1444
+"FUNCTION: TreeDirNode.closeChildren() {{{3
1445
+"Closes all the child dir nodes of this node
1446
+function! s:TreeDirNode.closeChildren()
1447
+    for i in self.children
1448
+        if i.path.isDirectory
1449
+            call i.close()
1450
+            call i.closeChildren()
1451
+        endif
1452
+    endfor
1453
+endfunction
1454
+
1455
+"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{3
1456
+"Instantiates a new child node for this node with the given path. The new
1457
+"nodes parent is set to this node.
1458
+"
1459
+"Args:
1460
+"path: a Path object that this node will represent/contain
1461
+"inOrder: 1 if the new node should be inserted in sorted order
1462
+"
1463
+"Returns:
1464
+"the newly created node
1465
+function! s:TreeDirNode.createChild(path, inOrder)
1466
+    let newTreeNode = s:TreeFileNode.New(a:path)
1467
+    call self.addChild(newTreeNode, a:inOrder)
1468
+    return newTreeNode
1469
+endfunction
1470
+
1471
+"FUNCTION: TreeDirNode.findNode(path) {{{3
1472
+"Will find one of the children (recursively) that has the given path
1473
+"
1474
+"Args:
1475
+"path: a path object
1476
+unlet s:TreeDirNode.findNode
1477
+function! s:TreeDirNode.findNode(path)
1478
+    if a:path.equals(self.path)
1479
+        return self
1480
+    endif
1481
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
1482
+        return {}
1483
+    endif
1484
+
1485
+    if self.path.isDirectory
1486
+        for i in self.children
1487
+            let retVal = i.findNode(a:path)
1488
+            if retVal != {}
1489
+                return retVal
1490
+            endif
1491
+        endfor
1492
+    endif
1493
+    return {}
1494
+endfunction
1495
+"FUNCTION: TreeDirNode.getChildCount() {{{3
1496
+"Returns the number of children this node has
1497
+function! s:TreeDirNode.getChildCount()
1498
+    return len(self.children)
1499
+endfunction
1500
+
1501
+"FUNCTION: TreeDirNode.getChild(path) {{{3
1502
+"Returns child node of this node that has the given path or {} if no such node
1503
+"exists.
1504
+"
1505
+"This function doesnt not recurse into child dir nodes
1506
+"
1507
+"Args:
1508
+"path: a path object
1509
+function! s:TreeDirNode.getChild(path)
1510
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
1511
+        return {}
1512
+    endif
1513
+
1514
+    let index = self.getChildIndex(a:path)
1515
+    if index ==# -1
1516
+        return {}
1517
+    else
1518
+        return self.children[index]
1519
+    endif
1520
+
1521
+endfunction
1522
+
1523
+"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{3
1524
+"returns the child at the given index
1525
+"Args:
1526
+"indx: the index to get the child from
1527
+"visible: 1 if only the visible children array should be used, 0 if all the
1528
+"children should be searched.
1529
+function! s:TreeDirNode.getChildByIndex(indx, visible)
1530
+    let array_to_search = a:visible? self.getVisibleChildren() : self.children
1531
+    if a:indx > len(array_to_search)
1532
+        throw "NERDTree.InvalidArgumentsError: Index is out of bounds."
1533
+    endif
1534
+    return array_to_search[a:indx]
1535
+endfunction
1536
+
1537
+"FUNCTION: TreeDirNode.getChildIndex(path) {{{3
1538
+"Returns the index of the child node of this node that has the given path or
1539
+"-1 if no such node exists.
1540
+"
1541
+"This function doesnt not recurse into child dir nodes
1542
+"
1543
+"Args:
1544
+"path: a path object
1545
+function! s:TreeDirNode.getChildIndex(path)
1546
+    if stridx(a:path.str(), self.path.str(), 0) ==# -1
1547
+        return -1
1548
+    endif
1549
+
1550
+    "do a binary search for the child
1551
+    let a = 0
1552
+    let z = self.getChildCount()
1553
+    while a < z
1554
+        let mid = (a+z)/2
1555
+        let diff = a:path.compareTo(self.children[mid].path)
1556
+
1557
+        if diff ==# -1
1558
+            let z = mid
1559
+        elseif diff ==# 1
1560
+            let a = mid+1
1561
+        else
1562
+            return mid
1563
+        endif
1564
+    endwhile
1565
+    return -1
1566
+endfunction
1567
+
1568
+"FUNCTION: TreeDirNode.GetSelected() {{{3
1569
+"Returns the current node if it is a dir node, or else returns the current
1570
+"nodes parent
1571
+unlet s:TreeDirNode.GetSelected
1572
+function! s:TreeDirNode.GetSelected()
1573
+    let currentDir = s:TreeFileNode.GetSelected()
1574
+    if currentDir != {} && !currentDir.isRoot()
1575
+        if currentDir.path.isDirectory ==# 0
1576
+            let currentDir = currentDir.parent
1577
+        endif
1578
+    endif
1579
+    return currentDir
1580
+endfunction
1581
+"FUNCTION: TreeDirNode.getVisibleChildCount() {{{3
1582
+"Returns the number of visible children this node has
1583
+function! s:TreeDirNode.getVisibleChildCount()
1584
+    return len(self.getVisibleChildren())
1585
+endfunction
1586
+
1587
+"FUNCTION: TreeDirNode.getVisibleChildren() {{{3
1588
+"Returns a list of children to display for this node, in the correct order
1589
+"
1590
+"Return:
1591
+"an array of treenodes
1592
+function! s:TreeDirNode.getVisibleChildren()
1593
+    let toReturn = []
1594
+    for i in self.children
1595
+        if i.path.ignore() ==# 0
1596
+            call add(toReturn, i)
1597
+        endif
1598
+    endfor
1599
+    return toReturn
1600
+endfunction
1601
+
1602
+"FUNCTION: TreeDirNode.hasVisibleChildren() {{{3
1603
+"returns 1 if this node has any childre, 0 otherwise..
1604
+function! s:TreeDirNode.hasVisibleChildren()
1605
+    return self.getVisibleChildCount() != 0
1606
+endfunction
1607
+
1608
+"FUNCTION: TreeDirNode._initChildren() {{{3
1609
+"Removes all childen from this node and re-reads them
1610
+"
1611
+"Args:
1612
+"silent: 1 if the function should not echo any "please wait" messages for
1613
+"large directories
1614
+"
1615
+"Return: the number of child nodes read
1616
+function! s:TreeDirNode._initChildren(silent)
1617
+    "remove all the current child nodes
1618
+    let self.children = []
1619
+
1620
+    "get an array of all the files in the nodes dir
1621
+    let dir = self.path
1622
+    let globDir = dir.str({'format': 'Glob'})
1623
+
1624
+    if version >= 703
1625
+        let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1)
1626
+    else
1627
+        let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
1628
+    endif
1629
+
1630
+    let files = split(filesStr, "\n")
1631
+
1632
+    if !a:silent && len(files) > g:NERDTreeNotificationThreshold
1633
+        call s:echo("Please wait, caching a large dir ...")
1634
+    endif
1635
+
1636
+    let invalidFilesFound = 0
1637
+    for i in files
1638
+
1639
+        "filter out the .. and . directories
1640
+        "Note: we must match .. AND ../ cos sometimes the globpath returns
1641
+        "../ for path with strange chars (eg $)
1642
+        if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
1643
+
1644
+            "put the next file in a new node and attach it
1645
+            try
1646
+                let path = s:Path.New(i)
1647
+                call self.createChild(path, 0)
1648
+            catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
1649
+                let invalidFilesFound += 1
1650
+            endtry
1651
+        endif
1652
+    endfor
1653
+
1654
+    call self.sortChildren()
1655
+
1656
+    if !a:silent && len(files) > g:NERDTreeNotificationThreshold
1657
+        call s:echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).")
1658
+    endif
1659
+
1660
+    if invalidFilesFound
1661
+        call s:echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree")
1662
+    endif
1663
+    return self.getChildCount()
1664
+endfunction
1665
+"FUNCTION: TreeDirNode.New(path) {{{3
1666
+"Returns a new TreeNode object with the given path and parent
1667
+"
1668
+"Args:
1669
+"path: a path object representing the full filesystem path to the file/dir that the node represents
1670
+unlet s:TreeDirNode.New
1671
+function! s:TreeDirNode.New(path)
1672
+    if a:path.isDirectory != 1
1673
+        throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object."
1674
+    endif
1675
+
1676
+    let newTreeNode = copy(self)
1677
+    let newTreeNode.path = a:path
1678
+
1679
+    let newTreeNode.isOpen = 0
1680
+    let newTreeNode.children = []
1681
+
1682
+    let newTreeNode.parent = {}
1683
+
1684
+    return newTreeNode
1685
+endfunction
1686
+"FUNCTION: TreeDirNode.open([opts]) {{{3
1687
+"Open the dir in the current tree or in a new tree elsewhere.
1688
+"
1689
+"If opening in the current tree, return the number of cached nodes.
1690
+unlet s:TreeDirNode.open
1691
+function! s:TreeDirNode.open(...)
1692
+    let opts = a:0 ? a:1 : {}
1693
+
1694
+    if has_key(opts, 'where') && !empty(opts['where'])
1695
+        let opener = s:Opener.New(self.path, opts)
1696
+        call opener.open(self)
1697
+    else
1698
+        let self.isOpen = 1
1699
+        if self.children ==# []
1700
+            return self._initChildren(0)
1701
+        else
1702
+            return 0
1703
+        endif
1704
+    endif
1705
+endfunction
1706
+"FUNCTION: TreeDirNode.openAlong([opts]) {{{3
1707
+"recursive open the dir if it has only one directory child.
1708
+"
1709
+"return the level of opened directories.
1710
+function! s:TreeDirNode.openAlong(...)
1711
+    let opts = a:0 ? a:1 : {}
1712
+    let level = 0
1713
+
1714
+    let node = self
1715
+    while node.path.isDirectory
1716
+        call node.open(opts)
1717
+        let level += 1
1718
+        if node.getVisibleChildCount() == 1
1719
+            let node = node.getChildByIndex(0, 1)
1720
+        else
1721
+            break
1722
+        endif
1723
+    endwhile
1724
+    return level
1725
+endfunction
1726
+" FUNCTION: TreeDirNode.openExplorer() {{{3
1727
+" opens an explorer window for this node in the previous window (could be a
1728
+" nerd tree or a netrw)
1729
+function! s:TreeDirNode.openExplorer()
1730
+    call self.open({'where': 'p'})
1731
+endfunction
1732
+"FUNCTION: TreeDirNode.openInNewTab(options) {{{3
1733
+unlet s:TreeDirNode.openInNewTab
1734
+function! s:TreeDirNode.openInNewTab(options)
1735
+    call s:deprecated('TreeDirNode.openInNewTab', 'is deprecated, use open() instead')
1736
+    call self.open({'where': 't'})
1737
+endfunction
1738
+"FUNCTION: TreeDirNode._openInNewTab() {{{3
1739
+function! s:TreeDirNode._openInNewTab()
1740
+    tabnew
1741
+    call s:initNerdTree(self.path.str())
1742
+endfunction
1743
+"FUNCTION: TreeDirNode.openRecursively() {{{3
1744
+"Opens this treenode and all of its children whose paths arent 'ignored'
1745
+"because of the file filters.
1746
+"
1747
+"This method is actually a wrapper for the OpenRecursively2 method which does
1748
+"the work.
1749
+function! s:TreeDirNode.openRecursively()
1750
+    call self._openRecursively2(1)
1751
+endfunction
1752
+
1753
+"FUNCTION: TreeDirNode._openRecursively2() {{{3
1754
+"Opens this all children of this treenode recursively if either:
1755
+"   *they arent filtered by file filters
1756
+"   *a:forceOpen is 1
1757
+"
1758
+"Args:
1759
+"forceOpen: 1 if this node should be opened regardless of file filters
1760
+function! s:TreeDirNode._openRecursively2(forceOpen)
1761
+    if self.path.ignore() ==# 0 || a:forceOpen
1762
+        let self.isOpen = 1
1763
+        if self.children ==# []
1764
+            call self._initChildren(1)
1765
+        endif
1766
+
1767
+        for i in self.children
1768
+            if i.path.isDirectory ==# 1
1769
+                call i._openRecursively2(0)
1770
+            endif
1771
+        endfor
1772
+    endif
1773
+endfunction
1774
+
1775
+"FUNCTION: TreeDirNode.refresh() {{{3
1776
+unlet s:TreeDirNode.refresh
1777
+function! s:TreeDirNode.refresh()
1778
+    call self.path.refresh()
1779
+
1780
+    "if this node was ever opened, refresh its children
1781
+    if self.isOpen || !empty(self.children)
1782
+        "go thru all the files/dirs under this node
1783
+        let newChildNodes = []
1784
+        let invalidFilesFound = 0
1785
+        let dir = self.path
1786
+        let globDir = dir.str({'format': 'Glob'})
1787
+        let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
1788
+        let files = split(filesStr, "\n")
1789
+        for i in files
1790
+            "filter out the .. and . directories
1791
+            "Note: we must match .. AND ../ cos sometimes the globpath returns
1792
+            "../ for path with strange chars (eg $)
1793
+            if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
1794
+
1795
+                try
1796
+                    "create a new path and see if it exists in this nodes children
1797
+                    let path = s:Path.New(i)
1798
+                    let newNode = self.getChild(path)
1799
+                    if newNode != {}
1800
+                        call newNode.refresh()
1801
+                        call add(newChildNodes, newNode)
1802
+
1803
+                    "the node doesnt exist so create it
1804
+                    else
1805
+                        let newNode = s:TreeFileNode.New(path)
1806
+                        let newNode.parent = self
1807
+                        call add(newChildNodes, newNode)
1808
+                    endif
1809
+
1810
+
1811
+                catch /^NERDTree.InvalidArgumentsError/
1812
+                    let invalidFilesFound = 1
1813
+                endtry
1814
+            endif
1815
+        endfor
1816
+
1817
+        "swap this nodes children out for the children we just read/refreshed
1818
+        let self.children = newChildNodes
1819
+        call self.sortChildren()
1820
+
1821
+        if invalidFilesFound
1822
+            call s:echoWarning("some files could not be loaded into the NERD tree")
1823
+        endif
1824
+    endif
1825
+endfunction
1826
+
1827
+"FUNCTION: TreeDirNode.reveal(path) {{{3
1828
+"reveal the given path, i.e. cache and open all treenodes needed to display it
1829
+"in the UI
1830
+function! s:TreeDirNode.reveal(path)
1831
+    if !a:path.isUnder(self.path)
1832
+        throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str()
1833
+    endif
1834
+
1835
+    call self.open()
1836
+
1837
+    if self.path.equals(a:path.getParent())
1838
+        let n = self.findNode(a:path)
1839
+        call s:renderView()
1840
+        call n.putCursorHere(1,0)
1841
+        return
1842
+    endif
1843
+
1844
+    let p = a:path
1845
+    while !p.getParent().equals(self.path)
1846
+        let p = p.getParent()
1847
+    endwhile
1848
+
1849
+    let n = self.findNode(p)
1850
+    call n.reveal(a:path)
1851
+endfunction
1852
+"FUNCTION: TreeDirNode.removeChild(treenode) {{{3
1853
+"
1854
+"Removes the given treenode from this nodes set of children
1855
+"
1856
+"Args:
1857
+"treenode: the node to remove
1858
+"
1859
+"Throws a NERDTree.ChildNotFoundError if the given treenode is not found
1860
+function! s:TreeDirNode.removeChild(treenode)
1861
+    for i in range(0, self.getChildCount()-1)
1862
+        if self.children[i].equals(a:treenode)
1863
+            call remove(self.children, i)
1864
+            return
1865
+        endif
1866
+    endfor
1867
+
1868
+    throw "NERDTree.ChildNotFoundError: child node was not found"
1869
+endfunction
1870
+
1871
+"FUNCTION: TreeDirNode.sortChildren() {{{3
1872
+"
1873
+"Sorts the children of this node according to alphabetical order and the
1874
+"directory priority.
1875
+"
1876
+function! s:TreeDirNode.sortChildren()
1877
+    let CompareFunc = function("s:compareNodes")
1878
+    call sort(self.children, CompareFunc)
1879
+endfunction
1880
+
1881
+"FUNCTION: TreeDirNode.toggleOpen([options]) {{{3
1882
+"Opens this directory if it is closed and vice versa
1883
+function! s:TreeDirNode.toggleOpen(...)
1884
+    let opts = a:0 ? a:1 : {}
1885
+    if self.isOpen ==# 1
1886
+        call self.close()
1887
+    else
1888
+        if g:NERDTreeCasadeOpenSingleChildDir == 0
1889
+            call self.open(opts)
1890
+        else
1891
+            call self.openAlong(opts)
1892
+        endif
1893
+    endif
1894
+endfunction
1895
+"FUNCTION: TreeDirNode.transplantChild(newNode) {{{3
1896
+"Replaces the child of this with the given node (where the child node's full
1897
+"path matches a:newNode's fullpath). The search for the matching node is
1898
+"non-recursive
1899
+"
1900
+"Arg:
1901
+"newNode: the node to graft into the tree
1902
+function! s:TreeDirNode.transplantChild(newNode)
1903
+    for i in range(0, self.getChildCount()-1)
1904
+        if self.children[i].equals(a:newNode)
1905
+            let self.children[i] = a:newNode
1906
+            let a:newNode.parent = self
1907
+            break
1908
+        endif
1909
+    endfor
1910
+endfunction
1911
+"============================================================
1912
+"CLASS: Opener {{{2
1913
+"============================================================
1914
+let s:Opener = {}
1915
+
1916
+"FUNCTION: Opener._checkToCloseTree(newtab) {{{3
1917
+"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
1918
+"if the tree should be closed now.
1919
+"
1920
+"Args:
1921
+"a:newtab - boolean. If set, only close the tree now if we are opening the
1922
+"target in a new tab. This is needed because we have to close tree before we
1923
+"leave the tab
1924
+function! s:Opener._checkToCloseTree(newtab)
1925
+    if self._keepopen
1926
+        return
1927
+    endif
1928
+
1929
+    if (a:newtab && self._where == 't') || !a:newtab
1930
+        call s:closeTreeIfQuitOnOpen()
1931
+    endif
1932
+endfunction
1933
+
1934
+"FUNCTION: Opener._gotoTargetWin() {{{3
1935
+function! s:Opener._gotoTargetWin()
1936
+    if b:NERDTreeType ==# "secondary"
1937
+        if self._where == 'v'
1938
+            vsplit
1939
+        elseif self._where == 'h'
1940
+            split
1941
+        elseif self._where == 't'
1942
+            tabnew
1943
+        endif
1944
+    else
1945
+        call self._checkToCloseTree(1)
1946
+
1947
+        if self._where == 'v'
1948
+            call self._newVSplit()
1949
+        elseif self._where == 'h'
1950
+            call self._newSplit()
1951
+        elseif self._where == 't'
1952
+            tabnew
1953
+        elseif self._where == 'p'
1954
+            call self._previousWindow()
1955
+        endif
1956
+
1957
+        call self._checkToCloseTree(0)
1958
+    endif
1959
+endfunction
1960
+
1961
+"FUNCTION: Opener.New(path, opts) {{{3
1962
+"Args:
1963
+"
1964
+"a:path: The path object that is to be opened.
1965
+"
1966
+"a:opts:
1967
+"
1968
+"A dictionary containing the following keys (all optional):
1969
+"  'where': Specifies whether the node should be opened in new split/tab or in
1970
+"           the previous window. Can be either 'v' or 'h' or 't' (for open in
1971
+"           new tab)
1972
+"  'reuse': if a window is displaying the file then jump the cursor there
1973
+"  'keepopen': dont close the tree window
1974
+"  'stay': open the file, but keep the cursor in the tree win
1975
+function! s:Opener.New(path, opts)
1976
+    let newObj = copy(self)
1977
+
1978
+    let newObj._path = a:path
1979
+    let newObj._stay = s:has_opt(a:opts, 'stay')
1980
+    let newObj._reuse = s:has_opt(a:opts, 'reuse')
1981
+    let newObj._keepopen = s:has_opt(a:opts, 'keepopen')
1982
+    let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
1983
+    let newObj._treetype = b:NERDTreeType
1984
+    call newObj._saveCursorPos()
1985
+
1986
+    return newObj
1987
+endfunction
1988
+
1989
+"FUNCTION: Opener._newSplit() {{{3
1990
+function! s:Opener._newSplit()
1991
+    " Save the user's settings for splitbelow and splitright
1992
+    let savesplitbelow=&splitbelow
1993
+    let savesplitright=&splitright
1994
+
1995
+    " 'there' will be set to a command to move from the split window
1996
+    " back to the explorer window
1997
+    "
1998
+    " 'back' will be set to a command to move from the explorer window
1999
+    " back to the newly split window
2000
+    "
2001
+    " 'right' and 'below' will be set to the settings needed for
2002
+    " splitbelow and splitright IF the explorer is the only window.
2003
+    "
2004
+    let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l"
2005
+    let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h"
2006
+    let right= g:NERDTreeWinPos ==# "left"
2007
+    let below=0
2008
+
2009
+    " Attempt to go to adjacent window
2010
+    call s:exec(back)
2011
+
2012
+    let onlyOneWin = (winnr("$") ==# 1)
2013
+
2014
+    " If no adjacent window, set splitright and splitbelow appropriately
2015
+    if onlyOneWin
2016
+        let &splitright=right
2017
+        let &splitbelow=below
2018
+    else
2019
+        " found adjacent window - invert split direction
2020
+        let &splitright=!right
2021
+        let &splitbelow=!below
2022
+    endif
2023
+
2024
+    let splitMode = onlyOneWin ? "vertical" : ""
2025
+
2026
+    " Open the new window
2027
+    try
2028
+        exec(splitMode." sp ")
2029
+    catch /^Vim\%((\a\+)\)\=:E37/
2030
+        call s:putCursorInTreeWin()
2031
+        throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
2032
+    catch /^Vim\%((\a\+)\)\=:/
2033
+        "do nothing
2034
+    endtry
2035
+
2036
+    "resize the tree window if no other window was open before
2037
+    if onlyOneWin
2038
+        let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
2039
+        call s:exec(there)
2040
+        exec("silent ". splitMode ." resize ". size)
2041
+        call s:exec('wincmd p')
2042
+    endif
2043
+
2044
+    " Restore splitmode settings
2045
+    let &splitbelow=savesplitbelow
2046
+    let &splitright=savesplitright
2047
+endfunction
2048
+
2049
+"FUNCTION: Opener._newVSplit() {{{3
2050
+function! s:Opener._newVSplit()
2051
+    let winwidth = winwidth(".")
2052
+    if winnr("$")==#1
2053
+        let winwidth = g:NERDTreeWinSize
2054
+    endif
2055
+
2056
+    call s:exec("wincmd p")
2057
+    vnew
2058
+
2059
+    "resize the nerd tree back to the original size
2060
+    call s:putCursorInTreeWin()
2061
+    exec("silent vertical resize ". winwidth)
2062
+    call s:exec('wincmd p')
2063
+endfunction
2064
+
2065
+"FUNCTION: Opener.open(target) {{{3
2066
+function! s:Opener.open(target)
2067
+    if self._path.isDirectory
2068
+        call self._openDirectory(a:target)
2069
+    else
2070
+        call self._openFile()
2071
+    endif
2072
+endfunction
2073
+
2074
+"FUNCTION: Opener._openFile() {{{3
2075
+function! s:Opener._openFile()
2076
+    if self._reuse && self._reuseWindow()
2077
+        return
2078
+    endif
2079
+
2080
+    call self._gotoTargetWin()
2081
+
2082
+    if self._treetype ==# "secondary"
2083
+        call self._path.edit()
2084
+    else
2085
+        call self._path.edit()
2086
+
2087
+
2088
+        if self._stay
2089
+            call self._restoreCursorPos()
2090
+        endif
2091
+    endif
2092
+endfunction
2093
+
2094
+"FUNCTION: Opener._openDirectory(node) {{{3
2095
+function! s:Opener._openDirectory(node)
2096
+    if self._treetype ==# "secondary"
2097
+        call self._gotoTargetWin()
2098
+        call s:initNerdTreeInPlace(a:node.path.str())
2099
+    else
2100
+        call self._gotoTargetWin()
2101
+        if empty(self._where)
2102
+            call a:node.makeRoot()
2103
+            call s:renderView()
2104
+            call a:node.putCursorHere(0, 0)
2105
+        elseif self._where == 't'
2106
+            call s:initNerdTree(a:node.path.str())
2107
+        else
2108
+            call s:initNerdTreeInPlace(a:node.path.str())
2109
+        endif
2110
+    endif
2111
+
2112
+    if self._stay
2113
+        call self._restoreCursorPos()
2114
+    endif
2115
+endfunction
2116
+
2117
+"FUNCTION: Opener._previousWindow() {{{3
2118
+function! s:Opener._previousWindow()
2119
+    if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1
2120
+        call self._newSplit()
2121
+    else
2122
+        try
2123
+            if !s:isWindowUsable(winnr("#"))
2124
+                call s:exec(s:firstUsableWindow() . "wincmd w")
2125
+            else
2126
+                call s:exec('wincmd p')
2127
+            endif
2128
+        catch /^Vim\%((\a\+)\)\=:E37/
2129
+            call s:putCursorInTreeWin()
2130
+            throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
2131
+        catch /^Vim\%((\a\+)\)\=:/
2132
+            echo v:exception
2133
+        endtry
2134
+    endif
2135
+endfunction
2136
+
2137
+"FUNCTION: Opener._restoreCursorPos(){{{3
2138
+function! s:Opener._restoreCursorPos()
2139
+    call s:exec('normal ' . self._tabnr . 'gt')
2140
+    call s:exec(bufwinnr(self._bufnr) . 'wincmd w')
2141
+endfunction
2142
+
2143
+"FUNCTION: Opener._reuseWindow(){{{3
2144
+"put the cursor in the first window we find for this file
2145
+"
2146
+"return 1 if we were successful
2147
+function! s:Opener._reuseWindow()
2148
+    "check the current tab for the window
2149
+    let winnr = bufwinnr('^' . self._path.str() . '$')
2150
+    if winnr != -1
2151
+        call s:exec(winnr . "wincmd w")
2152
+        call self._checkToCloseTree(0)
2153
+        return 1
2154
+    else
2155
+        "check other tabs
2156
+        let tabnr = self._path.tabnr()
2157
+        if tabnr
2158
+            call self._checkToCloseTree(1)
2159
+            call s:exec('normal! ' . tabnr . 'gt')
2160
+            let winnr = bufwinnr('^' . self._path.str() . '$')
2161
+            call s:exec(winnr . "wincmd w")
2162
+            return 1
2163
+        endif
2164
+    endif
2165
+    return 0
2166
+endfunction
2167
+
2168
+"FUNCTION: Opener._saveCursorPos(){{{3
2169
+function! s:Opener._saveCursorPos()
2170
+    let self._bufnr = bufnr("")
2171
+    let self._tabnr = tabpagenr()
2172
+endfunction
2173
+
2174
+"CLASS: Path {{{2
2175
+"============================================================
2176
+let s:Path = {}
2177
+"FUNCTION: Path.AbsolutePathFor(str) {{{3
2178
+function! s:Path.AbsolutePathFor(str)
2179
+    let prependCWD = 0
2180
+    if s:running_windows
2181
+        let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)'
2182
+    else
2183
+        let prependCWD = a:str !~# '^/'
2184
+    endif
2185
+
2186
+    let toReturn = a:str
2187
+    if prependCWD
2188
+        let toReturn = getcwd() . s:Path.Slash() . a:str
2189
+    endif
2190
+
2191
+    return toReturn
2192
+endfunction
2193
+"FUNCTION: Path.bookmarkNames() {{{3
2194
+function! s:Path.bookmarkNames()
2195
+    if !exists("self._bookmarkNames")
2196
+        call self.cacheDisplayString()
2197
+    endif
2198
+    return self._bookmarkNames
2199
+endfunction
2200
+"FUNCTION: Path.cacheDisplayString() {{{3
2201
+function! s:Path.cacheDisplayString()
2202
+    let self.cachedDisplayString = self.getLastPathComponent(1)
2203
+
2204
+    if self.isExecutable
2205
+        let self.cachedDisplayString = self.cachedDisplayString . '*'
2206
+    endif
2207
+
2208
+    let self._bookmarkNames = []
2209
+    for i in s:Bookmark.Bookmarks()
2210
+        if i.path.equals(self)
2211
+            call add(self._bookmarkNames, i.name)
2212
+        endif
2213
+    endfor
2214
+    if !empty(self._bookmarkNames)
2215
+        let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
2216
+    endif
2217
+
2218
+    if self.isSymLink
2219
+        let self.cachedDisplayString .=  ' -> ' . self.symLinkDest
2220
+    endif
2221
+
2222
+    if self.isReadOnly
2223
+        let self.cachedDisplayString .=  ' [RO]'
2224
+    endif
2225
+endfunction
2226
+"FUNCTION: Path.changeToDir() {{{3
2227
+function! s:Path.changeToDir()
2228
+    let dir = self.str({'format': 'Cd'})
2229
+    if self.isDirectory ==# 0
2230
+        let dir = self.getParent().str({'format': 'Cd'})
2231
+    endif
2232
+
2233
+    try
2234
+        execute "cd " . dir
2235
+        call s:echo("CWD is now: " . getcwd())
2236
+    catch
2237
+        throw "NERDTree.PathChangeError: cannot change CWD to " . dir
2238
+    endtry
2239
+endfunction
2240
+
2241
+"FUNCTION: Path.compareTo() {{{3
2242
+"
2243
+"Compares this Path to the given path and returns 0 if they are equal, -1 if
2244
+"this Path is "less than" the given path, or 1 if it is "greater".
2245
+"
2246
+"Args:
2247
+"path: the path object to compare this to
2248
+"
2249
+"Return:
2250
+"1, -1 or 0
2251
+function! s:Path.compareTo(path)
2252
+    let thisPath = self.getLastPathComponent(1)
2253
+    let thatPath = a:path.getLastPathComponent(1)
2254
+
2255
+    "if the paths are the same then clearly we return 0
2256
+    if thisPath ==# thatPath
2257
+        return 0
2258
+    endif
2259
+
2260
+    let thisSS = self.getSortOrderIndex()
2261
+    let thatSS = a:path.getSortOrderIndex()
2262
+
2263
+    "compare the sort sequences, if they are different then the return
2264
+    "value is easy
2265
+    if thisSS < thatSS
2266
+        return -1
2267
+    elseif thisSS > thatSS
2268
+        return 1
2269
+    else
2270
+        "if the sort sequences are the same then compare the paths
2271
+        "alphabetically
2272
+        let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath
2273
+        if pathCompare
2274
+            return -1
2275
+        else
2276
+            return 1
2277
+        endif
2278
+    endif
2279
+endfunction
2280
+
2281
+"FUNCTION: Path.Create(fullpath) {{{3
2282
+"
2283
+"Factory method.
2284
+"
2285
+"Creates a path object with the given path. The path is also created on the
2286
+"filesystem. If the path already exists, a NERDTree.Path.Exists exception is
2287
+"thrown. If any other errors occur, a NERDTree.Path exception is thrown.
2288
+"
2289
+"Args:
2290
+"fullpath: the full filesystem path to the file/dir to create
2291
+function! s:Path.Create(fullpath)
2292
+    "bail if the a:fullpath already exists
2293
+    if isdirectory(a:fullpath) || filereadable(a:fullpath)
2294
+        throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'"
2295
+    endif
2296
+
2297
+    try
2298
+
2299
+        "if it ends with a slash, assume its a dir create it
2300
+        if a:fullpath =~# '\(\\\|\/\)$'
2301
+            "whack the trailing slash off the end if it exists
2302
+            let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '')
2303
+
2304
+            call mkdir(fullpath, 'p')
2305
+
2306
+        "assume its a file and create
2307
+        else
2308
+            call writefile([], a:fullpath)
2309
+        endif
2310
+    catch
2311
+        throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'"
2312
+    endtry
2313
+
2314
+    return s:Path.New(a:fullpath)
2315
+endfunction
2316
+
2317
+"FUNCTION: Path.copy(dest) {{{3
2318
+"
2319
+"Copies the file/dir represented by this Path to the given location
2320
+"
2321
+"Args:
2322
+"dest: the location to copy this dir/file to
2323
+function! s:Path.copy(dest)
2324
+    if !s:Path.CopyingSupported()
2325
+        throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
2326
+    endif
2327
+
2328
+    let dest = s:Path.WinToUnixPath(a:dest)
2329
+
2330
+    let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), s:escape_chars) . " " . escape(dest, s:escape_chars)
2331
+    let success = system(cmd)
2332
+    if success != 0
2333
+        throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
2334
+    endif
2335
+endfunction
2336
+
2337
+"FUNCTION: Path.CopyingSupported() {{{3
2338
+"
2339
+"returns 1 if copying is supported for this OS
2340
+function! s:Path.CopyingSupported()
2341
+    return exists('g:NERDTreeCopyCmd')
2342
+endfunction
2343
+
2344
+
2345
+"FUNCTION: Path.copyingWillOverwrite(dest) {{{3
2346
+"
2347
+"returns 1 if copy this path to the given location will cause files to
2348
+"overwritten
2349
+"
2350
+"Args:
2351
+"dest: the location this path will be copied to
2352
+function! s:Path.copyingWillOverwrite(dest)
2353
+    if filereadable(a:dest)
2354
+        return 1
2355
+    endif
2356
+
2357
+    if isdirectory(a:dest)
2358
+        let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0))
2359
+        if filereadable(path)
2360
+            return 1
2361
+        endif
2362
+    endif
2363
+endfunction
2364
+
2365
+"FUNCTION: Path.delete() {{{3
2366
+"
2367
+"Deletes the file represented by this path.
2368
+"Deletion of directories is not supported
2369
+"
2370
+"Throws NERDTree.Path.Deletion exceptions
2371
+function! s:Path.delete()
2372
+    if self.isDirectory
2373
+
2374
+        let cmd = g:NERDTreeRemoveDirCmd . self.str({'escape': 1})
2375
+        let success = system(cmd)
2376
+
2377
+        if v:shell_error != 0
2378
+            throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'"
2379
+        endif
2380
+    else
2381
+        let success = delete(self.str())
2382
+        if success != 0
2383
+            throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'"
2384
+        endif
2385
+    endif
2386
+
2387
+    "delete all bookmarks for this path
2388
+    for i in self.bookmarkNames()
2389
+        let bookmark = s:Bookmark.BookmarkFor(i)
2390
+        call bookmark.delete()
2391
+    endfor
2392
+endfunction
2393
+
2394
+"FUNCTION: Path.displayString() {{{3
2395
+"
2396
+"Returns a string that specifies how the path should be represented as a
2397
+"string
2398
+function! s:Path.displayString()
2399
+    if self.cachedDisplayString ==# ""
2400
+        call self.cacheDisplayString()
2401
+    endif
2402
+
2403
+    return self.cachedDisplayString
2404
+endfunction
2405
+"FUNCTION: Path.edit() {{{3
2406
+function! s:Path.edit()
2407
+    exec "edit " . self.str({'format': 'Edit'})
2408
+endfunction
2409
+"FUNCTION: Path.extractDriveLetter(fullpath) {{{3
2410
+"
2411
+"If running windows, cache the drive letter for this path
2412
+function! s:Path.extractDriveLetter(fullpath)
2413
+    if s:running_windows
2414
+        if a:fullpath =~ '^\(\\\\\|\/\/\)'
2415
+            "For network shares, the 'drive' consists of the first two parts of the path, i.e. \\boxname\share
2416
+            let self.drive = substitute(a:fullpath, '^\(\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\).*', '\1', '')
2417
+            let self.drive = substitute(self.drive, '/', '\', "g")
2418
+        else
2419
+            let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '')
2420
+        endif
2421
+    else
2422
+        let self.drive = ''
2423
+    endif
2424
+
2425
+endfunction
2426
+"FUNCTION: Path.exists() {{{3
2427
+"return 1 if this path points to a location that is readable or is a directory
2428
+function! s:Path.exists()
2429
+    let p = self.str()
2430
+    return filereadable(p) || isdirectory(p)
2431
+endfunction
2432
+"FUNCTION: Path.getDir() {{{3
2433
+"
2434
+"Returns this path if it is a directory, else this paths parent.
2435
+"
2436
+"Return:
2437
+"a Path object
2438
+function! s:Path.getDir()
2439
+    if self.isDirectory
2440
+        return self
2441
+    else
2442
+        return self.getParent()
2443
+    endif
2444
+endfunction
2445
+"FUNCTION: Path.getParent() {{{3
2446
+"
2447
+"Returns a new path object for this paths parent
2448
+"
2449
+"Return:
2450
+"a new Path object
2451
+function! s:Path.getParent()
2452
+    if s:running_windows
2453
+        let path = self.drive . '\' . join(self.pathSegments[0:-2], '\')
2454
+    else
2455
+        let path = '/'. join(self.pathSegments[0:-2], '/')
2456
+    endif
2457
+
2458
+    return s:Path.New(path)
2459
+endfunction
2460
+"FUNCTION: Path.getLastPathComponent(dirSlash) {{{3
2461
+"
2462
+"Gets the last part of this path.
2463
+"
2464
+"Args:
2465
+"dirSlash: if 1 then a trailing slash will be added to the returned value for
2466
+"directory nodes.
2467
+function! s:Path.getLastPathComponent(dirSlash)
2468
+    if empty(self.pathSegments)
2469
+        return ''
2470
+    endif
2471
+    let toReturn = self.pathSegments[-1]
2472
+    if a:dirSlash && self.isDirectory
2473
+        let toReturn = toReturn . '/'
2474
+    endif
2475
+    return toReturn
2476
+endfunction
2477
+
2478
+"FUNCTION: Path.getSortOrderIndex() {{{3
2479
+"returns the index of the pattern in g:NERDTreeSortOrder that this path matches
2480
+function! s:Path.getSortOrderIndex()
2481
+    let i = 0
2482
+    while i < len(g:NERDTreeSortOrder)
2483
+        if  self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
2484
+            return i
2485
+        endif
2486
+        let i = i + 1
2487
+    endwhile
2488
+    return s:NERDTreeSortStarIndex
2489
+endfunction
2490
+
2491
+
2492
+"FUNCTION: Path.isUnixHiddenFile() {{{3
2493
+"check for unix hidden files
2494
+function! s:Path.isUnixHiddenFile()
2495
+    return self.getLastPathComponent(0) =~# '^\.'
2496
+endfunction
2497
+
2498
+"FUNCTION: Path.ignore() {{{3
2499
+"returns true if this path should be ignored
2500
+function! s:Path.ignore()
2501
+    "filter out the user specified paths to ignore
2502
+    if b:NERDTreeIgnoreEnabled
2503
+        for i in g:NERDTreeIgnore
2504
+            if self._ignorePatternMatches(i)
2505
+                return 1
2506
+            endif
2507
+        endfor
2508
+    endif
2509
+
2510
+    "dont show hidden files unless instructed to
2511
+    if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile()
2512
+        return 1
2513
+    endif
2514
+
2515
+    if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0
2516
+        return 1
2517
+    endif
2518
+
2519
+    if exists("*NERDTreeCustomIgnoreFilter") && NERDTreeCustomIgnoreFilter(self)
2520
+        return 1
2521
+    endif
2522
+
2523
+    return 0
2524
+endfunction
2525
+
2526
+"FUNCTION: Path._ignorePatternMatches(pattern) {{{3
2527
+"returns true if this path matches the given ignore pattern
2528
+function! s:Path._ignorePatternMatches(pattern)
2529
+    let pat = a:pattern
2530
+    if strpart(pat,len(pat)-7) == '[[dir]]'
2531
+        if !self.isDirectory
2532
+            return 0
2533
+        endif
2534
+        let pat = strpart(pat,0, len(pat)-7)
2535
+    elseif strpart(pat,len(pat)-8) == '[[file]]'
2536
+        if self.isDirectory
2537
+            return 0
2538
+        endif
2539
+        let pat = strpart(pat,0, len(pat)-8)
2540
+    endif
2541
+
2542
+    return self.getLastPathComponent(0) =~# pat
2543
+endfunction
2544
+"FUNCTION: Path.isUnder(path) {{{3
2545
+"return 1 if this path is somewhere under the given path in the filesystem.
2546
+"
2547
+"a:path should be a dir
2548
+function! s:Path.isUnder(path)
2549
+    if a:path.isDirectory == 0
2550
+        return 0
2551
+    endif
2552
+
2553
+    let this = self.str()
2554
+    let that = a:path.str()
2555
+    return stridx(this, that . s:Path.Slash()) == 0
2556
+endfunction
2557
+
2558
+"FUNCTION: Path.JoinPathStrings(...) {{{3
2559
+function! s:Path.JoinPathStrings(...)
2560
+    let components = []
2561
+    for i in a:000
2562
+        let components = extend(components, split(i, '/'))
2563
+    endfor
2564
+    return '/' . join(components, '/')
2565
+endfunction
2566
+
2567
+"FUNCTION: Path.equals() {{{3
2568
+"
2569
+"Determines whether 2 path objects are "equal".
2570
+"They are equal if the paths they represent are the same
2571
+"
2572
+"Args:
2573
+"path: the other path obj to compare this with
2574
+function! s:Path.equals(path)
2575
+    return self.str() ==# a:path.str()
2576
+endfunction
2577
+
2578
+"FUNCTION: Path.New() {{{3
2579
+"The Constructor for the Path object
2580
+function! s:Path.New(path)
2581
+    let newPath = copy(self)
2582
+
2583
+    call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
2584
+
2585
+    let newPath.cachedDisplayString = ""
2586
+
2587
+    return newPath
2588
+endfunction
2589
+
2590
+"FUNCTION: Path.Slash() {{{3
2591
+"return the slash to use for the current OS
2592
+function! s:Path.Slash()
2593
+    return s:running_windows ? '\' : '/'
2594
+endfunction
2595
+
2596
+"FUNCTION: Path.Resolve() {{{3
2597
+"Invoke the vim resolve() function and return the result
2598
+"This is necessary because in some versions of vim resolve() removes trailing
2599
+"slashes while in other versions it doesn't.  This always removes the trailing
2600
+"slash
2601
+function! s:Path.Resolve(path)
2602
+    let tmp = resolve(a:path)
2603
+    return tmp =~# '.\+/$' ? substitute(tmp, '/$', '', '') : tmp
2604
+endfunction
2605
+
2606
+"FUNCTION: Path.readInfoFromDisk(fullpath) {{{3
2607
+"
2608
+"
2609
+"Throws NERDTree.Path.InvalidArguments exception.
2610
+function! s:Path.readInfoFromDisk(fullpath)
2611
+    call self.extractDriveLetter(a:fullpath)
2612
+
2613
+    let fullpath = s:Path.WinToUnixPath(a:fullpath)
2614
+
2615
+    if getftype(fullpath) ==# "fifo"
2616
+        throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . a:fullpath
2617
+    endif
2618
+
2619
+    let self.pathSegments = split(fullpath, '/')
2620
+
2621
+    let self.isReadOnly = 0
2622
+    if isdirectory(a:fullpath)
2623
+        let self.isDirectory = 1
2624
+    elseif filereadable(a:fullpath)
2625
+        let self.isDirectory = 0
2626
+        let self.isReadOnly = filewritable(a:fullpath) ==# 0
2627
+    else
2628
+        throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath
2629
+    endif
2630
+
2631
+    let self.isExecutable = 0
2632
+    if !self.isDirectory
2633
+        let self.isExecutable = getfperm(a:fullpath) =~# 'x'
2634
+    endif
2635
+
2636
+    "grab the last part of the path (minus the trailing slash)
2637
+    let lastPathComponent = self.getLastPathComponent(0)
2638
+
2639
+    "get the path to the new node with the parent dir fully resolved
2640
+    let hardPath = s:Path.Resolve(self.strTrunk()) . '/' . lastPathComponent
2641
+
2642
+    "if  the last part of the path is a symlink then flag it as such
2643
+    let self.isSymLink = (s:Path.Resolve(hardPath) != hardPath)
2644
+    if self.isSymLink
2645
+        let self.symLinkDest = s:Path.Resolve(fullpath)
2646
+
2647
+        "if the link is a dir then slap a / on the end of its dest
2648
+        if isdirectory(self.symLinkDest)
2649
+
2650
+            "we always wanna treat MS windows shortcuts as files for
2651
+            "simplicity
2652
+            if hardPath !~# '\.lnk$'
2653
+
2654
+                let self.symLinkDest = self.symLinkDest . '/'
2655
+            endif
2656
+        endif
2657
+    endif
2658
+endfunction
2659
+
2660
+"FUNCTION: Path.refresh() {{{3
2661
+function! s:Path.refresh()
2662
+    call self.readInfoFromDisk(self.str())
2663
+    call self.cacheDisplayString()
2664
+endfunction
2665
+
2666
+"FUNCTION: Path.rename() {{{3
2667
+"
2668
+"Renames this node on the filesystem
2669
+function! s:Path.rename(newPath)
2670
+    if a:newPath ==# ''
2671
+        throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath
2672
+    endif
2673
+
2674
+    let success =  rename(self.str(), a:newPath)
2675
+    if success != 0
2676
+        throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath
2677
+    endif
2678
+    call self.readInfoFromDisk(a:newPath)
2679
+
2680
+    for i in self.bookmarkNames()
2681
+        let b = s:Bookmark.BookmarkFor(i)
2682
+        call b.setPath(copy(self))
2683
+    endfor
2684
+    call s:Bookmark.Write()
2685
+endfunction
2686
+
2687
+"FUNCTION: Path.str() {{{3
2688
+"
2689
+"Returns a string representation of this Path
2690
+"
2691
+"Takes an optional dictionary param to specify how the output should be
2692
+"formatted.
2693
+"
2694
+"The dict may have the following keys:
2695
+"  'format'
2696
+"  'escape'
2697
+"  'truncateTo'
2698
+"
2699
+"The 'format' key may have a value of:
2700
+"  'Cd' - a string to be used with the :cd command
2701
+"  'Edit' - a string to be used with :e :sp :new :tabedit etc
2702
+"  'UI' - a string used in the NERD tree UI
2703
+"
2704
+"The 'escape' key, if specified will cause the output to be escaped with
2705
+"shellescape()
2706
+"
2707
+"The 'truncateTo' key causes the resulting string to be truncated to the value
2708
+"'truncateTo' maps to. A '<' char will be prepended.
2709
+function! s:Path.str(...)
2710
+    let options = a:0 ? a:1 : {}
2711
+    let toReturn = ""
2712
+
2713
+    if has_key(options, 'format')
2714
+        let format = options['format']
2715
+        if has_key(self, '_strFor' . format)
2716
+            exec 'let toReturn = self._strFor' . format . '()'
2717
+        else
2718
+            raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"'
2719
+        endif
2720
+    else
2721
+        let toReturn = self._str()
2722
+    endif
2723
+
2724
+    if s:has_opt(options, 'escape')
2725
+        let toReturn = shellescape(toReturn)
2726
+    endif
2727
+
2728
+    if has_key(options, 'truncateTo')
2729
+        let limit = options['truncateTo']
2730
+        if len(toReturn) > limit
2731
+            let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1)
2732
+        endif
2733
+    endif
2734
+
2735
+    return toReturn
2736
+endfunction
2737
+
2738
+"FUNCTION: Path._strForUI() {{{3
2739
+function! s:Path._strForUI()
2740
+    let toReturn = '/' . join(self.pathSegments, '/')
2741
+    if self.isDirectory && toReturn != '/'
2742
+        let toReturn  = toReturn . '/'
2743
+    endif
2744
+    return toReturn
2745
+endfunction
2746
+
2747
+"FUNCTION: Path._strForCd() {{{3
2748
+"
2749
+" returns a string that can be used with :cd
2750
+function! s:Path._strForCd()
2751
+    return escape(self.str(), s:escape_chars)
2752
+endfunction
2753
+"FUNCTION: Path._strForEdit() {{{3
2754
+"
2755
+"Return: the string for this path that is suitable to be used with the :edit
2756
+"command
2757
+function! s:Path._strForEdit()
2758
+    let p = escape(self.str({'format': 'UI'}), s:escape_chars)
2759
+    let cwd = getcwd() . s:Path.Slash()
2760
+
2761
+    "return a relative path if we can
2762
+    let isRelative = 0
2763
+    if s:running_windows
2764
+        let isRelative = stridx(tolower(p), tolower(cwd)) == 0
2765
+    else
2766
+        let isRelative = stridx(p, cwd) == 0
2767
+    endif
2768
+
2769
+    if isRelative
2770
+        let p = strpart(p, strlen(cwd))
2771
+
2772
+        "handle the edge case where the file begins with a + (vim interprets
2773
+        "the +foo in `:e +foo` as an option to :edit)
2774
+        if p[0] == "+"
2775
+            let p = '\' . p
2776
+        endif
2777
+    endif
2778
+
2779
+    if p ==# ''
2780
+        let p = '.'
2781
+    endif
2782
+
2783
+    return p
2784
+endfunction
2785
+"FUNCTION: Path._strForGlob() {{{3
2786
+function! s:Path._strForGlob()
2787
+    let lead = s:Path.Slash()
2788
+
2789
+    "if we are running windows then slap a drive letter on the front
2790
+    if s:running_windows
2791
+        let lead = self.drive . '\'
2792
+    endif
2793
+
2794
+    let toReturn = lead . join(self.pathSegments, s:Path.Slash())
2795
+
2796
+    if !s:running_windows
2797
+        let toReturn = escape(toReturn, s:escape_chars)
2798
+    endif
2799
+    return toReturn
2800
+endfunction
2801
+"FUNCTION: Path._str() {{{3
2802
+"
2803
+"Gets the string path for this path object that is appropriate for the OS.
2804
+"EG, in windows c:\foo\bar
2805
+"    in *nix  /foo/bar
2806
+function! s:Path._str()
2807
+    let lead = s:Path.Slash()
2808
+
2809
+    "if we are running windows then slap a drive letter on the front
2810
+    if s:running_windows
2811
+        let lead = self.drive . '\'
2812
+    endif
2813
+
2814
+    return lead . join(self.pathSegments, s:Path.Slash())
2815
+endfunction
2816
+
2817
+"FUNCTION: Path.strTrunk() {{{3
2818
+"Gets the path without the last segment on the end.
2819
+function! s:Path.strTrunk()
2820
+    return self.drive . '/' . join(self.pathSegments[0:-2], '/')
2821
+endfunction
2822
+
2823
+" FUNCTION: Path.tabnr() {{{3
2824
+" return the number of the first tab that is displaying this file
2825
+"
2826
+" return 0 if no tab was found
2827
+function! s:Path.tabnr()
2828
+    let str = self.str()
2829
+    for t in range(tabpagenr('$'))
2830
+        for b in tabpagebuflist(t+1)
2831
+            if str == expand('#' . b . ':p')
2832
+                return t+1
2833
+            endif
2834
+        endfor
2835
+    endfor
2836
+    return 0
2837
+endfunction
2838
+"FUNCTION: Path.WinToUnixPath(pathstr){{{3
2839
+"Takes in a windows path and returns the unix equiv
2840
+"
2841
+"A class level method
2842
+"
2843
+"Args:
2844
+"pathstr: the windows path to convert
2845
+function! s:Path.WinToUnixPath(pathstr)
2846
+    if !s:running_windows
2847
+        return a:pathstr
2848
+    endif
2849
+
2850
+    let toReturn = a:pathstr
2851
+
2852
+    "remove the x:\ of the front
2853
+    let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "")
2854
+
2855
+    "remove the \\ network share from the front
2856
+    let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "")
2857
+
2858
+    "convert all \ chars to /
2859
+    let toReturn = substitute(toReturn, '\', '/', "g")
2860
+
2861
+    return toReturn
2862
+endfunction
2863
+
2864
+" SECTION: General Functions {{{1
2865
+"============================================================
2866
+"FUNCTION: s:bufInWindows(bnum){{{2
2867
+"[[STOLEN FROM VTREEEXPLORER.VIM]]
2868
+"Determine the number of windows open to this buffer number.
2869
+"Care of Yegappan Lakshman.  Thanks!
2870
+"
2871
+"Args:
2872
+"bnum: the subject buffers buffer number
2873
+function! s:bufInWindows(bnum)
2874
+    let cnt = 0
2875
+    let winnum = 1
2876
+    while 1
2877
+        let bufnum = winbufnr(winnum)
2878
+        if bufnum < 0
2879
+            break
2880
+        endif
2881
+        if bufnum ==# a:bnum
2882
+            let cnt = cnt + 1
2883
+        endif
2884
+        let winnum = winnum + 1
2885
+    endwhile
2886
+
2887
+    return cnt
2888
+endfunction " >>>
2889
+"FUNCTION: s:checkForBrowse(dir) {{{2
2890
+"inits a secondary nerd tree in the current buffer if appropriate
2891
+function! s:checkForBrowse(dir)
2892
+    if a:dir != '' && isdirectory(a:dir)
2893
+        call s:initNerdTreeInPlace(a:dir)
2894
+    endif
2895
+endfunction
2896
+"FUNCTION: s:compareBookmarks(first, second) {{{2
2897
+"Compares two bookmarks
2898
+function! s:compareBookmarks(first, second)
2899
+    return a:first.compareTo(a:second)
2900
+endfunction
2901
+
2902
+" FUNCTION: s:completeBookmarks(A,L,P) {{{2
2903
+" completion function for the bookmark commands
2904
+function! s:completeBookmarks(A,L,P)
2905
+    return filter(s:Bookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"')
2906
+endfunction
2907
+" FUNCTION: s:createDefaultBindings() {{{2
2908
+function! s:createDefaultBindings()
2909
+    let s = '<SNR>' . s:SID() . '_'
2910
+
2911
+    call NERDTreeAddKeyMap({ 'key': '<MiddleRelease>', 'scope': "all", 'callback': s."handleMiddleMouse" })
2912
+    call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', 'scope': "all", 'callback': s."handleLeftClick" })
2913
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" })
2914
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" })
2915
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" })
2916
+    call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" })
2917
+
2918
+
2919
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" })
2920
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" })
2921
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" })
2922
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" })
2923
+
2924
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" })
2925
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" })
2926
+
2927
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" })
2928
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" })
2929
+
2930
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" })
2931
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" })
2932
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" })
2933
+
2934
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" })
2935
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" })
2936
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" })
2937
+
2938
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" })
2939
+
2940
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" })
2941
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" })
2942
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" })
2943
+
2944
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" })
2945
+
2946
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" })
2947
+
2948
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': s."chRootCwd" })
2949
+
2950
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" })
2951
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" })
2952
+
2953
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" })
2954
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" })
2955
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" })
2956
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" })
2957
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" })
2958
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" })
2959
+
2960
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" })
2961
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" })
2962
+
2963
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" })
2964
+
2965
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" })
2966
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" })
2967
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" })
2968
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" })
2969
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" })
2970
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" })
2971
+
2972
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" })
2973
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" })
2974
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" })
2975
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" })
2976
+
2977
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" })
2978
+
2979
+    call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" })
2980
+
2981
+endfunction
2982
+" FUNCTION: s:deprecated(func, [msg]) {{{2
2983
+" Issue a deprecation warning for a:func. If a second arg is given, use this
2984
+" as the deprecation message
2985
+function! s:deprecated(func, ...)
2986
+    let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated'
2987
+
2988
+    if !exists('s:deprecationWarnings')
2989
+        let s:deprecationWarnings = {}
2990
+    endif
2991
+    if !has_key(s:deprecationWarnings, a:func)
2992
+        let s:deprecationWarnings[a:func] = 1
2993
+        echomsg msg
2994
+    endif
2995
+endfunction
2996
+" FUNCTION: s:exec(cmd) {{{2
2997
+" same as :exec cmd  but eventignore=all is set for the duration
2998
+function! s:exec(cmd)
2999
+    let old_ei = &ei
3000
+    set ei=all
3001
+    exec a:cmd
3002
+    let &ei = old_ei
3003
+endfunction
3004
+" FUNCTION: s:findAndRevealPath() {{{2
3005
+function! s:findAndRevealPath()
3006
+    try
3007
+        let p = s:Path.New(expand("%:p"))
3008
+    catch /^NERDTree.InvalidArgumentsError/
3009
+        call s:echo("no file for the current buffer")
3010
+        return
3011
+    endtry
3012
+
3013
+    if p.isUnixHiddenFile()
3014
+        let showhidden=g:NERDTreeShowHidden
3015
+        let g:NERDTreeShowHidden = 1
3016
+    endif
3017
+
3018
+    if !s:treeExistsForTab()
3019
+        try
3020
+            let cwd = s:Path.New(getcwd())
3021
+        catch /^NERDTree.InvalidArgumentsError/
3022
+            call s:echo("current directory does not exist.")
3023
+            let cwd = p.getParent()
3024
+        endtry
3025
+
3026
+        if p.isUnder(cwd)
3027
+            call s:initNerdTree(cwd.str())
3028
+        else
3029
+            call s:initNerdTree(p.getParent().str())
3030
+        endif
3031
+    else
3032
+        if !p.isUnder(s:TreeFileNode.GetRootForTab().path)
3033
+            if !s:isTreeOpen()
3034
+                call s:createTreeWin()
3035
+            else
3036
+                call s:putCursorInTreeWin()
3037
+            endif
3038
+            let b:NERDTreeShowHidden = g:NERDTreeShowHidden
3039
+            call s:chRoot(s:TreeDirNode.New(p.getParent()))
3040
+        else
3041
+            if !s:isTreeOpen()
3042
+                call s:toggle("")
3043
+            endif
3044
+        endif
3045
+    endif
3046
+    call s:putCursorInTreeWin()
3047
+    call b:NERDTreeRoot.reveal(p)
3048
+
3049
+    if p.isUnixHiddenFile()
3050
+        let g:NERDTreeShowHidden = showhidden
3051
+    endif
3052
+endfunction
3053
+
3054
+" FUNCTION: s:has_opt(options, name) {{{2
3055
+function! s:has_opt(options, name)
3056
+    return has_key(a:options, a:name) && a:options[a:name] == 1
3057
+endfunction
3058
+
3059
+"FUNCTION: s:initNerdTree(name) {{{2
3060
+"Initialise the nerd tree for this tab. The tree will start in either the
3061
+"given directory, or the directory associated with the given bookmark
3062
+"
3063
+"Args:
3064
+"name: the name of a bookmark or a directory
3065
+function! s:initNerdTree(name)
3066
+    let path = {}
3067
+    if s:Bookmark.BookmarkExistsFor(a:name)
3068
+        let path = s:Bookmark.BookmarkFor(a:name).path
3069
+    else
3070
+        let dir = a:name ==# '' ? getcwd() : a:name
3071
+
3072
+        "hack to get an absolute path if a relative path is given
3073
+        if dir =~# '^\.'
3074
+            let dir = getcwd() . s:Path.Slash() . dir
3075
+        endif
3076
+        let dir = s:Path.Resolve(dir)
3077
+
3078
+        try
3079
+            let path = s:Path.New(dir)
3080
+        catch /^NERDTree.InvalidArgumentsError/
3081
+            call s:echo("No bookmark or directory found for: " . a:name)
3082
+            return
3083
+        endtry
3084
+    endif
3085
+    if !path.isDirectory
3086
+        let path = path.getParent()
3087
+    endif
3088
+
3089
+    "if instructed to, then change the vim CWD to the dir the NERDTree is
3090
+    "inited in
3091
+    if g:NERDTreeChDirMode != 0
3092
+        call path.changeToDir()
3093
+    endif
3094
+
3095
+    if s:treeExistsForTab()
3096
+        if s:isTreeOpen()
3097
+            call s:closeTree()
3098
+        endif
3099
+        unlet t:NERDTreeBufName
3100
+    endif
3101
+
3102
+    let newRoot = s:TreeDirNode.New(path)
3103
+    call newRoot.open()
3104
+
3105
+    call s:createTreeWin()
3106
+    let b:treeShowHelp = 0
3107
+    let b:NERDTreeIgnoreEnabled = 1
3108
+    let b:NERDTreeShowFiles = g:NERDTreeShowFiles
3109
+    let b:NERDTreeShowHidden = g:NERDTreeShowHidden
3110
+    let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
3111
+    let b:NERDTreeRoot = newRoot
3112
+    let b:NERDTreeType = "primary"
3113
+
3114
+    call s:renderView()
3115
+    call b:NERDTreeRoot.putCursorHere(0, 0)
3116
+
3117
+    silent doautocmd User NERDTreeInit
3118
+endfunction
3119
+
3120
+"FUNCTION: s:initNerdTreeInPlace(dir) {{{2
3121
+function! s:initNerdTreeInPlace(dir)
3122
+    try
3123
+        let path = s:Path.New(a:dir)
3124
+    catch /^NERDTree.InvalidArgumentsError/
3125
+        call s:echo("Invalid directory name:" . a:name)
3126
+        return
3127
+    endtry
3128
+
3129
+    "we want the directory buffer to disappear when we do the :edit below
3130
+    setlocal bufhidden=wipe
3131
+
3132
+    let previousBuf = expand("#")
3133
+
3134
+    "we need a unique name for each secondary tree buffer to ensure they are
3135
+    "all independent
3136
+    exec "silent edit " . s:nextBufferName()
3137
+
3138
+    let b:NERDTreePreviousBuf = bufnr(previousBuf)
3139
+
3140
+    let b:NERDTreeRoot = s:TreeDirNode.New(path)
3141
+    call b:NERDTreeRoot.open()
3142
+
3143
+    call s:setCommonBufOptions()
3144
+    let b:NERDTreeType = "secondary"
3145
+
3146
+    call s:renderView()
3147
+
3148
+    silent doautocmd User NERDTreeInit
3149
+endfunction
3150
+" FUNCTION: s:initNerdTreeMirror() {{{2
3151
+function! s:initNerdTreeMirror()
3152
+
3153
+    "get the names off all the nerd tree buffers
3154
+    let treeBufNames = []
3155
+    for i in range(1, tabpagenr("$"))
3156
+        let nextName = s:tabpagevar(i, 'NERDTreeBufName')
3157
+        if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
3158
+            call add(treeBufNames, nextName)
3159
+        endif
3160
+    endfor
3161
+    let treeBufNames = s:unique(treeBufNames)
3162
+
3163
+    "map the option names (that the user will be prompted with) to the nerd
3164
+    "tree buffer names
3165
+    let options = {}
3166
+    let i = 0
3167
+    while i < len(treeBufNames)
3168
+        let bufName = treeBufNames[i]
3169
+        let treeRoot = getbufvar(bufName, "NERDTreeRoot")
3170
+        let options[i+1 . '. ' . treeRoot.path.str() . '  (buf name: ' . bufName . ')'] = bufName
3171
+        let i = i + 1
3172
+    endwhile
3173
+
3174
+    "work out which tree to mirror, if there is more than 1 then ask the user
3175
+    let bufferName = ''
3176
+    if len(keys(options)) > 1
3177
+        let choices = ["Choose a tree to mirror"]
3178
+        let choices = extend(choices, sort(keys(options)))
3179
+        let choice = inputlist(choices)
3180
+        if choice < 1 || choice > len(options) || choice ==# ''
3181
+            return
3182
+        endif
3183
+
3184
+        let bufferName = options[sort(keys(options))[choice-1]]
3185
+    elseif len(keys(options)) ==# 1
3186
+        let bufferName = values(options)[0]
3187
+    else
3188
+        call s:echo("No trees to mirror")
3189
+        return
3190
+    endif
3191
+
3192
+    if s:treeExistsForTab() && s:isTreeOpen()
3193
+        call s:closeTree()
3194
+    endif
3195
+
3196
+    let t:NERDTreeBufName = bufferName
3197
+    call s:createTreeWin()
3198
+    exec 'buffer ' .  bufferName
3199
+    if !&hidden
3200
+        call s:renderView()
3201
+    endif
3202
+endfunction
3203
+" FUNCTION: s:nextBufferName() {{{2
3204
+" returns the buffer name for the next nerd tree
3205
+function! s:nextBufferName()
3206
+    let name = s:NERDTreeBufName . s:next_buffer_number
3207
+    let s:next_buffer_number += 1
3208
+    return name
3209
+endfunction
3210
+" FUNCTION: s:postSourceActions() {{{2
3211
+function! s:postSourceActions()
3212
+    call s:Bookmark.CacheBookmarks(0)
3213
+    call s:createDefaultBindings()
3214
+
3215
+    "load all nerdtree plugins
3216
+    runtime! nerdtree_plugin/**/*.vim
3217
+endfunction
3218
+" FUNCTION: s:tabpagevar(tabnr, var) {{{2
3219
+function! s:tabpagevar(tabnr, var)
3220
+    let currentTab = tabpagenr()
3221
+    let old_ei = &ei
3222
+    set ei=all
3223
+
3224
+    exec "tabnext " . a:tabnr
3225
+    let v = -1
3226
+    if exists('t:' . a:var)
3227
+        exec 'let v = t:' . a:var
3228
+    endif
3229
+    exec "tabnext " . currentTab
3230
+
3231
+    let &ei = old_ei
3232
+
3233
+    return v
3234
+endfunction
3235
+" Function: s:treeExistsForBuffer()   {{{2
3236
+" Returns 1 if a nerd tree root exists in the current buffer
3237
+function! s:treeExistsForBuf()
3238
+    return exists("b:NERDTreeRoot")
3239
+endfunction
3240
+" Function: s:treeExistsForTab()   {{{2
3241
+" Returns 1 if a nerd tree root exists in the current tab
3242
+function! s:treeExistsForTab()
3243
+    return exists("t:NERDTreeBufName")
3244
+endfunction
3245
+" Function: s:SID()   {{{2
3246
+function s:SID()
3247
+    if !exists("s:sid")
3248
+        let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
3249
+    endif
3250
+    return s:sid
3251
+endfun
3252
+"FUNCTION: s:upDir(keepState) {{{2
3253
+"moves the tree up a level
3254
+"
3255
+"Args:
3256
+"keepState: 1 if the current root should be left open when the tree is
3257
+"re-rendered
3258
+function! s:upDir(keepState)
3259
+    let cwd = b:NERDTreeRoot.path.str({'format': 'UI'})
3260
+    if cwd ==# "/" || cwd =~# '^[^/]..$'
3261
+        call s:echo("already at top dir")
3262
+    else
3263
+        if !a:keepState
3264
+            call b:NERDTreeRoot.close()
3265
+        endif
3266
+
3267
+        let oldRoot = b:NERDTreeRoot
3268
+
3269
+        if empty(b:NERDTreeRoot.parent)
3270
+            let path = b:NERDTreeRoot.path.getParent()
3271
+            let newRoot = s:TreeDirNode.New(path)
3272
+            call newRoot.open()
3273
+            call newRoot.transplantChild(b:NERDTreeRoot)
3274
+            let b:NERDTreeRoot = newRoot
3275
+        else
3276
+            let b:NERDTreeRoot = b:NERDTreeRoot.parent
3277
+        endif
3278
+
3279
+        if g:NERDTreeChDirMode ==# 2
3280
+            call b:NERDTreeRoot.path.changeToDir()
3281
+        endif
3282
+
3283
+        call s:renderView()
3284
+        call oldRoot.putCursorHere(0, 0)
3285
+    endif
3286
+endfunction
3287
+" Function: s:unique(list)   {{{2
3288
+" returns a:list without duplicates
3289
+function! s:unique(list)
3290
+  let uniqlist = []
3291
+  for elem in a:list
3292
+    if index(uniqlist, elem) ==# -1
3293
+      let uniqlist += [elem]
3294
+    endif
3295
+  endfor
3296
+  return uniqlist
3297
+endfunction
3298
+" SECTION: Public API {{{1
3299
+"============================================================
3300
+let g:NERDTreePath = s:Path
3301
+let g:NERDTreeDirNode = s:TreeDirNode
3302
+let g:NERDTreeFileNode = s:TreeFileNode
3303
+let g:NERDTreeBookmark = s:Bookmark
3304
+
3305
+function! NERDTreeAddMenuItem(options)
3306
+    call s:MenuItem.Create(a:options)
3307
+endfunction
3308
+
3309
+function! NERDTreeAddMenuSeparator(...)
3310
+    let opts = a:0 ? a:1 : {}
3311
+    call s:MenuItem.CreateSeparator(opts)
3312
+endfunction
3313
+
3314
+function! NERDTreeAddSubmenu(options)
3315
+    return s:MenuItem.Create(a:options)
3316
+endfunction
3317
+
3318
+function! NERDTreeAddKeyMap(options)
3319
+    call s:KeyMap.Create(a:options)
3320
+endfunction
3321
+
3322
+function! NERDTreeRender()
3323
+    call s:renderView()
3324
+endfunction
3325
+
3326
+function! NERDTreeFocus()
3327
+    if s:isTreeOpen()
3328
+        call s:putCursorInTreeWin()
3329
+    else
3330
+        call s:toggle("")
3331
+    endif
3332
+endfunction
3333
+
3334
+function! NERDTreeCWD()
3335
+    call NERDTreeFocus()
3336
+    call s:chRootCwd()
3337
+endfunction
3338
+
3339
+" SECTION: View Functions {{{1
3340
+"============================================================
3341
+"FUNCTION: s:centerView() {{{2
3342
+"centers the nerd tree window around the cursor (provided the nerd tree
3343
+"options permit)
3344
+function! s:centerView()
3345
+    if g:NERDTreeAutoCenter
3346
+        let current_line = winline()
3347
+        let lines_to_top = current_line
3348
+        let lines_to_bottom = winheight(s:getTreeWinNum()) - current_line
3349
+        if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
3350
+            normal! zz
3351
+        endif
3352
+    endif
3353
+endfunction
3354
+"FUNCTION: s:closeTree() {{{2
3355
+"Closes the primary NERD tree window for this tab
3356
+function! s:closeTree()
3357
+    if !s:isTreeOpen()
3358
+        throw "NERDTree.NoTreeFoundError: no NERDTree is open"
3359
+    endif
3360
+
3361
+    if winnr("$") != 1
3362
+        if winnr() == s:getTreeWinNum()
3363
+            call s:exec("wincmd p")
3364
+            let bufnr = bufnr("")
3365
+            call s:exec("wincmd p")
3366
+        else
3367
+            let bufnr = bufnr("")
3368
+        endif
3369
+
3370
+        call s:exec(s:getTreeWinNum() . " wincmd w")
3371
+        close
3372
+        call s:exec(bufwinnr(bufnr) . " wincmd w")
3373
+    else
3374
+        close
3375
+    endif
3376
+endfunction
3377
+
3378
+"FUNCTION: s:closeTreeIfOpen() {{{2
3379
+"Closes the NERD tree window if it is open
3380
+function! s:closeTreeIfOpen()
3381
+   if s:isTreeOpen()
3382
+      call s:closeTree()
3383
+   endif
3384
+endfunction
3385
+"FUNCTION: s:closeTreeIfQuitOnOpen() {{{2
3386
+"Closes the NERD tree window if the close on open option is set
3387
+function! s:closeTreeIfQuitOnOpen()
3388
+    if g:NERDTreeQuitOnOpen && s:isTreeOpen()
3389
+        call s:closeTree()
3390
+    endif
3391
+endfunction
3392
+"FUNCTION: s:createTreeWin() {{{2
3393
+"Inits the NERD tree window. ie. opens it, sizes it, sets all the local
3394
+"options etc
3395
+function! s:createTreeWin()
3396
+    "create the nerd tree window
3397
+    let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright "
3398
+    let splitSize = g:NERDTreeWinSize
3399
+
3400
+    if !exists('t:NERDTreeBufName')
3401
+        let t:NERDTreeBufName = s:nextBufferName()
3402
+        silent! exec splitLocation . 'vertical ' . splitSize . ' new'
3403
+        silent! exec "edit " . t:NERDTreeBufName
3404
+    else
3405
+        silent! exec splitLocation . 'vertical ' . splitSize . ' split'
3406
+        silent! exec "buffer " . t:NERDTreeBufName
3407
+    endif
3408
+
3409
+    setlocal winfixwidth
3410
+    call s:setCommonBufOptions()
3411
+endfunction
3412
+
3413
+"FUNCTION: s:dumpHelp  {{{2
3414
+"prints out the quick help
3415
+function! s:dumpHelp()
3416
+    let old_h = @h
3417
+    if b:treeShowHelp ==# 1
3418
+        let @h=   "\" NERD tree (" . s:NERD_tree_version . ") quickhelp~\n"
3419
+        let @h=@h."\" ============================\n"
3420
+        let @h=@h."\" File node mappings~\n"
3421
+        let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n"
3422
+        let @h=@h."\" <CR>,\n"
3423
+        if b:NERDTreeType ==# "primary"
3424
+            let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n"
3425
+        else
3426
+            let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n"
3427
+        endif
3428
+        if b:NERDTreeType ==# "primary"
3429
+            let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n"
3430
+        endif
3431
+        let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
3432
+        let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
3433
+        let @h=@h."\" middle-click,\n"
3434
+        let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n"
3435
+        let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n"
3436
+        let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n"
3437
+        let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n"
3438
+
3439
+        let @h=@h."\"\n\" ----------------------------\n"
3440
+        let @h=@h."\" Directory node mappings~\n"
3441
+        let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n"
3442
+        let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n"
3443
+        let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n"
3444
+        let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n"
3445
+        let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n"
3446
+        let @h=@h."\"    current node recursively\n"
3447
+        let @h=@h."\" middle-click,\n"
3448
+        let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n"
3449
+
3450
+        let @h=@h."\"\n\" ----------------------------\n"
3451
+        let @h=@h."\" Bookmark table mappings~\n"
3452
+        let @h=@h."\" double-click,\n"
3453
+        let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n"
3454
+        let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n"
3455
+        let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n"
3456
+        let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n"
3457
+
3458
+        let @h=@h."\"\n\" ----------------------------\n"
3459
+        let @h=@h."\" Tree navigation mappings~\n"
3460
+        let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n"
3461
+        let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n"
3462
+        let @h=@h."\" ". g:NERDTreeMapJumpFirstChild  .": go to first child\n"
3463
+        let @h=@h."\" ". g:NERDTreeMapJumpLastChild   .": go to last child\n"
3464
+        let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n"
3465
+        let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n"
3466
+
3467
+        let @h=@h."\"\n\" ----------------------------\n"
3468
+        let @h=@h."\" Filesystem mappings~\n"
3469
+        let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n"
3470
+        let @h=@h."\"    selected dir\n"
3471
+        let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n"
3472
+        let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n"
3473
+        let @h=@h."\"    but leave old root open\n"
3474
+        let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n"
3475
+        let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n"
3476
+        let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n"
3477
+        let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n"
3478
+        let @h=@h."\"    selected dir\n"
3479
+        let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n"
3480
+
3481
+        let @h=@h."\"\n\" ----------------------------\n"
3482
+        let @h=@h."\" Tree filtering mappings~\n"
3483
+        let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n"
3484
+        let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n"
3485
+        let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n"
3486
+        let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n"
3487
+
3488
+        "add quickhelp entries for each custom key map
3489
+        let @h=@h."\"\n\" ----------------------------\n"
3490
+        let @h=@h."\" Custom mappings~\n"
3491
+        for i in s:KeyMap.All()
3492
+            if !empty(i.quickhelpText)
3493
+                let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n"
3494
+            endif
3495
+        endfor
3496
+
3497
+        let @h=@h."\"\n\" ----------------------------\n"
3498
+        let @h=@h."\" Other mappings~\n"
3499
+        let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n"
3500
+        let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n"
3501
+        let @h=@h."\"    the NERDTree window\n"
3502
+        let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n"
3503
+        let @h=@h."\"\n\" ----------------------------\n"
3504
+        let @h=@h."\" Bookmark commands~\n"
3505
+        let @h=@h."\" :Bookmark <name>\n"
3506
+        let @h=@h."\" :BookmarkToRoot <name>\n"
3507
+        let @h=@h."\" :RevealBookmark <name>\n"
3508
+        let @h=@h."\" :OpenBookmark <name>\n"
3509
+        let @h=@h."\" :ClearBookmarks [<names>]\n"
3510
+        let @h=@h."\" :ClearAllBookmarks\n"
3511
+        silent! put h
3512
+    elseif g:NERDTreeMinimalUI == 0
3513
+        let @h="\" Press ". g:NERDTreeMapHelp ." for help\n"
3514
+        silent! put h
3515
+    endif
3516
+
3517
+    let @h = old_h
3518
+endfunction
3519
+"FUNCTION: s:echo  {{{2
3520
+"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages
3521
+"
3522
+"Args:
3523
+"msg: the message to echo
3524
+function! s:echo(msg)
3525
+    redraw
3526
+    echomsg "NERDTree: " . a:msg
3527
+endfunction
3528
+"FUNCTION: s:echoWarning {{{2
3529
+"Wrapper for s:echo, sets the message type to warningmsg for this message
3530
+"Args:
3531
+"msg: the message to echo
3532
+function! s:echoWarning(msg)
3533
+    echohl warningmsg
3534
+    call s:echo(a:msg)
3535
+    echohl normal
3536
+endfunction
3537
+"FUNCTION: s:echoError {{{2
3538
+"Wrapper for s:echo, sets the message type to errormsg for this message
3539
+"Args:
3540
+"msg: the message to echo
3541
+function! s:echoError(msg)
3542
+    echohl errormsg
3543
+    call s:echo(a:msg)
3544
+    echohl normal
3545
+endfunction
3546
+"FUNCTION: s:firstUsableWindow(){{{2
3547
+"find the window number of the first normal window
3548
+function! s:firstUsableWindow()
3549
+    let i = 1
3550
+    while i <= winnr("$")
3551
+        let bnum = winbufnr(i)
3552
+        if bnum != -1 && getbufvar(bnum, '&buftype') ==# ''
3553
+                    \ && !getwinvar(i, '&previewwindow')
3554
+                    \ && (!getbufvar(bnum, '&modified') || &hidden)
3555
+            return i
3556
+        endif
3557
+
3558
+        let i += 1
3559
+    endwhile
3560
+    return -1
3561
+endfunction
3562
+"FUNCTION: s:getPath(ln) {{{2
3563
+"Gets the full path to the node that is rendered on the given line number
3564
+"
3565
+"Args:
3566
+"ln: the line number to get the path for
3567
+"
3568
+"Return:
3569
+"A path if a node was selected, {} if nothing is selected.
3570
+"If the 'up a dir' line was selected then the path to the parent of the
3571
+"current root is returned
3572
+function! s:getPath(ln)
3573
+    let line = getline(a:ln)
3574
+
3575
+    let rootLine = s:TreeFileNode.GetRootLineNum()
3576
+
3577
+    "check to see if we have the root node
3578
+    if a:ln == rootLine
3579
+        return b:NERDTreeRoot.path
3580
+    endif
3581
+
3582
+    if !g:NERDTreeDirArrows
3583
+        " in case called from outside the tree
3584
+        if line !~# '^ *[|`▸▾ ]' || line =~# '^$'
3585
+            return {}
3586
+        endif
3587
+    endif
3588
+
3589
+    if line ==# s:tree_up_dir_line
3590
+        return b:NERDTreeRoot.path.getParent()
3591
+    endif
3592
+
3593
+    let indent = s:indentLevelFor(line)
3594
+
3595
+    "remove the tree parts and the leading space
3596
+    let curFile = s:stripMarkupFromLine(line, 0)
3597
+
3598
+    let wasdir = 0
3599
+    if curFile =~# '/$'
3600
+        let wasdir = 1
3601
+        let curFile = substitute(curFile, '/\?$', '/', "")
3602
+    endif
3603
+
3604
+    let dir = ""
3605
+    let lnum = a:ln
3606
+    while lnum > 0
3607
+        let lnum = lnum - 1
3608
+        let curLine = getline(lnum)
3609
+        let curLineStripped = s:stripMarkupFromLine(curLine, 1)
3610
+
3611
+        "have we reached the top of the tree?
3612
+        if lnum == rootLine
3613
+            let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir
3614
+            break
3615
+        endif
3616
+        if curLineStripped =~# '/$'
3617
+            let lpindent = s:indentLevelFor(curLine)
3618
+            if lpindent < indent
3619
+                let indent = indent - 1
3620
+
3621
+                let dir = substitute (curLineStripped,'^\\', "", "") . dir
3622
+                continue
3623
+            endif
3624
+        endif
3625
+    endwhile
3626
+    let curFile = b:NERDTreeRoot.path.drive . dir . curFile
3627
+    let toReturn = s:Path.New(curFile)
3628
+    return toReturn
3629
+endfunction
3630
+
3631
+"FUNCTION: s:getTreeWinNum() {{{2
3632
+"gets the nerd tree window number for this tab
3633
+function! s:getTreeWinNum()
3634
+    if exists("t:NERDTreeBufName")
3635
+        return bufwinnr(t:NERDTreeBufName)
3636
+    else
3637
+        return -1
3638
+    endif
3639
+endfunction
3640
+"FUNCTION: s:indentLevelFor(line) {{{2
3641
+function! s:indentLevelFor(line)
3642
+    let level = match(a:line, '[^ \-+~▸▾`|]') / s:tree_wid
3643
+    " check if line includes arrows
3644
+    if match(a:line, '[▸▾]') > -1
3645
+        " decrement level as arrow uses 3 ascii chars
3646
+        let level = level - 1
3647
+    endif
3648
+    return level
3649
+endfunction
3650
+"FUNCTION: s:isTreeOpen() {{{2
3651
+function! s:isTreeOpen()
3652
+    return s:getTreeWinNum() != -1
3653
+endfunction
3654
+"FUNCTION: s:isWindowUsable(winnumber) {{{2
3655
+"Returns 0 if opening a file from the tree in the given window requires it to
3656
+"be split, 1 otherwise
3657
+"
3658
+"Args:
3659
+"winnumber: the number of the window in question
3660
+function! s:isWindowUsable(winnumber)
3661
+    "gotta split if theres only one window (i.e. the NERD tree)
3662
+    if winnr("$") ==# 1
3663
+        return 0
3664
+    endif
3665
+
3666
+    let oldwinnr = winnr()
3667
+    call s:exec(a:winnumber . "wincmd p")
3668
+    let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
3669
+    let modified = &modified
3670
+    call s:exec(oldwinnr . "wincmd p")
3671
+
3672
+    "if its a special window e.g. quickfix or another explorer plugin then we
3673
+    "have to split
3674
+    if specialWindow
3675
+        return 0
3676
+    endif
3677
+
3678
+    if &hidden
3679
+        return 1
3680
+    endif
3681
+
3682
+    return !modified || s:bufInWindows(winbufnr(a:winnumber)) >= 2
3683
+endfunction
3684
+
3685
+" FUNCTION: s:jumpToChild(direction) {{{2
3686
+" Args:
3687
+" direction: 0 if going to first child, 1 if going to last
3688
+function! s:jumpToChild(currentNode, direction)
3689
+    if a:currentNode.isRoot()
3690
+        return s:echo("cannot jump to " . (a:direction ? "last" : "first") .  " child")
3691
+    end
3692
+    let dirNode = a:currentNode.parent
3693
+    let childNodes = dirNode.getVisibleChildren()
3694
+
3695
+    let targetNode = childNodes[0]
3696
+    if a:direction
3697
+        let targetNode = childNodes[len(childNodes) - 1]
3698
+    endif
3699
+
3700
+    if targetNode.equals(a:currentNode)
3701
+        let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction)
3702
+        if siblingDir != {}
3703
+            let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0
3704
+            let targetNode = siblingDir.getChildByIndex(indx, 1)
3705
+        endif
3706
+    endif
3707
+
3708
+    call targetNode.putCursorHere(1, 0)
3709
+
3710
+    call s:centerView()
3711
+endfunction
3712
+
3713
+
3714
+" FUNCTION: s:jumpToSibling(currentNode, forward) {{{2
3715
+" moves the cursor to the sibling of the current node in the given direction
3716
+"
3717
+" Args:
3718
+" forward: 1 if the cursor should move to the next sibling, 0 if it should
3719
+" move back to the previous sibling
3720
+function! s:jumpToSibling(currentNode, forward)
3721
+    let sibling = a:currentNode.findSibling(a:forward)
3722
+
3723
+    if !empty(sibling)
3724
+        call sibling.putCursorHere(1, 0)
3725
+        call s:centerView()
3726
+    endif
3727
+endfunction
3728
+
3729
+"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{2
3730
+"prints out the given msg and, if the user responds by pushing 'y' then the
3731
+"buffer with the given bufnum is deleted
3732
+"
3733
+"Args:
3734
+"bufnum: the buffer that may be deleted
3735
+"msg: a message that will be echoed to the user asking them if they wish to
3736
+"     del the buffer
3737
+function! s:promptToDelBuffer(bufnum, msg)
3738
+    echo a:msg
3739
+    if nr2char(getchar()) ==# 'y'
3740
+        exec "silent bdelete! " . a:bufnum
3741
+    endif
3742
+endfunction
3743
+
3744
+"FUNCTION: s:putCursorOnBookmarkTable(){{{2
3745
+"Places the cursor at the top of the bookmarks table
3746
+function! s:putCursorOnBookmarkTable()
3747
+    if !b:NERDTreeShowBookmarks
3748
+        throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active"
3749
+    endif
3750
+
3751
+    if g:NERDTreeMinimalUI
3752
+        return cursor(1, 2)
3753
+    endif
3754
+
3755
+    let rootNodeLine = s:TreeFileNode.GetRootLineNum()
3756
+
3757
+    let line = 1
3758
+    while getline(line) !~# '^>-\+Bookmarks-\+$'
3759
+        let line = line + 1
3760
+        if line >= rootNodeLine
3761
+            throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table"
3762
+        endif
3763
+    endwhile
3764
+    call cursor(line, 2)
3765
+endfunction
3766
+
3767
+"FUNCTION: s:putCursorInTreeWin(){{{2
3768
+"Places the cursor in the nerd tree window
3769
+function! s:putCursorInTreeWin()
3770
+    if !s:isTreeOpen()
3771
+        throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists"
3772
+    endif
3773
+
3774
+    call s:exec(s:getTreeWinNum() . "wincmd w")
3775
+endfunction
3776
+
3777
+"FUNCTION: s:renderBookmarks {{{2
3778
+function! s:renderBookmarks()
3779
+
3780
+    if g:NERDTreeMinimalUI == 0
3781
+        call setline(line(".")+1, ">----------Bookmarks----------")
3782
+        call cursor(line(".")+1, col("."))
3783
+    endif
3784
+
3785
+    for i in s:Bookmark.Bookmarks()
3786
+        call setline(line(".")+1, i.str())
3787
+        call cursor(line(".")+1, col("."))
3788
+    endfor
3789
+
3790
+    call setline(line(".")+1, '')
3791
+    call cursor(line(".")+1, col("."))
3792
+endfunction
3793
+"FUNCTION: s:renderView {{{2
3794
+"The entry function for rendering the tree
3795
+function! s:renderView()
3796
+    setlocal modifiable
3797
+
3798
+    "remember the top line of the buffer and the current line so we can
3799
+    "restore the view exactly how it was
3800
+    let curLine = line(".")
3801
+    let curCol = col(".")
3802
+    let topLine = line("w0")
3803
+
3804
+    "delete all lines in the buffer (being careful not to clobber a register)
3805
+    silent 1,$delete _
3806
+
3807
+    call s:dumpHelp()
3808
+
3809
+    "delete the blank line before the help and add one after it
3810
+    if g:NERDTreeMinimalUI == 0
3811
+        call setline(line(".")+1, "")
3812
+        call cursor(line(".")+1, col("."))
3813
+    endif
3814
+
3815
+    if b:NERDTreeShowBookmarks
3816
+        call s:renderBookmarks()
3817
+    endif
3818
+
3819
+    "add the 'up a dir' line
3820
+    if !g:NERDTreeMinimalUI
3821
+        call setline(line(".")+1, s:tree_up_dir_line)
3822
+        call cursor(line(".")+1, col("."))
3823
+    endif
3824
+
3825
+    "draw the header line
3826
+    let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
3827
+    call setline(line(".")+1, header)
3828
+    call cursor(line(".")+1, col("."))
3829
+
3830
+    "draw the tree
3831
+    let old_o = @o
3832
+    let @o = b:NERDTreeRoot.renderToString()
3833
+    silent put o
3834
+    let @o = old_o
3835
+
3836
+    "delete the blank line at the top of the buffer
3837
+    silent 1,1delete _
3838
+
3839
+    "restore the view
3840
+    let old_scrolloff=&scrolloff
3841
+    let &scrolloff=0
3842
+    call cursor(topLine, 1)
3843
+    normal! zt
3844
+    call cursor(curLine, curCol)
3845
+    let &scrolloff = old_scrolloff
3846
+
3847
+    setlocal nomodifiable
3848
+endfunction
3849
+
3850
+"FUNCTION: s:renderViewSavingPosition {{{2
3851
+"Renders the tree and ensures the cursor stays on the current node or the
3852
+"current nodes parent if it is no longer available upon re-rendering
3853
+function! s:renderViewSavingPosition()
3854
+    let currentNode = s:TreeFileNode.GetSelected()
3855
+
3856
+    "go up the tree till we find a node that will be visible or till we run
3857
+    "out of nodes
3858
+    while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot()
3859
+        let currentNode = currentNode.parent
3860
+    endwhile
3861
+
3862
+    call s:renderView()
3863
+
3864
+    if currentNode != {}
3865
+        call currentNode.putCursorHere(0, 0)
3866
+    endif
3867
+endfunction
3868
+"FUNCTION: s:restoreScreenState() {{{2
3869
+"
3870
+"Sets the screen state back to what it was when s:saveScreenState was last
3871
+"called.
3872
+"
3873
+"Assumes the cursor is in the NERDTree window
3874
+function! s:restoreScreenState()
3875
+    if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize")
3876
+        return
3877
+    endif
3878
+    exec("silent vertical resize ".b:NERDTreeOldWindowSize)
3879
+
3880
+    let old_scrolloff=&scrolloff
3881
+    let &scrolloff=0
3882
+    call cursor(b:NERDTreeOldTopLine, 0)
3883
+    normal! zt
3884
+    call setpos(".", b:NERDTreeOldPos)
3885
+    let &scrolloff=old_scrolloff
3886
+endfunction
3887
+
3888
+"FUNCTION: s:saveScreenState() {{{2
3889
+"Saves the current cursor position in the current buffer and the window
3890
+"scroll position
3891
+function! s:saveScreenState()
3892
+    let win = winnr()
3893
+    try
3894
+        call s:putCursorInTreeWin()
3895
+        let b:NERDTreeOldPos = getpos(".")
3896
+        let b:NERDTreeOldTopLine = line("w0")
3897
+        let b:NERDTreeOldWindowSize = winwidth("")
3898
+        call s:exec(win . "wincmd w")
3899
+    catch /^NERDTree.InvalidOperationError/
3900
+    endtry
3901
+endfunction
3902
+
3903
+"FUNCTION: s:setCommonBufOptions() {{{2
3904
+function! s:setCommonBufOptions()
3905
+    "throwaway buffer options
3906
+    setlocal noswapfile
3907
+    setlocal buftype=nofile
3908
+    setlocal bufhidden=hide
3909
+    setlocal nowrap
3910
+    setlocal foldcolumn=0
3911
+    setlocal foldmethod=manual
3912
+    setlocal nofoldenable
3913
+    setlocal nobuflisted
3914
+    setlocal nospell
3915
+    if g:NERDTreeShowLineNumbers
3916
+        setlocal nu
3917
+    else
3918
+        setlocal nonu
3919
+        if v:version >= 703
3920
+            setlocal nornu
3921
+        endif
3922
+    endif
3923
+
3924
+    iabc <buffer>
3925
+
3926
+    if g:NERDTreeHighlightCursorline
3927
+        setlocal cursorline
3928
+    endif
3929
+
3930
+    call s:setupStatusline()
3931
+
3932
+
3933
+    let b:treeShowHelp = 0
3934
+    let b:NERDTreeIgnoreEnabled = 1
3935
+    let b:NERDTreeShowFiles = g:NERDTreeShowFiles
3936
+    let b:NERDTreeShowHidden = g:NERDTreeShowHidden
3937
+    let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
3938
+    setfiletype nerdtree
3939
+    call s:bindMappings()
3940
+endfunction
3941
+
3942
+"FUNCTION: s:setupStatusline() {{{2
3943
+function! s:setupStatusline()
3944
+    if g:NERDTreeStatusline != -1
3945
+        let &l:statusline = g:NERDTreeStatusline
3946
+    endif
3947
+endfunction
3948
+"FUNCTION: s:stripMarkupFromLine(line, removeLeadingSpaces){{{2
3949
+"returns the given line with all the tree parts stripped off
3950
+"
3951
+"Args:
3952
+"line: the subject line
3953
+"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces =
3954
+"any spaces before the actual text of the node)
3955
+function! s:stripMarkupFromLine(line, removeLeadingSpaces)
3956
+    let line = a:line
3957
+    "remove the tree parts and the leading space
3958
+    let line = substitute (line, s:tree_markup_reg,"","")
3959
+
3960
+    "strip off any read only flag
3961
+    let line = substitute (line, ' \[RO\]', "","")
3962
+
3963
+    "strip off any bookmark flags
3964
+    let line = substitute (line, ' {[^}]*}', "","")
3965
+
3966
+    "strip off any executable flags
3967
+    let line = substitute (line, '*\ze\($\| \)', "","")
3968
+
3969
+    let wasdir = 0
3970
+    if line =~# '/$'
3971
+        let wasdir = 1
3972
+    endif
3973
+    let line = substitute (line,' -> .*',"","") " remove link to
3974
+    if wasdir ==# 1
3975
+        let line = substitute (line, '/\?$', '/', "")
3976
+    endif
3977
+
3978
+    if a:removeLeadingSpaces
3979
+        let line = substitute (line, '^ *', '', '')
3980
+    endif
3981
+
3982
+    return line
3983
+endfunction
3984
+
3985
+"FUNCTION: s:toggle(dir) {{{2
3986
+"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is
3987
+"closed it is restored or initialized (if it doesnt exist)
3988
+"
3989
+"Args:
3990
+"dir: the full path for the root node (is only used if the NERD tree is being
3991
+"initialized.
3992
+function! s:toggle(dir)
3993
+    if s:treeExistsForTab()
3994
+        if !s:isTreeOpen()
3995
+            call s:createTreeWin()
3996
+            if !&hidden
3997
+                call s:renderView()
3998
+            endif
3999
+            call s:restoreScreenState()
4000
+        else
4001
+            call s:closeTree()
4002
+        endif
4003
+    else
4004
+        call s:initNerdTree(a:dir)
4005
+    endif
4006
+endfunction
4007
+"SECTION: Interface bindings {{{1
4008
+"============================================================
4009
+
4010
+"FUNCTION: s:activateAll() {{{2
4011
+"handle the user activating the updir line
4012
+function! s:activateAll()
4013
+    if getline(".") ==# s:tree_up_dir_line
4014
+        return s:upDir(0)
4015
+    endif
4016
+endfunction
4017
+
4018
+"FUNCTION: s:activateDirNode() {{{2
4019
+"handle the user activating a tree node
4020
+function! s:activateDirNode(node)
4021
+    call a:node.activate({'reuse': 1})
4022
+endfunction
4023
+
4024
+"FUNCTION: s:activateFileNode() {{{2
4025
+"handle the user activating a tree node
4026
+function! s:activateFileNode(node)
4027
+    call a:node.activate({'reuse': 1, 'where': 'p'})
4028
+endfunction
4029
+
4030
+"FUNCTION: s:activateBookmark() {{{2
4031
+"handle the user activating a bookmark
4032
+function! s:activateBookmark(bm)
4033
+    call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {})
4034
+endfunction
4035
+
4036
+"FUNCTION: s:bindMappings() {{{2
4037
+function! s:bindMappings()
4038
+    "make <cr> do the same as the default 'o' mapping
4039
+    exec "nnoremap <silent> <buffer> <cr> :call <SID>KeyMap_Invoke('". g:NERDTreeMapActivateNode ."')<cr>"
4040
+
4041
+    call s:KeyMap.BindAll()
4042
+
4043
+    command! -buffer -nargs=? Bookmark :call <SID>bookmarkNode('<args>')
4044
+    command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 RevealBookmark :call <SID>revealBookmark('<args>')
4045
+    command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 OpenBookmark :call <SID>openBookmark('<args>')
4046
+    command! -buffer -complete=customlist,s:completeBookmarks -nargs=* ClearBookmarks call <SID>clearBookmarks('<args>')
4047
+    command! -buffer -complete=customlist,s:completeBookmarks -nargs=+ BookmarkToRoot call s:Bookmark.ToRoot('<args>')
4048
+    command! -buffer -nargs=0 ClearAllBookmarks call s:Bookmark.ClearAll() <bar> call <SID>renderView()
4049
+    command! -buffer -nargs=0 ReadBookmarks call s:Bookmark.CacheBookmarks(0) <bar> call <SID>renderView()
4050
+    command! -buffer -nargs=0 WriteBookmarks call s:Bookmark.Write()
4051
+endfunction
4052
+
4053
+" FUNCTION: s:bookmarkNode(name) {{{2
4054
+" Associate the current node with the given name
4055
+function! s:bookmarkNode(...)
4056
+    let currentNode = s:TreeFileNode.GetSelected()
4057
+    if currentNode != {}
4058
+        let name = a:1
4059
+        if empty(name)
4060
+            let name = currentNode.path.getLastPathComponent(0)
4061
+        endif
4062
+        try
4063
+            call currentNode.bookmark(name)
4064
+            call s:renderView()
4065
+        catch /^NERDTree.IllegalBookmarkNameError/
4066
+            call s:echo("bookmark names must not contain spaces")
4067
+        endtry
4068
+    else
4069
+        call s:echo("select a node first")
4070
+    endif
4071
+endfunction
4072
+
4073
+" FUNCTION: s:chCwd(node) {{{2
4074
+function! s:chCwd(node)
4075
+    try
4076
+        call a:node.path.changeToDir()
4077
+    catch /^NERDTree.PathChangeError/
4078
+        call s:echoWarning("could not change cwd")
4079
+    endtry
4080
+endfunction
4081
+
4082
+" FUNCTION: s:chRoot(node) {{{2
4083
+" changes the current root to the selected one
4084
+function! s:chRoot(node)
4085
+    call a:node.makeRoot()
4086
+    call s:renderView()
4087
+    call b:NERDTreeRoot.putCursorHere(0, 0)
4088
+endfunction
4089
+
4090
+" FUNCTION: s:chRootCwd() {{{2
4091
+" changes the current root to CWD
4092
+function! s:chRootCwd()
4093
+    try
4094
+        let cwd = s:Path.New(getcwd())
4095
+    catch /^NERDTree.InvalidArgumentsError/
4096
+        call s:echo("current directory does not exist.")
4097
+        return
4098
+    endtry
4099
+    if cwd.str() == s:TreeFileNode.GetRootForTab().path.str()
4100
+       return
4101
+    endif
4102
+    call s:chRoot(s:TreeDirNode.New(cwd))
4103
+endfunction
4104
+
4105
+" FUNCTION: s:clearBookmarks(bookmarks) {{{2
4106
+function! s:clearBookmarks(bookmarks)
4107
+    if a:bookmarks ==# ''
4108
+        let currentNode = s:TreeFileNode.GetSelected()
4109
+        if currentNode != {}
4110
+            call currentNode.clearBookmarks()
4111
+        endif
4112
+    else
4113
+        for name in split(a:bookmarks, ' ')
4114
+            let bookmark = s:Bookmark.BookmarkFor(name)
4115
+            call bookmark.delete()
4116
+        endfor
4117
+    endif
4118
+    call s:renderView()
4119
+endfunction
4120
+" FUNCTION: s:closeChildren(node) {{{2
4121
+" closes all childnodes of the current node
4122
+function! s:closeChildren(node)
4123
+    call a:node.closeChildren()
4124
+    call s:renderView()
4125
+    call a:node.putCursorHere(0, 0)
4126
+endfunction
4127
+" FUNCTION: s:closeCurrentDir(node) {{{2
4128
+" closes the parent dir of the current node
4129
+function! s:closeCurrentDir(node)
4130
+    let parent = a:node.parent
4131
+    if parent ==# {} || parent.isRoot()
4132
+        call s:echo("cannot close tree root")
4133
+    else
4134
+        call a:node.parent.close()
4135
+        call s:renderView()
4136
+        call a:node.parent.putCursorHere(0, 0)
4137
+    endif
4138
+endfunction
4139
+" FUNCTION: s:closeTreeWindow() {{{2
4140
+" close the tree window
4141
+function! s:closeTreeWindow()
4142
+    if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1
4143
+        exec "buffer " . b:NERDTreePreviousBuf
4144
+    else
4145
+        if winnr("$") > 1
4146
+            call s:closeTree()
4147
+        else
4148
+            call s:echo("Cannot close last window")
4149
+        endif
4150
+    endif
4151
+endfunction
4152
+" FUNCTION: s:deleteBookmark(bm) {{{2
4153
+" if the cursor is on a bookmark, prompt to delete
4154
+function! s:deleteBookmark(bm)
4155
+    echo  "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):"
4156
+
4157
+    if  nr2char(getchar()) ==# 'y'
4158
+        try
4159
+            call a:bm.delete()
4160
+            call s:renderView()
4161
+            redraw
4162
+        catch /^NERDTree/
4163
+            call s:echoWarning("Could not remove bookmark")
4164
+        endtry
4165
+    else
4166
+        call s:echo("delete aborted" )
4167
+    endif
4168
+
4169
+endfunction
4170
+
4171
+" FUNCTION: s:displayHelp() {{{2
4172
+" toggles the help display
4173
+function! s:displayHelp()
4174
+    let b:treeShowHelp = b:treeShowHelp ? 0 : 1
4175
+    call s:renderView()
4176
+    call s:centerView()
4177
+endfunction
4178
+
4179
+"FUNCTION: s:handleLeftClick() {{{2
4180
+"Checks if the click should open the current node
4181
+function! s:handleLeftClick()
4182
+    let currentNode = s:TreeFileNode.GetSelected()
4183
+    if currentNode != {}
4184
+
4185
+        "the dir arrows are multibyte chars, and vim's string functions only
4186
+        "deal with single bytes - so split the line up with the hack below and
4187
+        "take the line substring manually
4188
+        let line = split(getline(line(".")), '\zs')
4189
+        let startToCur = ""
4190
+        for i in range(0,len(line)-1)
4191
+            let startToCur .= line[i]
4192
+        endfor
4193
+
4194
+        if currentNode.path.isDirectory
4195
+            if startToCur =~# s:tree_markup_reg && startToCur =~# '[+~▾▸] \?$'
4196
+                call currentNode.activate()
4197
+                return
4198
+            endif
4199
+        endif
4200
+
4201
+        if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
4202
+            let char = strpart(startToCur, strlen(startToCur)-1, 1)
4203
+            if char !~# s:tree_markup_reg
4204
+                if currentNode.path.isDirectory
4205
+                    call currentNode.activate()
4206
+                else
4207
+                    call currentNode.activate({'reuse': 1, 'where': 'p'})
4208
+                endif
4209
+                return
4210
+            endif
4211
+        endif
4212
+    endif
4213
+endfunction
4214
+
4215
+" FUNCTION: s:handleMiddleMouse() {{{2
4216
+function! s:handleMiddleMouse()
4217
+    let curNode = s:TreeFileNode.GetSelected()
4218
+    if curNode ==# {}
4219
+        call s:echo("Put the cursor on a node first" )
4220
+        return
4221
+    endif
4222
+
4223
+    if curNode.path.isDirectory
4224
+        call s:openExplorer(curNode)
4225
+    else
4226
+        call curNode.open({'where': 'h'})
4227
+    endif
4228
+endfunction
4229
+
4230
+" FUNCTION: s:jumpToFirstChild() {{{2
4231
+" wrapper for the jump to child method
4232
+function! s:jumpToFirstChild(node)
4233
+    call s:jumpToChild(a:node, 0)
4234
+endfunction
4235
+
4236
+" FUNCTION: s:jumpToLastChild() {{{2
4237
+" wrapper for the jump to child method
4238
+function! s:jumpToLastChild(node)
4239
+    call s:jumpToChild(a:node, 1)
4240
+endfunction
4241
+
4242
+" FUNCTION: s:jumpToParent(node) {{{2
4243
+" moves the cursor to the parent of the current node
4244
+function! s:jumpToParent(node)
4245
+    if !empty(a:node.parent)
4246
+        call a:node.parent.putCursorHere(1, 0)
4247
+        call s:centerView()
4248
+    else
4249
+        call s:echo("cannot jump to parent")
4250
+    endif
4251
+endfunction
4252
+
4253
+" FUNCTION: s:jumpToRoot() {{{2
4254
+" moves the cursor to the root node
4255
+function! s:jumpToRoot()
4256
+    call b:NERDTreeRoot.putCursorHere(1, 0)
4257
+    call s:centerView()
4258
+endfunction
4259
+
4260
+" FUNCTION: s:jumpToNextSibling(node) {{{2
4261
+function! s:jumpToNextSibling(node)
4262
+    call s:jumpToSibling(a:node, 1)
4263
+endfunction
4264
+
4265
+" FUNCTION: s:jumpToPrevSibling(node) {{{2
4266
+function! s:jumpToPrevSibling(node)
4267
+    call s:jumpToSibling(a:node, 0)
4268
+endfunction
4269
+
4270
+" FUNCTION: s:openBookmark(name) {{{2
4271
+" put the cursor on the given bookmark and, if its a file, open it
4272
+function! s:openBookmark(name)
4273
+    try
4274
+        let targetNode = s:Bookmark.GetNodeForName(a:name, 0)
4275
+        call targetNode.putCursorHere(0, 1)
4276
+        redraw!
4277
+    catch /^NERDTree.BookmarkedNodeNotFoundError/
4278
+        call s:echo("note - target node is not cached")
4279
+        let bookmark = s:Bookmark.BookmarkFor(a:name)
4280
+        let targetNode = s:TreeFileNode.New(bookmark.path)
4281
+    endtry
4282
+    if targetNode.path.isDirectory
4283
+        call targetNode.openExplorer()
4284
+    else
4285
+        call targetNode.open({'where': 'p'})
4286
+    endif
4287
+endfunction
4288
+
4289
+" FUNCTION: s:openHSplit(target) {{{2
4290
+function! s:openHSplit(target)
4291
+    call a:target.activate({'where': 'h'})
4292
+endfunction
4293
+
4294
+" FUNCTION: s:openVSplit(target) {{{2
4295
+function! s:openVSplit(target)
4296
+    call a:target.activate({'where': 'v'})
4297
+endfunction
4298
+
4299
+" FUNCTION: s:openExplorer(node) {{{2
4300
+function! s:openExplorer(node)
4301
+    call a:node.openExplorer()
4302
+endfunction
4303
+
4304
+" FUNCTION: s:openInNewTab(target) {{{2
4305
+function! s:openInNewTab(target)
4306
+    call a:target.activate({'where': 't'})
4307
+endfunction
4308
+
4309
+" FUNCTION: s:openInNewTabSilent(target) {{{2
4310
+function! s:openInNewTabSilent(target)
4311
+    call a:target.activate({'where': 't', 'stay': 1})
4312
+endfunction
4313
+
4314
+" FUNCTION: s:openNodeRecursively(node) {{{2
4315
+function! s:openNodeRecursively(node)
4316
+    call s:echo("Recursively opening node. Please wait...")
4317
+    call a:node.openRecursively()
4318
+    call s:renderView()
4319
+    redraw
4320
+    call s:echo("Recursively opening node. Please wait... DONE")
4321
+endfunction
4322
+
4323
+"FUNCTION: s:previewNodeCurrent(node) {{{2
4324
+function! s:previewNodeCurrent(node)
4325
+    call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
4326
+endfunction
4327
+
4328
+"FUNCTION: s:previewNodeHSplit(node) {{{2
4329
+function! s:previewNodeHSplit(node)
4330
+    call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
4331
+endfunction
4332
+
4333
+"FUNCTION: s:previewNodeVSplit(node) {{{2
4334
+function! s:previewNodeVSplit(node)
4335
+    call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
4336
+endfunction
4337
+
4338
+" FUNCTION: s:revealBookmark(name) {{{2
4339
+" put the cursor on the node associate with the given name
4340
+function! s:revealBookmark(name)
4341
+    try
4342
+        let targetNode = s:Bookmark.GetNodeForName(a:name, 0)
4343
+        call targetNode.putCursorHere(0, 1)
4344
+    catch /^NERDTree.BookmarkNotFoundError/
4345
+        call s:echo("Bookmark isnt cached under the current root")
4346
+    endtry
4347
+endfunction
4348
+" FUNCTION: s:refreshRoot() {{{2
4349
+" Reloads the current root. All nodes below this will be lost and the root dir
4350
+" will be reloaded.
4351
+function! s:refreshRoot()
4352
+    call s:echo("Refreshing the root node. This could take a while...")
4353
+    call b:NERDTreeRoot.refresh()
4354
+    call s:renderView()
4355
+    redraw
4356
+    call s:echo("Refreshing the root node. This could take a while... DONE")
4357
+endfunction
4358
+
4359
+" FUNCTION: s:refreshCurrent(node) {{{2
4360
+" refreshes the root for the current node
4361
+function! s:refreshCurrent(node)
4362
+    let node = a:node
4363
+    if !node.path.isDirectory
4364
+        let node = node.parent
4365
+    endif
4366
+
4367
+    call s:echo("Refreshing node. This could take a while...")
4368
+    call node.refresh()
4369
+    call s:renderView()
4370
+    redraw
4371
+    call s:echo("Refreshing node. This could take a while... DONE")
4372
+endfunction
4373
+" FUNCTION: s:showMenu(node) {{{2
4374
+function! s:showMenu(node)
4375
+    let mc = s:MenuController.New(s:MenuItem.AllEnabled())
4376
+    call mc.showMenu()
4377
+endfunction
4378
+
4379
+" FUNCTION: s:toggleIgnoreFilter() {{{2
4380
+" toggles the use of the NERDTreeIgnore option
4381
+function! s:toggleIgnoreFilter()
4382
+    let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled
4383
+    call s:renderViewSavingPosition()
4384
+    call s:centerView()
4385
+endfunction
4386
+
4387
+" FUNCTION: s:toggleShowBookmarks() {{{2
4388
+" toggles the display of bookmarks
4389
+function! s:toggleShowBookmarks()
4390
+    let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
4391
+    if b:NERDTreeShowBookmarks
4392
+        call s:renderView()
4393
+        call s:putCursorOnBookmarkTable()
4394
+    else
4395
+        call s:renderViewSavingPosition()
4396
+    endif
4397
+    call s:centerView()
4398
+endfunction
4399
+" FUNCTION: s:toggleShowFiles() {{{2
4400
+" toggles the display of hidden files
4401
+function! s:toggleShowFiles()
4402
+    let b:NERDTreeShowFiles = !b:NERDTreeShowFiles
4403
+    call s:renderViewSavingPosition()
4404
+    call s:centerView()
4405
+endfunction
4406
+
4407
+" FUNCTION: s:toggleShowHidden() {{{2
4408
+" toggles the display of hidden files
4409
+function! s:toggleShowHidden()
4410
+    let b:NERDTreeShowHidden = !b:NERDTreeShowHidden
4411
+    call s:renderViewSavingPosition()
4412
+    call s:centerView()
4413
+endfunction
4414
+
4415
+" FUNCTION: s:toggleZoom() {{{2
4416
+" zoom (maximize/minimize) the NERDTree window
4417
+function! s:toggleZoom()
4418
+    if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed
4419
+        let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
4420
+        exec "silent vertical resize ". size
4421
+        let b:NERDTreeZoomed = 0
4422
+    else
4423
+        exec "vertical resize"
4424
+        let b:NERDTreeZoomed = 1
4425
+    endif
4426
+endfunction
4427
+
4428
+" FUNCTION: s:upDirCurrentRootOpen() {{{2
4429
+function! s:upDirCurrentRootOpen()
4430
+    call s:upDir(1)
4431
+endfunction
4432
+
4433
+" FUNCTION: s:upDirCurrentRootClosed() {{{2
4434
+function! s:upDirCurrentRootClosed()
4435
+    call s:upDir(0)
4436
+endfunction
4437
+
4438
+" SECTION: Post Source Actions {{{1
4439
+call s:postSourceActions()
4440
+
4441
+"reset &cpo back to users setting
4442
+let &cpo = s:old_cpo
4443
+
4444
+" vim: set sw=4 sts=4 et fdm=marker:
... ...
@@ -0,0 +1,88 @@
1
+let s:tree_up_dir_line = '.. (up a dir)'
2
+"NERDTreeFlags are syntax items that should be invisible, but give clues as to
3
+"how things should be highlighted
4
+syn match NERDTreeFlag #\~#
5
+syn match NERDTreeFlag #\[RO\]#
6
+
7
+"highlighting for the .. (up dir) line at the top of the tree
8
+execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#"
9
+
10
+"highlighting for the ~/+ symbols for the directory nodes
11
+syn match NERDTreeClosable #\~\<#
12
+syn match NERDTreeClosable #\~\.#
13
+syn match NERDTreeOpenable #+\<#
14
+syn match NERDTreeOpenable #+\.#he=e-1
15
+
16
+"highlighting for the tree structural parts
17
+syn match NERDTreePart #|#
18
+syn match NERDTreePart #`#
19
+syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart
20
+
21
+"quickhelp syntax elements
22
+syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1
23
+syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1
24
+syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag
25
+syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey
26
+syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey
27
+syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3
28
+syn match NERDTreeHelp  #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
29
+
30
+"highlighting for readonly files
31
+syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
32
+
33
+"highlighting for sym links
34
+syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash
35
+
36
+"highlighing for directory nodes and file nodes
37
+syn match NERDTreeDirSlash #/#
38
+syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable
39
+syn match NERDTreeExecFile  #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark
40
+syn match NERDTreeFile  #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
41
+syn match NERDTreeFile  #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
42
+syn match NERDTreeCWD #^[</].*$#
43
+
44
+"highlighting for bookmarks
45
+syn match NERDTreeBookmark # {.*}#hs=s+1
46
+
47
+"highlighting for the bookmarks table
48
+syn match NERDTreeBookmarksLeader #^>#
49
+syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader
50
+syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader
51
+syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader
52
+
53
+if exists("g:NERDChristmasTree") && g:NERDChristmasTree
54
+    hi def link NERDTreePart Special
55
+    hi def link NERDTreePartFile Type
56
+    hi def link NERDTreeFile Normal
57
+    hi def link NERDTreeExecFile Title
58
+    hi def link NERDTreeDirSlash Identifier
59
+    hi def link NERDTreeClosable Type
60
+else
61
+    hi def link NERDTreePart Normal
62
+    hi def link NERDTreePartFile Normal
63
+    hi def link NERDTreeFile Normal
64
+    hi def link NERDTreeClosable Title
65
+endif
66
+
67
+hi def link NERDTreeBookmarksHeader statement
68
+hi def link NERDTreeBookmarksLeader ignore
69
+hi def link NERDTreeBookmarkName Identifier
70
+hi def link NERDTreeBookmark normal
71
+
72
+hi def link NERDTreeHelp String
73
+hi def link NERDTreeHelpKey Identifier
74
+hi def link NERDTreeHelpCommand Identifier
75
+hi def link NERDTreeHelpTitle Macro
76
+hi def link NERDTreeToggleOn Question
77
+hi def link NERDTreeToggleOff WarningMsg
78
+
79
+hi def link NERDTreeDir Directory
80
+hi def link NERDTreeUp Directory
81
+hi def link NERDTreeCWD Statement
82
+hi def link NERDTreeLink Macro
83
+hi def link NERDTreeOpenable Title
84
+hi def link NERDTreeFlag ignore
85
+hi def link NERDTreeRO WarningMsg
86
+hi def link NERDTreeBookmark Statement
87
+
88
+hi def link NERDTreeCurrentNode Search
... ...
@@ -0,0 +1,1501 @@
1
+*taglist.txt*	Plugin for browsing source code
2
+
3
+Author: Yegappan Lakshmanan  (yegappan AT yahoo DOT com)
4
+For Vim version 6.0 and above
5
+Last change: 2007 May 24
6
+
7
+1. Overview 					|taglist-intro|
8
+2. Taglist on the internet			|taglist-internet|
9
+3. Requirements					|taglist-requirements|
10
+4. Installation 				|taglist-install|
11
+5. Usage 					|taglist-using|
12
+6. Options 					|taglist-options|
13
+7. Commands 					|taglist-commands|
14
+8. Global functions 				|taglist-functions|
15
+9. Extending 					|taglist-extend|
16
+10. FAQ 					|taglist-faq|
17
+11. License 					|taglist-license|
18
+12. Todo					|taglist-todo|
19
+
20
+==============================================================================
21
+						*taglist-intro*
22
+1. Overview~
23
+
24
+The "Tag List" plugin is a source code browser plugin for Vim. This plugin
25
+allows you to efficiently browse through source code files for different
26
+programming languages. The "Tag List" plugin provides the following features:
27
+
28
+    * Displays the tags (functions, classes, structures, variables, etc.) 
29
+      defined in a file in a vertically or horizontally split Vim window.
30
+    * In GUI Vim, optionally displays the tags in the Tags drop-down menu and
31
+      in the popup menu.
32
+    * Automatically updates the taglist window as you switch between
33
+      files/buffers. As you open new files, the tags defined in the new files
34
+      are added to the existing file list and the tags defined in all the
35
+      files are displayed grouped by the filename.
36
+    * When a tag name is selected from the taglist window, positions the
37
+      cursor at the definition of the tag in the source file.
38
+    * Automatically highlights the current tag name.
39
+    * Groups the tags by their type and displays them in a foldable tree.
40
+    * Can display the prototype and scope of a tag.
41
+    * Can optionally display the tag prototype instead of the tag name in the
42
+      taglist window.
43
+    * The tag list can be sorted either by name or by chronological order.
44
+    * Supports the following language files: Assembly, ASP, Awk, Beta, C,
45
+      C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp,
46
+      Lua, Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang,
47
+      SML, Sql, TCL, Verilog, Vim and Yacc.
48
+    * Can be easily extended to support new languages. Support for
49
+      existing languages can be modified easily.
50
+    * Provides functions to display the current tag name in the Vim status
51
+      line or the window title bar.
52
+    * The list of tags and files in the taglist can be saved and
53
+      restored across Vim sessions.
54
+    * Provides commands to get the name and prototype of the current tag.
55
+    * Runs in both console/terminal and GUI versions of Vim.
56
+    * Works with the winmanager plugin. Using the winmanager plugin, you
57
+      can use Vim plugins like the file explorer, buffer explorer and the
58
+      taglist plugin at the same time like an IDE.
59
+    * Can be used in both Unix and MS-Windows systems.
60
+
61
+==============================================================================
62
+						*taglist-internet*
63
+2. Taglist on the internet~
64
+
65
+The home page of the taglist plugin is at:
66
+>
67
+	http://vim-taglist.sourceforge.net/
68
+<
69
+You can subscribe to the taglist mailing list to post your questions or
70
+suggestions for improvement or to send bug reports. Visit the following page
71
+for subscribing to the mailing list:
72
+>
73
+	http://groups.yahoo.com/group/taglist
74
+<
75
+==============================================================================
76
+						*taglist-requirements*
77
+3. Requirements~
78
+
79
+The taglist plugin requires the following:
80
+
81
+    * Vim version 6.0 and above
82
+    * Exuberant ctags 5.0 and above
83
+
84
+The taglist plugin will work on all the platforms where the exuberant ctags
85
+utility and Vim are supported (this includes MS-Windows and Unix based
86
+systems).
87
+
88
+The taglist plugin relies on the exuberant ctags utility to dynamically
89
+generate the tag listing.  The exuberant ctags utility must be installed in
90
+your system to use this plugin.  The exuberant ctags utility is shipped with
91
+most of the Linux distributions.  You can download the exuberant ctags utility
92
+from
93
+>
94
+	http://ctags.sourceforge.net
95
+<
96
+The taglist plugin doesn't use or create a tags file and there is no need to
97
+create a tags file to use this plugin. The taglist plugin will not work with
98
+the GNU ctags or the Unix ctags utility.
99
+
100
+This plugin relies on the Vim "filetype" detection mechanism to determine the
101
+type of the current file. You have to turn on the Vim filetype detection by
102
+adding the following line to your .vimrc file:
103
+>
104
+	filetype on
105
+<
106
+The taglist plugin will not work if you run Vim in the restricted mode (using
107
+the -Z command-line argument).
108
+
109
+The taglist plugin uses the Vim system() function to invoke the exuberant
110
+ctags utility. If Vim is compiled without the system() function then you
111
+cannot use the taglist plugin. Some of the Linux distributions (Suse) compile
112
+Vim without the system() function for security reasons.
113
+
114
+==============================================================================
115
+						*taglist-install*
116
+4. Installation~
117
+
118
+1. Download the taglist.zip file and unzip the files to the $HOME/.vim or the
119
+   $HOME/vimfiles or the $VIM/vimfiles directory. After this step, you should
120
+   have the following two files (the directory structure should be preserved):
121
+
122
+	plugin/taglist.vim - main taglist plugin file
123
+	doc/taglist.txt    - documentation (help) file
124
+
125
+   Refer to the |add-plugin|and |'runtimepath'| Vim help pages for more
126
+   details about installing Vim plugins.
127
+2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or $VIM/vimfiles/doc
128
+   directory, start Vim and run the ":helptags ." command to process the
129
+   taglist help file. Without this step, you cannot jump to the taglist help
130
+   topics.
131
+3. If the exuberant ctags utility is not present in one of the directories in
132
+   the PATH environment variable, then set the 'Tlist_Ctags_Cmd' variable to
133
+   point to the location of the exuberant ctags utility (not to the directory)
134
+   in the .vimrc file.
135
+4. If you are running a terminal/console version of Vim and the terminal
136
+   doesn't support changing the window width then set the
137
+   'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file.
138
+5. Restart Vim.
139
+6. You can now use the ":TlistToggle" command to open/close the taglist
140
+   window. You can use the ":help taglist" command to get more information
141
+   about using the taglist plugin.
142
+
143
+To uninstall the taglist plugin, remove the plugin/taglist.vim and
144
+doc/taglist.txt files from the $HOME/.vim or $HOME/vimfiles directory.
145
+
146
+==============================================================================
147
+						*taglist-using*
148
+5. Usage~
149
+
150
+The taglist plugin can be used in several different ways.
151
+
152
+1. You can keep the taglist window open during the entire editing session. On
153
+   opening the taglist window, the tags defined in all the files in the Vim
154
+   buffer list will be displayed in the taglist window. As you edit files, the
155
+   tags defined in them will be added to the taglist window. You can select a
156
+   tag from the taglist window and jump to it. The current tag will be
157
+   highlighted in the taglist window. You can close the taglist window when
158
+   you no longer need the window.
159
+2. You can configure the taglist plugin to process the tags defined in all the
160
+   edited files always. In this configuration, even if the taglist window is
161
+   closed and the taglist menu is not displayed, the taglist plugin will
162
+   processes the tags defined in newly edited files. You can then open the
163
+   taglist window only when you need to select a tag and then automatically
164
+   close the taglist window after selecting the tag.
165
+3. You can configure the taglist plugin to display only the tags defined in
166
+   the current file in the taglist window. By default, the taglist plugin
167
+   displays the tags defined in all the files in the Vim buffer list. As you
168
+   switch between files, the taglist window will be refreshed to display only
169
+   the tags defined in the current file.
170
+4. In GUI Vim, you can use the Tags pull-down and popup menu created by the
171
+   taglist plugin to display the tags defined in the current file and select a
172
+   tag to jump to it. You can use the menu without opening the taglist window.
173
+   By default, the Tags menu is disabled.
174
+5. You can configure the taglist plugin to display the name of the current tag
175
+   in the Vim window status line or in the Vim window title bar. For this to
176
+   work without the taglist window or menu, you need to configure the taglist
177
+   plugin to process the tags defined in a file always.
178
+6. You can save the tags defined in multiple files to a taglist session file
179
+   and load it when needed. You can also configure the taglist plugin to not
180
+   update the taglist window when editing new files. You can then manually add
181
+   files to the taglist window.
182
+
183
+Opening the taglist window~
184
+You can open the taglist window using the ":TlistOpen" or the ":TlistToggle"
185
+commands. The ":TlistOpen" command opens the taglist window and jumps to it.
186
+The ":TlistToggle" command opens or closes (toggle) the taglist window and the
187
+cursor remains in the current window. If the 'Tlist_GainFocus_On_ToggleOpen'
188
+variable is set to 1, then the ":TlistToggle" command opens the taglist window
189
+and moves the cursor to the taglist window.
190
+
191
+You can map a key to invoke these commands. For example, the following command
192
+creates a normal mode mapping for the <F8> key to toggle the taglist window.
193
+>
194
+	nnoremap <silent> <F8> :TlistToggle<CR>
195
+<
196
+Add the above mapping to your ~/.vimrc or $HOME/_vimrc file.
197
+
198
+To automatically open the taglist window on Vim startup, set the
199
+'Tlist_Auto_Open' variable to 1.
200
+
201
+You can also open the taglist window on startup using the following command
202
+line:
203
+>
204
+	$ vim +TlistOpen
205
+<
206
+Closing the taglist window~
207
+You can close the taglist window from the taglist window by pressing 'q' or
208
+using the Vim ":q" command. You can also use any of the Vim window commands to
209
+close the taglist window. Invoking the ":TlistToggle" command when the taglist
210
+window is opened, closes the taglist window. You can also use the
211
+":TlistClose" command to close the taglist window.
212
+
213
+To automatically close the taglist window when a tag or file is selected, you
214
+can set the 'Tlist_Close_On_Select' variable to 1.  To exit Vim when only the
215
+taglist window is present, set the 'Tlist_Exit_OnlyWindow' variable to 1.
216
+
217
+Jumping to a tag or a file~
218
+You can select a tag in the taglist window either by pressing the <Enter> key
219
+or by double clicking the tag name using the mouse. To jump to a tag on a
220
+single mouse click set the 'Tlist_Use_SingleClick' variable to 1.
221
+
222
+If the selected file is already opened in a window, then the cursor is moved
223
+to that window. If the file is not currently opened in a window then the file
224
+is opened in the window used by the taglist plugin to show the previously
225
+selected file. If there are no usable windows, then the file is opened in a
226
+new window.  The file is not opened in special windows like the quickfix
227
+window, preview window and windows containing buffer with the 'buftype' option
228
+set.
229
+
230
+To jump to the tag in a new window, press the 'o' key. To open the file in the
231
+previous window (Ctrl-W_p) use the 'P' key. You can press the 'p' key to jump
232
+to the tag but still keep the cursor in the taglist window (preview).
233
+
234
+To open the selected file in a tab, use the 't' key.  If the file is already
235
+present in a tab then the cursor is moved to that tab otherwise the file is
236
+opened in a new tab. To jump to a tag in a new tab press Ctrl-t.  The taglist
237
+window is automatically opened in the newly created tab.
238
+
239
+Instead of jumping to a tag, you can open a file by pressing the <Enter> key
240
+or by double clicking the file name using the mouse.
241
+
242
+In the taglist window, you can use the [[ or <Backspace> key to jump to the
243
+beginning of the previous file. You can use the ]] or <Tab> key to jump to the
244
+beginning of the next file. When you reach the first or last file, the search
245
+wraps around and the jumps to the next/previous file.
246
+
247
+Highlighting the current tag~
248
+The taglist plugin automatically highlights the name of the current tag in the
249
+taglist window. The Vim |CursorHold| autocmd event is used for this. If the
250
+current tag name is not visible in the taglist window, then the taglist window
251
+contents are scrolled to make that tag name visible. You can also use the
252
+":TlistHighlightTag" command to force the highlighting of the current tag.
253
+
254
+The tag name is highlighted if no activity is performed for |'updatetime'|
255
+milliseconds. The default value for this Vim option is 4 seconds. To avoid
256
+unexpected problems, you should not set the |'updatetime'| option to a very
257
+low value.
258
+
259
+To disable the automatic highlighting of the current tag name in the taglist
260
+window, set the 'Tlist_Auto_Highlight_Tag' variable to zero.
261
+
262
+When entering a Vim buffer/window, the taglist plugin automatically highlights
263
+the current tag in that buffer/window.  If you like to disable the automatic
264
+highlighting of the current tag when entering a buffer, set the
265
+'Tlist_Highlight_Tag_On_BufEnter' variable to zero.
266
+
267
+Adding files to the taglist~
268
+When the taglist window is opened, all the files in the Vim buffer list are
269
+processed and the supported files are added to the taglist.  When you edit a
270
+file in Vim, the taglist plugin automatically processes this file and adds it
271
+to the taglist. If you close the taglist window, the tag information in the
272
+taglist is retained.
273
+
274
+To process files even when the taglist window is not open, set the
275
+'Tlist_Process_File_Always' variable to 1.
276
+
277
+You can manually add multiple files to the taglist without opening them using
278
+the ":TlistAddFiles" and the ":TlistAddFilesRecursive" commands.
279
+
280
+For example, to add all the C files in the /my/project/dir directory to the
281
+taglist, you can use the following command:
282
+>
283
+	:TlistAddFiles /my/project/dir/*.c
284
+<
285
+Note that when adding several files with a large number of tags or a large
286
+number of files, it will take several seconds to several minutes for the
287
+taglist plugin to process all the files. You should not interrupt the taglist
288
+plugin by pressing <CTRL-C>.
289
+
290
+You can recursively add multiple files from a directory tree using the
291
+":TlistAddFilesRecursive" command:
292
+>
293
+	:TlistAddFilesRecursive /my/project/dir *.c
294
+<
295
+This command takes two arguments. The first argument specifies the directory
296
+from which to recursively add the files. The second optional argument
297
+specifies the wildcard matching pattern for selecting the files to add. The
298
+default pattern is * and all the files are added.
299
+
300
+Displaying tags for only one file~
301
+The taglist window displays the tags for all the files in the Vim buffer list
302
+and all the manually added files. To display the tags for only the current
303
+active buffer, set the 'Tlist_Show_One_File' variable to 1.
304
+
305
+Removing files from the taglist~
306
+You can remove a file from the taglist window, by pressing the 'd' key when the
307
+cursor is on one of the tags listed for the file in the taglist window. The
308
+removed file will no longer be displayed in the taglist window in the current
309
+Vim session. To again display the tags for the file, open the file in a Vim
310
+window and then use the ":TlistUpdate" command or use ":TlistAddFiles" command
311
+to add the file to the taglist.
312
+
313
+When a buffer is removed from the Vim buffer list using the ":bdelete" or the
314
+":bwipeout" command, the taglist is updated to remove the stored information
315
+for this buffer.
316
+
317
+Updating the tags displayed for a file~
318
+The taglist plugin keeps track of the modification time of a file. When the
319
+modification time changes (the file is modified), the taglist plugin
320
+automatically updates the tags listed for that file. The modification time of
321
+a file is checked when you enter a window containing that file or when you
322
+load that file.
323
+
324
+You can also update or refresh the tags displayed for a file by pressing the
325
+"u" key in the taglist window. If an existing file is modified, after the file
326
+is saved, the taglist plugin automatically updates the tags displayed for the
327
+file.
328
+
329
+You can also use the ":TlistUpdate" command to update the tags for the current
330
+buffer after you made some changes to it. You should save the modified buffer
331
+before you update the taglist window. Otherwise the listed tags will not
332
+include the new tags created in the buffer. 
333
+
334
+If you have deleted the tags displayed for a file in the taglist window using
335
+the 'd' key, you can again display the tags for that file using the
336
+":TlistUpdate" command.
337
+
338
+Controlling the taglist updates~
339
+To disable the automatic processing of new files or modified files, you can
340
+set the 'Tlist_Auto_Update' variable to zero. When this variable is set to
341
+zero, the taglist is updated only when you use the ":TlistUpdate" command or
342
+the ":TlistAddFiles" or the ":TlistAddFilesRecursive" commands. You can use
343
+this option to control which files are added to the taglist.
344
+
345
+You can use the ":TlistLock" command to lock the taglist contents. After this
346
+command is executed, new files are not automatically added to the taglist.
347
+When the taglist is locked, you can use the ":TlistUpdate" command to add the
348
+current file or the ":TlistAddFiles" or ":TlistAddFilesRecursive" commands to
349
+add new files to the taglist.  To unlock the taglist, use the ":TlistUnlock"
350
+command.
351
+
352
+Displaying the tag prototype~
353
+To display the prototype of the tag under the cursor in the taglist window,
354
+press the space bar. If you place the cursor on a tag name in the taglist
355
+window, then the tag prototype is displayed at the Vim status line after
356
+|'updatetime'| milliseconds. The default value for the |'updatetime'| Vim
357
+option is 4 seconds.
358
+
359
+You can get the name and prototype of a tag without opening the taglist window
360
+and the taglist menu using the ":TlistShowTag" and the ":TlistShowPrototype"
361
+commands. These commands will work only if the current file is already present
362
+in the taglist. To use these commands without opening the taglist window, set
363
+the 'Tlist_Process_File_Always' variable to 1.
364
+
365
+You can use the ":TlistShowTag" command to display the name of the tag at or
366
+before the specified line number in the specified file.  If the file name and
367
+line number are not supplied, then this command will display the name of the
368
+current tag. For example,
369
+>
370
+	:TlistShowTag
371
+	:TlistShowTag myfile.java 100
372
+<
373
+You can use the ":TlistShowPrototype" command to display the prototype of the
374
+tag at or before the specified line number in the specified file.  If the file
375
+name and the line number are not supplied, then this command will display the
376
+prototype of the current tag.  For example,
377
+>
378
+	:TlistShowPrototype
379
+	:TlistShowPrototype myfile.c 50
380
+<
381
+In the taglist window, when the mouse is moved over a tag name, the tag
382
+prototype is displayed in a balloon. This works only in GUI versions where
383
+balloon evaluation is supported.
384
+
385
+Taglist window contents~
386
+The taglist window contains the tags defined in various files in the taglist
387
+grouped by the filename and by the tag type (variable, function, class, etc.).
388
+For tags with scope information (like class members, structures inside
389
+structures, etc.), the scope information is displayed in square brackets "[]"
390
+after the tag name.
391
+
392
+The contents of the taglist buffer/window are managed by the taglist plugin.
393
+The |'filetype'| for the taglist buffer is set to 'taglist'.  The Vim
394
+|'modifiable'| option is turned off for the taglist buffer. You should not
395
+manually edit the taglist buffer, by setting the |'modifiable'| flag. If you
396
+manually edit the taglist buffer contents, then the taglist plugin will be out
397
+of sync with the taglist buffer contents and the plugin will no longer work
398
+correctly. To redisplay the taglist buffer contents again, close the taglist
399
+window and reopen it.
400
+
401
+Opening and closing the tag and file tree~
402
+In the taglist window, the tag names are displayed as a foldable tree using
403
+the Vim folding support. You can collapse the tree using the '-' key or using
404
+the Vim |zc| fold command. You can open the tree using the '+' key or using
405
+the Vim |zo| fold command. You can open all the folds using the '*' key or
406
+using the Vim |zR| fold command. You can also use the mouse to open/close the
407
+folds. You can close all the folds using the '=' key. You should not manually
408
+create or delete the folds in the taglist window.
409
+
410
+To automatically close the fold for the inactive files/buffers and open only
411
+the fold for the current buffer in the taglist window, set the
412
+'Tlist_File_Fold_Auto_Close' variable to 1.
413
+
414
+Sorting the tags for a file~
415
+The tags displayed in the taglist window can be sorted either by their name or
416
+by their chronological order. The default sorting method is by the order in
417
+which the tags appear in a file. You can change the default sort method by
418
+setting the 'Tlist_Sort_Type' variable to either "name" or "order". You can
419
+sort the tags by their name by pressing the "s" key in the taglist window. You
420
+can again sort the tags by their chronological order using the "s" key. Each
421
+file in the taglist window can be sorted using different order.
422
+
423
+Zooming in and out of the taglist window~
424
+You can press the 'x' key in the taglist window to maximize the taglist
425
+window width/height. The window will be maximized to the maximum possible
426
+width/height without closing the other existing windows. You can again press
427
+'x' to restore the taglist window to the default width/height.
428
+
429
+						*taglist-session*
430
+Taglist Session~
431
+A taglist session refers to the group of files and their tags stored in the
432
+taglist in a Vim session.
433
+
434
+You can save and restore a taglist session (and all the displayed tags) using
435
+the ":TlistSessionSave" and ":TlistSessionLoad" commands.
436
+
437
+To save the information about the tags and files in the taglist to a file, use
438
+the ":TlistSessionSave" command and specify the filename:
439
+>
440
+	:TlistSessionSave <file name>
441
+<
442
+To load a saved taglist session, use the ":TlistSessionLoad" command: >
443
+
444
+	:TlistSessionLoad <file name>
445
+<
446
+When you load a taglist session file, the tags stored in the file will be
447
+added to the tags already stored in the taglist.
448
+
449
+The taglist session feature can be used to save the tags for large files or a
450
+group of frequently used files (like a project). By using the taglist session
451
+file, you can minimize the amount to time it takes to load/refresh the taglist
452
+for multiple files.
453
+
454
+You can create more than one taglist session file for multiple groups of
455
+files.
456
+
457
+Displaying the tag name in the Vim status line or the window title bar~
458
+You can use the Tlist_Get_Tagname_By_Line() function provided by the taglist
459
+plugin to display the current tag name in the Vim status line or the window
460
+title bar. Similarly, you can use the Tlist_Get_Tag_Prototype_By_Line()
461
+function to display the current tag prototype in the Vim status line or the
462
+window title bar.
463
+
464
+For example, the following command can be used to display the current tag name
465
+in the status line:
466
+>
467
+	:set statusline=%<%f%=%([%{Tlist_Get_Tagname_By_Line()}]%)
468
+<
469
+The following command can be used to display the current tag name in the
470
+window title bar:
471
+>
472
+	:set title titlestring=%<%f\ %([%{Tlist_Get_Tagname_By_Line()}]%)
473
+<
474
+Note that the current tag name can be displayed only after the file is
475
+processed by the taglist plugin. For this, you have to either set the
476
+'Tlist_Process_File_Always' variable to 1 or open the taglist window or use
477
+the taglist menu. For more information about configuring the Vim status line,
478
+refer to the documentation for the Vim |'statusline'| option.
479
+
480
+Changing the taglist window highlighting~
481
+The following Vim highlight groups are defined and used to highlight the
482
+various entities in the taglist window:
483
+
484
+    TagListTagName  - Used for tag names
485
+    TagListTagScope - Used for tag scope
486
+    TagListTitle    - Used for tag titles
487
+    TagListComment  - Used for comments
488
+    TagListFileName - Used for filenames
489
+
490
+By default, these highlight groups are linked to the standard Vim highlight
491
+groups. If you want to change the colors used for these highlight groups,
492
+prefix the highlight group name with 'My' and define it in your .vimrc or
493
+.gvimrc file: MyTagListTagName, MyTagListTagScope, MyTagListTitle,
494
+MyTagListComment and MyTagListFileName.  For example, to change the colors
495
+used for tag names, you can use the following command:
496
+>
497
+    :highlight MyTagListTagName guifg=blue ctermfg=blue
498
+<
499
+Controlling the taglist window~
500
+To use a horizontally split taglist window, instead of a vertically split
501
+window, set the 'Tlist_Use_Horiz_Window' variable to 1.
502
+
503
+To use a vertically split taglist window on the rightmost side of the Vim
504
+window, set the 'Tlist_Use_Right_Window' variable to 1.
505
+
506
+You can specify the width of the vertically split taglist window, by setting
507
+the 'Tlist_WinWidth' variable.  You can specify the height of the horizontally
508
+split taglist window, by setting the 'Tlist_WinHeight' variable.
509
+
510
+When opening a vertically split taglist window, the Vim window width is
511
+increased to accommodate the new taglist window. When the taglist window is
512
+closed, the Vim window is reduced. To disable this, set the
513
+'Tlist_Inc_Winwidth' variable to zero.
514
+
515
+To reduce the number of empty lines in the taglist window, set the
516
+'Tlist_Compact_Format' variable to 1.
517
+
518
+To not display the Vim fold column in the taglist window, set the
519
+'Tlist_Enable_Fold_Column' variable to zero.
520
+
521
+To display the tag prototypes instead of the tag names in the taglist window,
522
+set the 'Tlist_Display_Prototype' variable to 1.
523
+
524
+To not display the scope of the tags next to the tag names, set the
525
+'Tlist_Display_Tag_Scope' variable to zero.
526
+
527
+						*taglist-keys*
528
+Taglist window key list~
529
+The following table lists the description of the keys that can be used
530
+in the taglist window.
531
+
532
+  Key           Description~
533
+
534
+  <CR>          Jump to the location where the tag under cursor is
535
+                defined.
536
+  o             Jump to the location where the tag under cursor is
537
+                defined in a new window.
538
+  P             Jump to the tag in the previous (Ctrl-W_p) window.
539
+  p             Display the tag definition in the file window and
540
+                keep the cursor in the taglist window itself.
541
+  t             Jump to the tag in a new tab. If the file is already
542
+                opened in a tab, move to that tab.
543
+  Ctrl-t	Jump to the tag in a new tab.
544
+  <Space>       Display the prototype of the tag under the cursor.
545
+  		For file names, display the full path to the file,
546
+		file type and the number of tags. For tag types, display the
547
+		tag type and the number of tags.
548
+  u             Update the tags listed in the taglist window
549
+  s             Change the sort order of the tags (by name or by order)
550
+  d             Remove the tags for the file under the cursor
551
+  x             Zoom-in or Zoom-out the taglist window
552
+  +             Open a fold
553
+  -             Close a fold
554
+  *             Open all folds
555
+  =             Close all folds
556
+  [[		Jump to the beginning of the previous file
557
+  <Backspace>	Jump to the beginning of the previous file
558
+  ]]		Jump to the beginning of the next file
559
+  <Tab>		Jump to the beginning of the next file
560
+  q             Close the taglist window
561
+  <F1>          Display help
562
+
563
+The above keys will work in both the normal mode and the insert mode.
564
+
565
+						*taglist-menu*
566
+Taglist menu~
567
+When using GUI Vim, the taglist plugin can display the tags defined in the
568
+current file in the drop-down menu and the popup menu. By default, this
569
+feature is turned off. To turn on this feature, set the 'Tlist_Show_Menu'
570
+variable to 1.
571
+
572
+You can jump to a tag by selecting the tag name from the menu. You can use the
573
+taglist menu independent of the taglist window i.e. you don't need to open the
574
+taglist window to get the taglist menu.
575
+
576
+When you switch between files/buffers, the taglist menu is automatically
577
+updated to display the tags defined in the current file/buffer.
578
+
579
+The tags are grouped by their type (variables, functions, classes, methods,
580
+etc.) and displayed as a separate sub-menu for each type. If all the tags
581
+defined in a file are of the same type (e.g. functions), then the sub-menu is
582
+not used.
583
+
584
+If the number of items in a tag type submenu exceeds the value specified by
585
+the 'Tlist_Max_Submenu_Items' variable, then the submenu will be split into
586
+multiple submenus. The default setting for 'Tlist_Max_Submenu_Items' is 25.
587
+The first and last tag names in the submenu are used to form the submenu name.
588
+The menu items are prefixed by alpha-numeric characters for easy selection by
589
+keyboard.
590
+
591
+If the popup menu support is enabled (the |'mousemodel'| option contains
592
+"popup"), then the tags menu is added to the popup menu. You can access
593
+the popup menu by right clicking on the GUI window.
594
+
595
+You can regenerate the tags menu by selecting the 'Tags->Refresh menu' entry.
596
+You can sort the tags listed in the menu either by name or by order by
597
+selecting the 'Tags->Sort menu by->Name/Order' menu entry.
598
+
599
+You can tear-off the Tags menu and keep it on the side of the Vim window
600
+for quickly locating the tags.
601
+
602
+Using the taglist plugin with the winmanager plugin~
603
+You can use the taglist plugin with the winmanager plugin. This will allow you
604
+to use the file explorer, buffer explorer and the taglist plugin at the same
605
+time in different windows. To use the taglist plugin with the winmanager
606
+plugin, set 'TagList' in the 'winManagerWindowLayout' variable. For example,
607
+to use the file explorer plugin and the taglist plugin at the same time, use
608
+the following setting: >
609
+
610
+	let winManagerWindowLayout = 'FileExplorer|TagList'
611
+<
612
+Getting help~
613
+If you have installed the taglist help file (this file), then you can use the
614
+Vim ":help taglist-<keyword>" command to get help on the various taglist
615
+topics.
616
+
617
+You can press the <F1> key in the taglist window to display the help
618
+information about using the taglist window. If you again press the <F1> key,
619
+the help information is removed from the taglist window.
620
+
621
+						*taglist-debug*
622
+Debugging the taglist plugin~
623
+You can use the ":TlistDebug" command to enable logging of the debug messages
624
+from the taglist plugin. To display the logged debug messages, you can use the
625
+":TlistMessages" command. To disable the logging of the debug messages, use
626
+the ":TlistUndebug" command.
627
+
628
+You can specify a file name to the ":TlistDebug" command to log the debug
629
+messages to a file. Otherwise, the debug messages are stored in a script-local
630
+variable. In the later case, to minimize memory usage, only the last 3000
631
+characters from the debug messages are stored.
632
+
633
+==============================================================================
634
+						*taglist-options*
635
+6. Options~
636
+
637
+A number of Vim variables control the behavior of the taglist plugin. These
638
+variables are initialized to a default value. By changing these variables you
639
+can change the behavior of the taglist plugin. You need to change these
640
+settings only if you want to change the behavior of the taglist plugin. You
641
+should use the |:let| command in your .vimrc file to change the setting of any
642
+of these variables. 
643
+
644
+The configurable taglist variables are listed below. For a detailed
645
+description of these variables refer to the text below this table.
646
+
647
+|'Tlist_Auto_Highlight_Tag'|	Automatically highlight the current tag in the
648
+				taglist.
649
+|'Tlist_Auto_Open'|		Open the taglist window when Vim starts.
650
+|'Tlist_Auto_Update'|		Automatically update the taglist to include
651
+				newly edited files.
652
+|'Tlist_Close_On_Select'|	Close the taglist window when a file or tag is
653
+				selected.
654
+|'Tlist_Compact_Format'|	Remove extra information and blank lines from
655
+       				the taglist window.
656
+|'Tlist_Ctags_Cmd'|		Specifies the path to the ctags utility.
657
+|'Tlist_Display_Prototype'|	Show prototypes and not tags in the taglist
658
+				window.
659
+|'Tlist_Display_Tag_Scope'|	Show tag scope next to the tag name.
660
+|'Tlist_Enable_Fold_Column'|	Show the fold indicator column in the taglist
661
+				window.
662
+|'Tlist_Exit_OnlyWindow'|	Close Vim if the taglist is the only window.
663
+|'Tlist_File_Fold_Auto_Close'|	Close tag folds for inactive buffers.
664
+|'Tlist_GainFocus_On_ToggleOpen'|
665
+				Jump to taglist window on open.
666
+|'Tlist_Highlight_Tag_On_BufEnter'|
667
+				On entering a buffer, automatically highlight
668
+				the current tag.
669
+|'Tlist_Inc_Winwidth'|		Increase the Vim window width to accommodate
670
+				the taglist window.
671
+|'Tlist_Max_Submenu_Items'|	Maximum number of items in a tags sub-menu.
672
+|'Tlist_Max_Tag_Length'|	Maximum tag length used in a tag menu entry.
673
+|'Tlist_Process_File_Always'|	Process files even when the taglist window is
674
+				closed.
675
+|'Tlist_Show_Menu'|		Display the tags menu.
676
+|'Tlist_Show_One_File'|		Show tags for the current buffer only.
677
+|'Tlist_Sort_Type'|		Sort method used for arranging the tags.
678
+|'Tlist_Use_Horiz_Window'|	Use a horizontally split window for the
679
+				taglist window.
680
+|'Tlist_Use_Right_Window'|	Place the taglist window on the right side.
681
+|'Tlist_Use_SingleClick'|	Single click on a tag jumps to it.
682
+|'Tlist_WinHeight'|		Horizontally split taglist window height.
683
+|'Tlist_WinWidth'|		Vertically split taglist window width.
684
+
685
+						*'Tlist_Auto_Highlight_Tag'*
686
+Tlist_Auto_Highlight_Tag~
687
+The taglist plugin will automatically highlight the current tag in the taglist
688
+window. If you want to disable this, then you can set the
689
+'Tlist_Auto_Highlight_Tag' variable to zero. Note that even though the current
690
+tag highlighting is disabled, the tags for a new file will still be added to
691
+the taglist window.
692
+>
693
+	let Tlist_Auto_Highlight_Tag = 0
694
+<
695
+With the above variable set to 1, you can use the ":TlistHighlightTag" command
696
+to highlight the current tag.
697
+
698
+						*'Tlist_Auto_Open'*
699
+Tlist_Auto_Open~
700
+To automatically open the taglist window, when you start Vim, you can set the
701
+'Tlist_Auto_Open' variable to 1. By default, this variable is set to zero and
702
+the taglist window will not be opened automatically on Vim startup.
703
+>
704
+	let Tlist_Auto_Open = 1
705
+<
706
+The taglist window is opened only when a supported type of file is opened on
707
+Vim startup. For example, if you open text files, then the taglist window will
708
+not be opened.
709
+
710
+						*'Tlist_Auto_Update'*
711
+Tlist_Auto_Update~
712
+When a new file is edited, the tags defined in the file are automatically
713
+processed and added to the taglist. To stop adding new files to the taglist,
714
+set the 'Tlist_Auto_Update' variable to zero. By default, this variable is set
715
+to 1.
716
+>
717
+	let Tlist_Auto_Update = 0
718
+<
719
+With the above variable set to 1, you can use the ":TlistUpdate" command to
720
+add the tags defined in the current file to the taglist.
721
+
722
+						*'Tlist_Close_On_Select'*
723
+Tlist_Close_On_Select~
724
+If you want to close the taglist window when a file or tag is selected, then
725
+set the 'Tlist_Close_On_Select' variable to 1. By default, this variable is
726
+set zero and when you select a tag or file from the taglist window, the window
727
+is not closed.
728
+>
729
+	let Tlist_Close_On_Select = 1
730
+<
731
+						*'Tlist_Compact_Format'*
732
+Tlist_Compact_Format~
733
+By default, empty lines are used to separate different tag types displayed for
734
+a file and the tags displayed for different files in the taglist window. If
735
+you want to display as many tags as possible in the taglist window, you can
736
+set the 'Tlist_Compact_Format' variable to 1 to get a compact display.
737
+>
738
+	let Tlist_Compact_Format = 1
739
+<
740
+						*'Tlist_Ctags_Cmd'*
741
+Tlist_Ctags_Cmd~
742
+The 'Tlist_Ctags_Cmd' variable specifies the location (path) of the exuberant
743
+ctags utility. If exuberant ctags is present in any one of the directories in
744
+the PATH environment variable, then there is no need to set this variable.
745
+
746
+The exuberant ctags tool can be installed under different names.  When the
747
+taglist plugin starts up, if the 'Tlist_Ctags_Cmd' variable is not set, it
748
+checks for the names exuberant-ctags, exctags, ctags, ctags.exe and tags in
749
+the PATH environment variable.  If any one of the named executable is found,
750
+then the Tlist_Ctags_Cmd variable is set to that name.
751
+
752
+If exuberant ctags is not present in one of the directories specified in the
753
+PATH environment variable, then set this variable to point to the location of
754
+the ctags utility in your system. Note that this variable should point to the
755
+fully qualified exuberant ctags location and NOT to the directory in which
756
+exuberant ctags is installed. If the exuberant ctags tool is not found in
757
+either PATH or in the specified location, then the taglist plugin will not be
758
+loaded. Examples:
759
+>
760
+	let Tlist_Ctags_Cmd = 'd:\tools\ctags.exe'
761
+	let Tlist_Ctags_Cmd = '/usr/local/bin/ctags'
762
+<
763
+						*'Tlist_Display_Prototype'*
764
+Tlist_Display_Prototype~
765
+By default, only the tag name will be displayed in the taglist window. If you
766
+like to see tag prototypes instead of names, set the 'Tlist_Display_Prototype'
767
+variable to 1. By default, this variable is set to zero and only tag names
768
+will be displayed.
769
+>
770
+	let Tlist_Display_Prototype = 1
771
+<
772
+						*'Tlist_Display_Tag_Scope'*
773
+Tlist_Display_Tag_Scope~
774
+By default, the scope of a tag (like a C++ class) will be displayed in
775
+square brackets next to the tag name. If you don't want the tag scopes
776
+to be displayed, then set the 'Tlist_Display_Tag_Scope' to zero. By default,
777
+this variable is set to 1 and the tag scopes will be displayed.
778
+>
779
+	let Tlist_Display_Tag_Scope = 0
780
+<
781
+						*'Tlist_Enable_Fold_Column'*
782
+Tlist_Enable_Fold_Column~
783
+By default, the Vim fold column is enabled and displayed in the taglist
784
+window. If you wish to disable this (for example, when you are working with a
785
+narrow Vim window or terminal), you can set the 'Tlist_Enable_Fold_Column'
786
+variable to zero.
787
+>
788
+	let Tlist_Enable_Fold_Column = 1
789
+<
790
+						*'Tlist_Exit_OnlyWindow'*
791
+Tlist_Exit_OnlyWindow~
792
+If you want to exit Vim if only the taglist window is currently opened, then
793
+set the 'Tlist_Exit_OnlyWindow' variable to 1. By default, this variable is
794
+set to zero and the Vim instance will not be closed if only the taglist window
795
+is present.
796
+>
797
+	let Tlist_Exit_OnlyWindow = 1
798
+<
799
+						*'Tlist_File_Fold_Auto_Close'*
800
+Tlist_File_Fold_Auto_Close~
801
+By default, the tags tree displayed in the taglist window for all the files is
802
+opened. You can close/fold the tags tree for the files manually. To
803
+automatically close the tags tree for inactive files, you can set the
804
+'Tlist_File_Fold_Auto_Close' variable to 1. When this variable is set to 1,
805
+the tags tree for the current buffer is automatically opened and for all the
806
+other buffers is closed.
807
+>
808
+	let Tlist_File_Fold_Auto_Close = 1
809
+<
810
+					    *'Tlist_GainFocus_On_ToggleOpen'*
811
+Tlist_GainFocus_On_ToggleOpen~
812
+When the taglist window is opened using the ':TlistToggle' command, this
813
+option controls whether the cursor is moved to the taglist window or remains
814
+in the current window. By default, this option is set to 0 and the cursor
815
+remains in the current window. When this variable is set to 1, the cursor
816
+moves to the taglist window after opening the taglist window.
817
+>
818
+	let Tlist_GainFocus_On_ToggleOpen = 1
819
+<
820
+					    *'Tlist_Highlight_Tag_On_BufEnter'*
821
+Tlist_Highlight_Tag_On_BufEnter~
822
+When you enter a Vim buffer/window, the current tag in that buffer/window is
823
+automatically highlighted in the taglist window. If the current tag name is
824
+not visible in the taglist window, then the taglist window contents are
825
+scrolled to make that tag name visible. If you like to disable the automatic
826
+highlighting of the current tag when entering a buffer, you can set the
827
+'Tlist_Highlight_Tag_On_BufEnter' variable to zero. The default setting for
828
+this variable is 1.
829
+>
830
+	let Tlist_Highlight_Tag_On_BufEnter = 0
831
+<
832
+						*'Tlist_Inc_Winwidth'*
833
+Tlist_Inc_Winwidth~
834
+By default, when the width of the window is less than 100 and a new taglist
835
+window is opened vertically, then the window width is increased by the value
836
+set in the 'Tlist_WinWidth' variable to accommodate the new window. The value
837
+of this variable is used only if you are using a vertically split taglist
838
+window.
839
+
840
+If your terminal doesn't support changing the window width from Vim (older
841
+version of xterm running in a Unix system) or if you see any weird problems in
842
+the screen due to the change in the window width or if you prefer not to
843
+adjust the window width then set the 'Tlist_Inc_Winwidth' variable to zero.
844
+CAUTION: If you are using the MS-Windows version of Vim in a MS-DOS command
845
+window then you must set this variable to zero, otherwise the system may hang
846
+due to a Vim limitation (explained in :help win32-problems)
847
+>
848
+	let Tlist_Inc_Winwidth = 0
849
+<
850
+						*'Tlist_Max_Submenu_Items'*
851
+Tlist_Max_Submenu_Items~
852
+If a file contains too many tags of a particular type (function, variable,
853
+class, etc.), greater than that specified by the 'Tlist_Max_Submenu_Items'
854
+variable, then the menu for that tag type will be split into multiple
855
+sub-menus. The default setting for the 'Tlist_Max_Submenu_Items' variable is
856
+25.  This can be changed by setting the 'Tlist_Max_Submenu_Items' variable:
857
+>
858
+	let Tlist_Max_Submenu_Items = 20
859
+<
860
+The name of the submenu is formed using the names of the first and the last
861
+tag entries in that submenu.
862
+
863
+						*'Tlist_Max_Tag_Length'*
864
+Tlist_Max_Tag_Length~
865
+Only the first 'Tlist_Max_Tag_Length' characters from the tag names will be
866
+used to form the tag type submenu name. The default value for this variable is
867
+10.  Change the 'Tlist_Max_Tag_Length' setting if you want to include more or
868
+less characters:
869
+>
870
+	let Tlist_Max_Tag_Length = 10
871
+<
872
+						*'Tlist_Process_File_Always'*
873
+Tlist_Process_File_Always~
874
+By default, the taglist plugin will generate and process the tags defined in
875
+the newly opened files only when the taglist window is opened or when the
876
+taglist menu is enabled. When the taglist window is closed, the taglist plugin
877
+will stop processing the tags for newly opened files.
878
+
879
+You can set the 'Tlist_Process_File_Always' variable to 1 to generate the list
880
+of tags for new files even when the taglist window is closed and the taglist
881
+menu is disabled.
882
+>
883
+	let Tlist_Process_File_Always = 1
884
+<
885
+To use the ":TlistShowTag" and the ":TlistShowPrototype" commands without the
886
+taglist window and the taglist menu, you should set this variable to 1.
887
+
888
+						*'Tlist_Show_Menu'*
889
+Tlist_Show_Menu~
890
+When using GUI Vim, you can display the tags defined in the current file in a
891
+menu named "Tags". By default, this feature is turned off. To turn on this
892
+feature, set the 'Tlist_Show_Menu' variable to 1:
893
+>
894
+	let Tlist_Show_Menu = 1
895
+<
896
+						*'Tlist_Show_One_File'*
897
+Tlist_Show_One_File~
898
+By default, the taglist plugin will display the tags defined in all the loaded
899
+buffers in the taglist window. If you prefer to display the tags defined only
900
+in the current buffer, then you can set the 'Tlist_Show_One_File' to 1. When
901
+this variable is set to 1, as you switch between buffers, the taglist window
902
+will be refreshed to display the tags for the current buffer and the tags for
903
+the previous buffer will be removed.
904
+>
905
+	let Tlist_Show_One_File = 1
906
+<
907
+						*'Tlist_Sort_Type'*
908
+Tlist_Sort_Type~
909
+The 'Tlist_Sort_Type' variable specifies the sort order for the tags in the
910
+taglist window. The tags can be sorted either alphabetically by their name or
911
+by the order of their appearance in the file (chronological order). By
912
+default, the tag names will be listed by the order in which they are defined
913
+in the file. You can change the sort type (from name to order or from order to
914
+name) by pressing the "s" key in the taglist window. You can also change the
915
+default sort order by setting 'Tlist_Sort_Type' to "name" or "order":
916
+>
917
+	let Tlist_Sort_Type = "name"
918
+<
919
+						*'Tlist_Use_Horiz_Window'*
920
+Tlist_Use_Horiz_Window~
921
+Be default, the tag names are displayed in a vertically split window. If you
922
+prefer a horizontally split window, then set the 'Tlist_Use_Horiz_Window'
923
+variable to 1. If you are running MS-Windows version of Vim in a MS-DOS
924
+command window, then you should use a horizontally split window instead of a
925
+vertically split window. Also, if you are using an older version of xterm in a
926
+Unix system that doesn't support changing the xterm window width, you should
927
+use a horizontally split window.
928
+>
929
+	let Tlist_Use_Horiz_Window = 1
930
+<
931
+						*'Tlist_Use_Right_Window'*
932
+Tlist_Use_Right_Window~
933
+By default, the vertically split taglist window will appear on the left hand
934
+side. If you prefer to open the window on the right hand side, you can set the
935
+'Tlist_Use_Right_Window' variable to 1:
936
+>
937
+	let Tlist_Use_Right_Window = 1
938
+<
939
+						*'Tlist_Use_SingleClick'*
940
+Tlist_Use_SingleClick~
941
+By default, when you double click on the tag name using the left mouse 
942
+button, the cursor will be positioned at the definition of the tag. You 
943
+can set the 'Tlist_Use_SingleClick' variable to 1 to jump to a tag when
944
+you single click on the tag name using the mouse. By default this variable
945
+is set to zero.
946
+>
947
+	let Tlist_Use_SingleClick = 1
948
+<
949
+Due to a bug in Vim, if you set 'Tlist_Use_SingleClick' to 1 and try to resize
950
+the taglist window using the mouse, then Vim will crash. This problem is fixed
951
+in Vim 6.3 and above. In the meantime, instead of resizing the taglist window
952
+using the mouse, you can use normal Vim window resizing commands to resize the
953
+taglist window.
954
+
955
+						*'Tlist_WinHeight'*
956
+Tlist_WinHeight~
957
+The default height of the horizontally split taglist window is 10. This can be
958
+changed by modifying the 'Tlist_WinHeight' variable:
959
+>
960
+	let Tlist_WinHeight = 20
961
+<
962
+The |'winfixheight'| option is set for the taglist window, to maintain the
963
+height of the taglist window, when new Vim windows are opened and existing
964
+windows are closed.
965
+
966
+						*'Tlist_WinWidth'*
967
+Tlist_WinWidth~
968
+The default width of the vertically split taglist window is 30. This can be
969
+changed by modifying the 'Tlist_WinWidth' variable:
970
+>
971
+	let Tlist_WinWidth = 20
972
+<
973
+Note that the value of the |'winwidth'| option setting determines the minimum
974
+width of the current window. If you set the 'Tlist_WinWidth' variable to a
975
+value less than that of the |'winwidth'| option setting, then Vim will use the
976
+value of the |'winwidth'| option.
977
+
978
+When new Vim windows are opened and existing windows are closed, the taglist
979
+plugin will try to maintain the width of the taglist window to the size
980
+specified by the 'Tlist_WinWidth' variable.
981
+
982
+==============================================================================
983
+						*taglist-commands*
984
+7. Commands~
985
+
986
+The taglist plugin provides the following ex-mode commands:
987
+
988
+|:TlistAddFiles|	Add multiple files to the taglist.
989
+|:TlistAddFilesRecursive|
990
+			Add files recursively to the taglist.
991
+|:TlistClose|		Close the taglist window.
992
+|:TlistDebug|		Start logging of taglist debug messages.
993
+|:TlistLock|		Stop adding new files to the taglist.
994
+|:TlistMessages|	Display the logged taglist plugin debug messages.
995
+|:TlistOpen|		Open and jump to the taglist window.
996
+|:TlistSessionSave|	Save the information about files and tags in the
997
+			taglist to a session file.
998
+|:TlistSessionLoad|	Load the information about files and tags stored
999
+			in a session file to taglist.
1000
+|:TlistShowPrototype|	Display the prototype of the tag at or before the
1001
+		    	specified line number.
1002
+|:TlistShowTag|		Display the name of the tag defined at or before the
1003
+			specified line number.
1004
+|:TlistHighlightTag|	Highlight the current tag in the taglist window.
1005
+|:TlistToggle|		Open or close (toggle) the taglist window.
1006
+|:TlistUndebug|		Stop logging of taglist debug messages.
1007
+|:TlistUnlock|		Start adding new files to the taglist.
1008
+|:TlistUpdate|		Update the tags for the current buffer.
1009
+
1010
+						*:TlistAddFiles*
1011
+:TlistAddFiles {file(s)} [file(s) ...]
1012
+		Add one or more specified files to the taglist. You can
1013
+		specify multiple filenames using wildcards. To specify a
1014
+		file name with space character, you should escape the space
1015
+		character with a backslash.
1016
+		Examples:
1017
+>
1018
+		    :TlistAddFiles *.c *.cpp
1019
+		    :TlistAddFiles file1.html file2.html
1020
+<
1021
+		If you specify a large number of files, then it will take some
1022
+		time for the taglist plugin to process all of them. The
1023
+		specified files will not be edited in a Vim window and will
1024
+		not be added to the Vim buffer list.
1025
+
1026
+						*:TlistAddFilesRecursive*
1027
+:TlistAddFilesRecursive {directory} [ {pattern} ]
1028
+		Add files matching {pattern} recursively from the specified
1029
+		{directory} to the taglist. If {pattern} is not specified,
1030
+		then '*' is assumed. To specify the current directory, use "."
1031
+		for {directory}. To specify a directory name with space
1032
+		character, you should escape the space character with a
1033
+		backslash.
1034
+		Examples:
1035
+>
1036
+		    :TlistAddFilesRecursive myproject *.java
1037
+		    :TlistAddFilesRecursive smallproject
1038
+<
1039
+		If large number of files are present in the specified
1040
+		directory tree, then it will take some time for the taglist
1041
+		plugin to process all of them.
1042
+
1043
+						*:TlistClose*
1044
+:TlistClose	Close the taglist window. This command can be used from any
1045
+		one of the Vim windows.
1046
+
1047
+						*:TlistDebug*
1048
+:TlistDebug [filename]
1049
+		Start logging of debug messages from the taglist plugin.
1050
+		If {filename} is specified, then the debug messages are stored
1051
+		in the specified file. Otherwise, the debug messages are
1052
+		stored in a script local variable. If the file {filename} is
1053
+		already present, then it is overwritten.
1054
+
1055
+						*:TlistLock*
1056
+:TlistLock
1057
+		Lock the taglist and don't process new files. After this
1058
+		command is executed, newly edited files will not be added to
1059
+		the taglist.
1060
+
1061
+						*:TlistMessages*
1062
+:TlistMessages
1063
+		Display the logged debug messages from the taglist plugin
1064
+		in a window.  This command works only when logging to a
1065
+		script-local variable.
1066
+
1067
+						*:TlistOpen*
1068
+:TlistOpen	Open and jump to the taglist window. Creates the taglist
1069
+		window, if the window is not opened currently. After executing
1070
+		this command, the cursor is moved to the taglist window.  When
1071
+		the taglist window is opened for the first time, all the files
1072
+		in the buffer list are processed and the tags defined in them
1073
+		are displayed in the taglist window.
1074
+
1075
+						*:TlistSessionSave*
1076
+:TlistSessionSave {filename}
1077
+		Saves the information about files and tags in the taglist to
1078
+		the specified file. This command can be used to save and
1079
+		restore the taglist contents across Vim sessions.
1080
+
1081
+						*:TlistSessionLoad*
1082
+:TlistSessionLoad {filename}
1083
+		Load the information about files and tags stored in the
1084
+		specified session file to the taglist.
1085
+
1086
+						*:TlistShowPrototype*
1087
+:TlistShowPrototype [filename] [linenumber]
1088
+		Display the prototype of the tag at or before the specified
1089
+		line number. If the file name and the line number are not
1090
+		specified, then the current file name and line number are
1091
+		used. A tag spans multiple lines starting from the line where
1092
+		it is defined to the line before the next tag. This command
1093
+		displays the prototype for the tag for any line number in this
1094
+		range. 
1095
+
1096
+						*:TlistShowTag*
1097
+:TlistShowTag [filename] [linenumber]
1098
+		Display the name of the tag defined at or before the specified
1099
+		line number. If the file name and the line number are not
1100
+		specified, then the current file name and line number are
1101
+		used. A tag spans multiple lines starting from the line where
1102
+		it is defined to the line before the next tag. This command
1103
+		displays the tag name for any line number in this range. 
1104
+
1105
+						*:TlistHighlightTag*
1106
+:TlistHighlightTag
1107
+		Highlight the current tag in the taglist window. By default,
1108
+		the taglist plugin periodically updates the taglist window to
1109
+		highlight the current tag. This command can be used to force
1110
+		the taglist plugin to highlight the current tag.
1111
+
1112
+						*:TlistToggle*
1113
+:TlistToggle	Open or close (toggle) the taglist window. Opens the taglist
1114
+		window, if the window is not opened currently. Closes the
1115
+		taglist window, if the taglist window is already opened. When
1116
+		the taglist window is opened for the first time, all the files
1117
+		in the buffer list are processed and the tags are displayed in
1118
+		the taglist window. After executing this command, the cursor
1119
+		is not moved from the current window to the taglist window.
1120
+
1121
+						*:TlistUndebug*
1122
+:TlistUndebug
1123
+		Stop logging of debug messages from the taglist plugin.
1124
+
1125
+						*:TlistUnlock*
1126
+:TlistUnlock
1127
+		Unlock the taglist and start processing newly edited files.
1128
+
1129
+						*:TlistUpdate*
1130
+:TlistUpdate	Update the tags information for the current buffer. This
1131
+		command can be used to re-process the current file/buffer and
1132
+		get the tags information. As the taglist plugin uses the file
1133
+		saved in the disk (instead of the file displayed in a Vim
1134
+		buffer), you should save a modified buffer before you update
1135
+		the taglist. Otherwise the listed tags will not include the
1136
+		new tags created in the buffer. You can use this command even
1137
+		when the taglist window is not opened.
1138
+
1139
+==============================================================================
1140
+						*taglist-functions*
1141
+8. Global functions~
1142
+
1143
+The taglist plugin provides several global functions that can be used from
1144
+other Vim plugins to interact with the taglist plugin. These functions are
1145
+described below.
1146
+
1147
+|Tlist_Update_File_Tags()|		Update the tags for the specified file
1148
+|Tlist_Get_Tag_Prototype_By_Line()|	Return the prototype of the tag at or
1149
+				    	before the specified line number in the
1150
+				    	specified file.
1151
+|Tlist_Get_Tagname_By_Line()|		Return the name of the tag at or
1152
+					before the specified line number in
1153
+					the specified file.
1154
+|Tlist_Set_App()|			Set the name of the application
1155
+					controlling the taglist window.
1156
+
1157
+					    *Tlist_Update_File_Tags()*
1158
+Tlist_Update_File_Tags({filename}, {filetype})
1159
+		Update the tags for the file {filename}. The second argument
1160
+		specifies the Vim filetype for the file. If the taglist plugin
1161
+		has not processed the file previously, then the exuberant
1162
+		ctags tool is invoked to generate the tags for the file.
1163
+
1164
+					    *Tlist_Get_Tag_Prototype_By_Line()*
1165
+Tlist_Get_Tag_Prototype_By_Line([{filename}, {linenumber}])
1166
+		Return the prototype of the tag at or before the specified
1167
+		line number in the specified file. If the filename and line
1168
+		number are not specified, then the current buffer name and the
1169
+		current line number are used.
1170
+
1171
+					    *Tlist_Get_Tagname_By_Line()*
1172
+Tlist_Get_Tagname_By_Line([{filename}, {linenumber}])
1173
+		Return the name of the tag at or before the specified line
1174
+		number in the specified file. If the filename and line number
1175
+		are not specified, then the current buffer name and the
1176
+		current line number are used.
1177
+
1178
+					    *Tlist_Set_App()*
1179
+Tlist_Set_App({appname})
1180
+		Set the name of the plugin that controls the taglist plugin
1181
+		window and buffer. This can be used to integrate the taglist
1182
+		plugin with other Vim plugins.
1183
+		
1184
+		For example, the winmanager plugin and the Cream package use
1185
+		this function and specify the appname as "winmanager" and
1186
+		"cream" respectively.
1187
+		
1188
+		By default, the taglist plugin is a stand-alone plugin and
1189
+		controls the taglist window and buffer. If the taglist window
1190
+		is controlled by an external plugin, then the appname should
1191
+		be set appropriately.
1192
+
1193
+==============================================================================
1194
+						*taglist-extend*
1195
+9. Extending~
1196
+
1197
+The taglist plugin supports all the languages supported by the exuberant ctags
1198
+tool, which includes the following languages: Assembly, ASP, Awk, Beta, C,
1199
+C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, Lua,
1200
+Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, SML, Sql,
1201
+TCL, Verilog, Vim and Yacc.
1202
+
1203
+You can extend the taglist plugin to add support for new languages and also
1204
+modify the support for the above listed languages.
1205
+
1206
+You should NOT make modifications to the taglist plugin script file to add
1207
+support for new languages. You will lose these changes when you upgrade to the
1208
+next version of the taglist plugin. Instead you should follow the below
1209
+described instructions to extend the taglist plugin.
1210
+
1211
+You can extend the taglist plugin by setting variables in the .vimrc or _vimrc
1212
+file. The name of these variables depends on the language name and is
1213
+described below.
1214
+
1215
+Modifying support for an existing language~
1216
+To modify the support for an already supported language, you have to set the
1217
+tlist_xxx_settings variable in the ~/.vimrc or $HOME/_vimrc file. Replace xxx
1218
+with the Vim filetype name for the language file.  For example, to modify the
1219
+support for the perl language files, you have to set the tlist_perl_settings
1220
+variable. To modify the support for java files, you have to set the
1221
+tlist_java_settings variable.
1222
+
1223
+To determine the filetype name used by Vim for a file, use the following
1224
+command in the buffer containing the file:
1225
+
1226
+	:set filetype
1227
+
1228
+The above command will display the Vim filetype for the current buffer.
1229
+
1230
+The format of the value set in the tlist_xxx_settings variable is
1231
+
1232
+    <language_name>;flag1:name1;flag2:name2;flag3:name3
1233
+
1234
+The different fields in the value are separated by the ';' character.
1235
+
1236
+The first field 'language_name' is the name used by exuberant ctags to refer
1237
+to this language file. This name can be different from the file type name used
1238
+by Vim. For example, for C++, the language name used by ctags is 'c++' but the
1239
+filetype name used by Vim is 'cpp'. To get the list of language names
1240
+supported by exuberant ctags, use the following command:
1241
+
1242
+	$ ctags --list-maps=all
1243
+
1244
+The remaining fields follow the format "flag:name". The sub-field 'flag' is
1245
+the language specific flag used by exuberant ctags to generate the
1246
+corresponding tags. For example, for the C language, to list only the
1247
+functions, the 'f' flag is used. To get the list of flags supported by
1248
+exuberant ctags for the various languages use the following command:
1249
+
1250
+	$ ctags --list-kinds=all
1251
+
1252
+The sub-field 'name' specifies the title text to use for displaying the tags
1253
+of a particular type. For example, 'name' can be set to 'functions'. This
1254
+field can be set to any text string name.
1255
+
1256
+For example, to list only the classes and functions defined in a C++ language
1257
+file, add the following line to your .vimrc file:
1258
+
1259
+	let tlist_cpp_settings = 'c++;c:class;f:function'
1260
+
1261
+In the above setting, 'cpp' is the Vim filetype name and 'c++' is the name
1262
+used by the exuberant ctags tool. 'c' and 'f' are the flags passed to
1263
+exuberant ctags to list C++ classes and functions and 'class' is the title
1264
+used for the class tags and 'function' is the title used for the function tags
1265
+in the taglist window.
1266
+
1267
+For example, to display only functions defined in a C file and to use "My
1268
+Functions" as the title for the function tags, use
1269
+
1270
+	let tlist_c_settings = 'c;f:My Functions'
1271
+
1272
+When you set the tlist_xxx_settings variable, you will override the default
1273
+setting used by the taglist plugin for the 'xxx' language. You cannot add to
1274
+the default options used by the taglist plugin for a particular file type. To
1275
+add to the options used by the taglist plugin for a language, copy the option
1276
+values from the taglist plugin file to your .vimrc file and modify it.
1277
+
1278
+Adding support for a new language~
1279
+If you want to add support for a new language to the taglist plugin, you need
1280
+to first extend the exuberant ctags tool. For more information about extending
1281
+exuberant ctags, visit the following page:
1282
+
1283
+    http://ctags.sourceforge.net/EXTENDING.html
1284
+
1285
+To add support for a new language, set the tlist_xxx_settings variable in the
1286
+~/.vimrc file appropriately as described above. Replace 'xxx' in the variable
1287
+name with the Vim filetype name for the new language.
1288
+
1289
+For example, to extend the taglist plugin to support the latex language, you
1290
+can use the following line (assuming, you have already extended exuberant
1291
+ctags to support the latex language):
1292
+
1293
+	let tlist_tex_settings='latex;b:bibitem;c:command;l:label'
1294
+
1295
+With the above line, when you edit files of filetype "tex" in Vim, the taglist
1296
+plugin will invoke the exuberant ctags tool passing the "latex" filetype and
1297
+the flags b, c and l to generate the tags. The text heading 'bibitem',
1298
+'command' and 'label' will be used in the taglist window for the tags which
1299
+are generated for the flags b, c and l respectively.
1300
+
1301
+==============================================================================
1302
+						*taglist-faq*
1303
+10. Frequently Asked Questions~
1304
+
1305
+Q. The taglist plugin doesn't work. The taglist window is empty and the tags
1306
+   defined in a file are not displayed. 
1307
+A. Are you using Vim version 6.0 and above? The taglist plugin relies on the
1308
+   features supported by Vim version 6.0 and above. You can use the following
1309
+   command to get the Vim version:
1310
+>
1311
+	$ vim --version
1312
+<
1313
+   Are you using exuberant ctags version 5.0 and above? The taglist plugin
1314
+   relies on the features supported by exuberant ctags and will not work with
1315
+   GNU ctags or the Unix ctags utility. You can use the following command to
1316
+   determine whether the ctags installed in your system is exuberant ctags:
1317
+>
1318
+	$ ctags --version
1319
+<
1320
+   Is exuberant ctags present in one of the directories in your PATH? If not,
1321
+   you need to set the Tlist_Ctags_Cmd variable to point to the location of
1322
+   exuberant ctags. Use the following Vim command to verify that this is setup
1323
+   correctly:
1324
+>
1325
+	:echo system(Tlist_Ctags_Cmd . ' --version')
1326
+<
1327
+   The above command should display the version information for exuberant
1328
+   ctags.
1329
+
1330
+   Did you turn on the Vim filetype detection? The taglist plugin relies on
1331
+   the filetype detected by Vim and passes the filetype to the exuberant ctags
1332
+   utility to parse the tags. Check the output of the following Vim command:
1333
+>
1334
+	:filetype
1335
+<
1336
+   The output of the above command should contain "filetype detection:ON".
1337
+   To turn on the filetype detection, add the following line to the .vimrc or
1338
+   _vimrc file:
1339
+>
1340
+	filetype on
1341
+<
1342
+   Is your version of Vim compiled with the support for the system() function?
1343
+   The following Vim command should display 1:
1344
+>
1345
+	:echo exists('*system')
1346
+<
1347
+   In some Linux distributions (particularly Suse Linux), the default Vim
1348
+   installation is built without the support for the system() function. The
1349
+   taglist plugin uses the system() function to invoke the exuberant ctags
1350
+   utility. You need to rebuild Vim after enabling the support for the
1351
+   system() function. If you use the default build options, the system()
1352
+   function will be supported. 
1353
+
1354
+   Do you have the |'shellslash'| option set? You can try disabling the
1355
+   |'shellslash'| option. When the taglist plugin invokes the exuberant ctags
1356
+   utility with the path to the file, if the incorrect slashes are used, then
1357
+   you will see errors.
1358
+   
1359
+   Check the shell related Vim options values using the following command:
1360
+>
1361
+	:set shell? shellcmdflag? shellpipe?
1362
+	:set shellquote? shellredir? shellxquote?
1363
+<
1364
+   If these options are set in your .vimrc or _vimrc file, try removing those
1365
+   lines.
1366
+
1367
+   Are you using a Unix shell in a MS-Windows environment? For example,
1368
+   the Unix shell from the MKS-toolkit. Do you have the SHELL environment
1369
+   set to point to this shell? You can try resetting the SHELL environment
1370
+   variable.
1371
+
1372
+   If you are using a Unix shell on MS-Windows, you should try to use
1373
+   exuberant ctags that is compiled for Unix-like environments so that
1374
+   exuberant ctags will understand path names with forward slash characters.
1375
+
1376
+   Is your filetype supported by the exuberant ctags utility? The file types
1377
+   supported by the exuberant ctags utility are listed in the ctags help. If a
1378
+   file type is not supported, you have to extend exuberant ctags. You can use
1379
+   the following command to list the filetypes supported by exuberant ctags:
1380
+>
1381
+	ctags --list-languages
1382
+<
1383
+   Run the following command from the shell prompt and check whether the tags
1384
+   defined in your file are listed in the output from exuberant ctags:
1385
+>
1386
+	ctags -f - --format=2 --excmd=pattern --fields=nks <filename>
1387
+<
1388
+   If you see your tags in the output from the above command, then the
1389
+   exuberant ctags utility is properly parsing your file.
1390
+
1391
+   Do you have the .ctags or _ctags or the ctags.cnf file in your home
1392
+   directory for specifying default options or for extending exuberant ctags?
1393
+   If you do have this file, check the options in this file and make sure
1394
+   these options are not interfering with the operation of the taglist plugin.
1395
+
1396
+   If you are using MS-Windows, check the value of the TEMP and TMP
1397
+   environment variables. If these environment variables are set to a path
1398
+   with space characters in the name, then try using the DOS 8.3 short name
1399
+   for the path or set them to a path without the space characters in the
1400
+   name. For example, if the temporary directory name is "C:\Documents and
1401
+   Settings\xyz\Local Settings\Temp", then try setting the TEMP variable to
1402
+   the following:
1403
+>
1404
+	set TEMP=C:\DOCUMEN~1\xyz\LOCALS~1\Temp
1405
+<
1406
+   If exuberant ctags is installed in a directory with space characters in the
1407
+   name, then try adding the directory to the PATH environment variable or try
1408
+   setting the 'Tlist_Ctags_Cmd' variable to the shortest path name to ctags
1409
+   or try copying the exuberant ctags to a path without space characters in
1410
+   the name. For example, if exuberant ctags is installed in the directory
1411
+   "C:\Program Files\Ctags", then try setting the 'Tlist_Ctags_Cmd' variable
1412
+   as below:
1413
+>
1414
+	let Tlist_Ctags_Cmd='C:\Progra~1\Ctags\ctags.exe'
1415
+<
1416
+   If you are using a cygwin compiled version of exuberant ctags on MS-Windows,
1417
+   make sure that either you have the cygwin compiled sort utility installed
1418
+   and available in your PATH or compile exuberant ctags with internal sort
1419
+   support. Otherwise, when exuberant ctags sorts the tags output by invoking
1420
+   the sort utility, it may end up invoking the MS-Windows version of
1421
+   sort.exe, thereby resulting in failure.
1422
+
1423
+Q. When I try to open the taglist window, I am seeing the following error
1424
+   message. How do I fix this problem?
1425
+
1426
+   Taglist: Failed to generate tags for /my/path/to/file
1427
+   ctags: illegal option -- -^@usage: ctags [-BFadtuwvx] [-f tagsfile] file ...
1428
+
1429
+A. The taglist plugin will work only with the exuberant ctags tool. You
1430
+   cannot use the GNU ctags or the Unix ctags program with the taglist plugin.
1431
+   You will see an error message similar to the one shown above, if you try
1432
+   use a non-exuberant ctags program with Vim. To fix this problem, either add
1433
+   the exuberant ctags tool location to the PATH environment variable or set
1434
+   the 'Tlist_Ctags_Cmd' variable.
1435
+
1436
+Q. A file has more than one tag with the same name. When I select a tag name
1437
+   from the taglist window, the cursor is positioned at the incorrect tag
1438
+   location. 
1439
+A. The taglist plugin uses the search pattern generated by the exuberant ctags
1440
+   utility to position the cursor at the location of a tag definition. If a
1441
+   file has more than one tag with the same name and same prototype, then the
1442
+   search pattern will be the same. In this case, when searching for the tag
1443
+   pattern, the cursor may be positioned at the incorrect location. 
1444
+
1445
+Q. I have made some modifications to my file and introduced new
1446
+   functions/classes/variables. I have not yet saved my file. The taglist
1447
+   plugin is not displaying the new tags when I update the taglist window.
1448
+A. The exuberant ctags utility will process only files that are present in the
1449
+   disk. To list the tags defined in a file, you have to save the file and
1450
+   then update the taglist window. 
1451
+
1452
+Q. I have created a ctags file using the exuberant ctags utility for my source
1453
+   tree. How do I configure the taglist plugin to use this tags file? 
1454
+A. The taglist plugin doesn't use a tags file stored in disk. For every opened
1455
+   file, the taglist plugin invokes the exuberant ctags utility to get the
1456
+   list of tags dynamically. The Vim system() function is used to invoke
1457
+   exuberant ctags and get the ctags output. This function internally uses a
1458
+   temporary file to store the output. This file is deleted after the output
1459
+   from the command is read. So you will never see the file that contains the
1460
+   output of exuberant ctags.
1461
+
1462
+Q. When I set the |'updatetime'| option to a low value (less than 1000) and if
1463
+   I keep pressing a key with the taglist window open, the current buffer
1464
+   contents are changed. Why is this?
1465
+A. The taglist plugin uses the |CursorHold| autocmd to highlight the current
1466
+   tag. The CursorHold autocmd triggers for every |'updatetime'| milliseconds.
1467
+   If the |'updatetime'| option is set to a low value, then the CursorHold
1468
+   autocmd will be triggered frequently. As the taglist plugin changes
1469
+   the focus to the taglist window to highlight the current tag, this could
1470
+   interfere with the key movement resulting in changing the contents of
1471
+   the current buffer. The workaround for this problem is to not set the
1472
+   |'updatetime'| option to a low value.
1473
+
1474
+==============================================================================
1475
+						*taglist-license*
1476
+11. License~
1477
+Permission is hereby granted to use and distribute the taglist plugin, with or
1478
+without modifications, provided that this copyright notice is copied with it.
1479
+Like anything else that's free, taglist.vim is provided *as is* and comes with
1480
+no warranty of any kind, either expressed or implied. In no event will the
1481
+copyright holder be liable for any damamges resulting from the use of this
1482
+software.
1483
+
1484
+==============================================================================
1485
+						*taglist-todo*
1486
+12. Todo~
1487
+
1488
+1. Group tags according to the scope and display them. For example,
1489
+   group all the tags belonging to a C++/Java class 
1490
+2. Support for displaying tags in a modified (not-yet-saved) file. 
1491
+3. Automatically open the taglist window only for selected filetypes.
1492
+   For other filetypes, close the taglist window. 
1493
+4. When using the shell from the MKS toolkit, the taglist plugin 
1494
+   doesn't work.
1495
+5. The taglist plugin doesn't work with files edited remotely using the
1496
+   netrw plugin. The exuberant ctags utility cannot process files over
1497
+   scp/rcp/ftp, etc.
1498
+
1499
+==============================================================================
1500
+
1501
+vim:tw=78:ts=8:noet:ft=help:
... ...
@@ -0,0 +1,62 @@
1
+'Tlist_Auto_Highlight_Tag'	taglist.txt	/*'Tlist_Auto_Highlight_Tag'*
2
+'Tlist_Auto_Open'	taglist.txt	/*'Tlist_Auto_Open'*
3
+'Tlist_Auto_Update'	taglist.txt	/*'Tlist_Auto_Update'*
4
+'Tlist_Close_On_Select'	taglist.txt	/*'Tlist_Close_On_Select'*
5
+'Tlist_Compact_Format'	taglist.txt	/*'Tlist_Compact_Format'*
6
+'Tlist_Ctags_Cmd'	taglist.txt	/*'Tlist_Ctags_Cmd'*
7
+'Tlist_Display_Prototype'	taglist.txt	/*'Tlist_Display_Prototype'*
8
+'Tlist_Display_Tag_Scope'	taglist.txt	/*'Tlist_Display_Tag_Scope'*
9
+'Tlist_Enable_Fold_Column'	taglist.txt	/*'Tlist_Enable_Fold_Column'*
10
+'Tlist_Exit_OnlyWindow'	taglist.txt	/*'Tlist_Exit_OnlyWindow'*
11
+'Tlist_File_Fold_Auto_Close'	taglist.txt	/*'Tlist_File_Fold_Auto_Close'*
12
+'Tlist_GainFocus_On_ToggleOpen'	taglist.txt	/*'Tlist_GainFocus_On_ToggleOpen'*
13
+'Tlist_Highlight_Tag_On_BufEnter'	taglist.txt	/*'Tlist_Highlight_Tag_On_BufEnter'*
14
+'Tlist_Inc_Winwidth'	taglist.txt	/*'Tlist_Inc_Winwidth'*
15
+'Tlist_Max_Submenu_Items'	taglist.txt	/*'Tlist_Max_Submenu_Items'*
16
+'Tlist_Max_Tag_Length'	taglist.txt	/*'Tlist_Max_Tag_Length'*
17
+'Tlist_Process_File_Always'	taglist.txt	/*'Tlist_Process_File_Always'*
18
+'Tlist_Show_Menu'	taglist.txt	/*'Tlist_Show_Menu'*
19
+'Tlist_Show_One_File'	taglist.txt	/*'Tlist_Show_One_File'*
20
+'Tlist_Sort_Type'	taglist.txt	/*'Tlist_Sort_Type'*
21
+'Tlist_Use_Horiz_Window'	taglist.txt	/*'Tlist_Use_Horiz_Window'*
22
+'Tlist_Use_Right_Window'	taglist.txt	/*'Tlist_Use_Right_Window'*
23
+'Tlist_Use_SingleClick'	taglist.txt	/*'Tlist_Use_SingleClick'*
24
+'Tlist_WinHeight'	taglist.txt	/*'Tlist_WinHeight'*
25
+'Tlist_WinWidth'	taglist.txt	/*'Tlist_WinWidth'*
26
+:TlistAddFiles	taglist.txt	/*:TlistAddFiles*
27
+:TlistAddFilesRecursive	taglist.txt	/*:TlistAddFilesRecursive*
28
+:TlistClose	taglist.txt	/*:TlistClose*
29
+:TlistDebug	taglist.txt	/*:TlistDebug*
30
+:TlistHighlightTag	taglist.txt	/*:TlistHighlightTag*
31
+:TlistLock	taglist.txt	/*:TlistLock*
32
+:TlistMessages	taglist.txt	/*:TlistMessages*
33
+:TlistOpen	taglist.txt	/*:TlistOpen*
34
+:TlistSessionLoad	taglist.txt	/*:TlistSessionLoad*
35
+:TlistSessionSave	taglist.txt	/*:TlistSessionSave*
36
+:TlistShowPrototype	taglist.txt	/*:TlistShowPrototype*
37
+:TlistShowTag	taglist.txt	/*:TlistShowTag*
38
+:TlistToggle	taglist.txt	/*:TlistToggle*
39
+:TlistUndebug	taglist.txt	/*:TlistUndebug*
40
+:TlistUnlock	taglist.txt	/*:TlistUnlock*
41
+:TlistUpdate	taglist.txt	/*:TlistUpdate*
42
+Tlist_Get_Tag_Prototype_By_Line()	taglist.txt	/*Tlist_Get_Tag_Prototype_By_Line()*
43
+Tlist_Get_Tagname_By_Line()	taglist.txt	/*Tlist_Get_Tagname_By_Line()*
44
+Tlist_Set_App()	taglist.txt	/*Tlist_Set_App()*
45
+Tlist_Update_File_Tags()	taglist.txt	/*Tlist_Update_File_Tags()*
46
+taglist-commands	taglist.txt	/*taglist-commands*
47
+taglist-debug	taglist.txt	/*taglist-debug*
48
+taglist-extend	taglist.txt	/*taglist-extend*
49
+taglist-faq	taglist.txt	/*taglist-faq*
50
+taglist-functions	taglist.txt	/*taglist-functions*
51
+taglist-install	taglist.txt	/*taglist-install*
52
+taglist-internet	taglist.txt	/*taglist-internet*
53
+taglist-intro	taglist.txt	/*taglist-intro*
54
+taglist-keys	taglist.txt	/*taglist-keys*
55
+taglist-license	taglist.txt	/*taglist-license*
56
+taglist-menu	taglist.txt	/*taglist-menu*
57
+taglist-options	taglist.txt	/*taglist-options*
58
+taglist-requirements	taglist.txt	/*taglist-requirements*
59
+taglist-session	taglist.txt	/*taglist-session*
60
+taglist-todo	taglist.txt	/*taglist-todo*
61
+taglist-using	taglist.txt	/*taglist-using*
62
+taglist.txt	taglist.txt	/*taglist.txt*
... ...
@@ -0,0 +1,4546 @@
1
+" File: taglist.vim
2
+" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
3
+" Version: 4.5
4
+" Last Modified: September 21, 2007
5
+" Copyright: Copyright (C) 2002-2007 Yegappan Lakshmanan
6
+"            Permission is hereby granted to use and distribute this code,
7
+"            with or without modifications, provided that this copyright
8
+"            notice is copied with it. Like anything else that's free,
9
+"            taglist.vim is provided *as is* and comes with no warranty of any
10
+"            kind, either expressed or implied. In no event will the copyright
11
+"            holder be liable for any damamges resulting from the use of this
12
+"            software.
13
+"
14
+" The "Tag List" plugin is a source code browser plugin for Vim and provides
15
+" an overview of the structure of the programming language files and allows
16
+" you to efficiently browse through source code files for different
17
+" programming languages.  You can visit the taglist plugin home page for more
18
+" information:
19
+"
20
+"       http://vim-taglist.sourceforge.net
21
+"
22
+" You can subscribe to the taglist mailing list to post your questions
23
+" or suggestions for improvement or to report bugs. Visit the following
24
+" page for subscribing to the mailing list:
25
+"
26
+"       http://groups.yahoo.com/group/taglist/
27
+"
28
+" For more information about using this plugin, after installing the
29
+" taglist plugin, use the ":help taglist" command.
30
+"
31
+" Installation
32
+" ------------
33
+" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim
34
+"    or the $HOME/vimfiles or the $VIM/vimfiles directory. This should
35
+"    unzip the following two files (the directory structure should be
36
+"    preserved):
37
+"
38
+"       plugin/taglist.vim - main taglist plugin file
39
+"       doc/taglist.txt    - documentation (help) file
40
+"
41
+"    Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath'
42
+"    Vim help pages for more details about installing Vim plugins.
43
+" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or
44
+"    $VIM/vimfiles/doc directory, start Vim and run the ":helptags ."
45
+"    command to process the taglist help file.
46
+" 3. If the exuberant ctags utility is not present in your PATH, then set the
47
+"    Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags
48
+"    utility (not to the directory) in the .vimrc file.
49
+" 4. If you are running a terminal/console version of Vim and the
50
+"    terminal doesn't support changing the window width then set the
51
+"    'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file.
52
+" 5. Restart Vim.
53
+" 6. You can now use the ":TlistToggle" command to open/close the taglist
54
+"    window. You can use the ":help taglist" command to get more
55
+"    information about using the taglist plugin.
56
+"
57
+" ****************** Do not modify after this line ************************
58
+
59
+" Line continuation used here
60
+let s:cpo_save = &cpo
61
+set cpo&vim
62
+
63
+if !exists('loaded_taglist')
64
+    " First time loading the taglist plugin
65
+    "
66
+    " To speed up the loading of Vim, the taglist plugin uses autoload
67
+    " mechanism to load the taglist functions.
68
+    " Only define the configuration variables, user commands and some
69
+    " auto-commands and finish sourcing the file
70
+
71
+    " The taglist plugin requires the built-in Vim system() function. If this
72
+    " function is not available, then don't load the plugin.
73
+    if !exists('*system')
74
+        echomsg 'Taglist: Vim system() built-in function is not available. ' .
75
+                    \ 'Plugin is not loaded.'
76
+        let loaded_taglist = 'no'
77
+        let &cpo = s:cpo_save
78
+        finish
79
+    endif
80
+
81
+    " Location of the exuberant ctags tool
82
+    if !exists('Tlist_Ctags_Cmd')
83
+        if executable('exuberant-ctags')
84
+            " On Debian Linux, exuberant ctags is installed
85
+            " as exuberant-ctags
86
+            let Tlist_Ctags_Cmd = 'exuberant-ctags'
87
+        elseif executable('exctags')
88
+            " On Free-BSD, exuberant ctags is installed as exctags
89
+            let Tlist_Ctags_Cmd = 'exctags'
90
+        elseif executable('ctags')
91
+            let Tlist_Ctags_Cmd = 'ctags'
92
+        elseif executable('ctags.exe')
93
+            let Tlist_Ctags_Cmd = 'ctags.exe'
94
+        elseif executable('tags')
95
+            let Tlist_Ctags_Cmd = 'tags'
96
+        else
97
+            echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' .
98
+                        \ 'not found in PATH. Plugin is not loaded.'
99
+            " Skip loading the plugin
100
+            let loaded_taglist = 'no'
101
+            let &cpo = s:cpo_save
102
+            finish
103
+        endif
104
+    endif
105
+
106
+
107
+    " Automatically open the taglist window on Vim startup
108
+    if !exists('Tlist_Auto_Open')
109
+        let Tlist_Auto_Open = 0
110
+    endif
111
+
112
+    " When the taglist window is toggle opened, move the cursor to the
113
+    " taglist window
114
+    if !exists('Tlist_GainFocus_On_ToggleOpen')
115
+        let Tlist_GainFocus_On_ToggleOpen = 0
116
+    endif
117
+
118
+    " Process files even when the taglist window is not open
119
+    if !exists('Tlist_Process_File_Always')
120
+        let Tlist_Process_File_Always = 0
121
+    endif
122
+
123
+    if !exists('Tlist_Show_Menu')
124
+        let Tlist_Show_Menu = 0
125
+    endif
126
+
127
+    " Tag listing sort type - 'name' or 'order'
128
+    if !exists('Tlist_Sort_Type')
129
+        let Tlist_Sort_Type = 'order'
130
+    endif
131
+
132
+    " Tag listing window split (horizontal/vertical) control
133
+    if !exists('Tlist_Use_Horiz_Window')
134
+        let Tlist_Use_Horiz_Window = 0
135
+    endif
136
+
137
+    " Open the vertically split taglist window on the left or on the right
138
+    " side.  This setting is relevant only if Tlist_Use_Horiz_Window is set to
139
+    " zero (i.e.  only for vertically split windows)
140
+    if !exists('Tlist_Use_Right_Window')
141
+        let Tlist_Use_Right_Window = 0
142
+    endif
143
+
144
+    " Increase Vim window width to display vertically split taglist window.
145
+    " For MS-Windows version of Vim running in a MS-DOS window, this must be
146
+    " set to 0 otherwise the system may hang due to a Vim limitation.
147
+    if !exists('Tlist_Inc_Winwidth')
148
+        if (has('win16') || has('win95')) && !has('gui_running')
149
+            let Tlist_Inc_Winwidth = 0
150
+        else
151
+            let Tlist_Inc_Winwidth = 1
152
+        endif
153
+    endif
154
+
155
+    " Vertically split taglist window width setting
156
+    if !exists('Tlist_WinWidth')
157
+        let Tlist_WinWidth = 30
158
+    endif
159
+
160
+    " Horizontally split taglist window height setting
161
+    if !exists('Tlist_WinHeight')
162
+        let Tlist_WinHeight = 10
163
+    endif
164
+
165
+    " Display tag prototypes or tag names in the taglist window
166
+    if !exists('Tlist_Display_Prototype')
167
+        let Tlist_Display_Prototype = 0
168
+    endif
169
+
170
+    " Display tag scopes in the taglist window
171
+    if !exists('Tlist_Display_Tag_Scope')
172
+        let Tlist_Display_Tag_Scope = 1
173
+    endif
174
+
175
+    " Use single left mouse click to jump to a tag. By default this is disabled.
176
+    " Only double click using the mouse will be processed.
177
+    if !exists('Tlist_Use_SingleClick')
178
+        let Tlist_Use_SingleClick = 0
179
+    endif
180
+
181
+    " Control whether additional help is displayed as part of the taglist or
182
+    " not.  Also, controls whether empty lines are used to separate the tag
183
+    " tree.
184
+    if !exists('Tlist_Compact_Format')
185
+        let Tlist_Compact_Format = 0
186
+    endif
187
+
188
+    " Exit Vim if only the taglist window is currently open. By default, this is
189
+    " set to zero.
190
+    if !exists('Tlist_Exit_OnlyWindow')
191
+        let Tlist_Exit_OnlyWindow = 0
192
+    endif
193
+
194
+    " Automatically close the folds for the non-active files in the taglist
195
+    " window
196
+    if !exists('Tlist_File_Fold_Auto_Close')
197
+        let Tlist_File_Fold_Auto_Close = 0
198
+    endif
199
+
200
+    " Close the taglist window when a tag is selected
201
+    if !exists('Tlist_Close_On_Select')
202
+        let Tlist_Close_On_Select = 0
203
+    endif
204
+
205
+    " Automatically update the taglist window to display tags for newly
206
+    " edited files
207
+    if !exists('Tlist_Auto_Update')
208
+        let Tlist_Auto_Update = 1
209
+    endif
210
+
211
+    " Automatically highlight the current tag
212
+    if !exists('Tlist_Auto_Highlight_Tag')
213
+        let Tlist_Auto_Highlight_Tag = 1
214
+    endif
215
+    
216
+    " Automatically highlight the current tag on entering a buffer
217
+    if !exists('Tlist_Highlight_Tag_On_BufEnter')
218
+        let Tlist_Highlight_Tag_On_BufEnter = 1
219
+    endif
220
+
221
+    " Enable fold column to display the folding for the tag tree
222
+    if !exists('Tlist_Enable_Fold_Column')
223
+        let Tlist_Enable_Fold_Column = 1
224
+    endif
225
+
226
+    " Display the tags for only one file in the taglist window
227
+    if !exists('Tlist_Show_One_File')
228
+        let Tlist_Show_One_File = 0
229
+    endif
230
+
231
+    if !exists('Tlist_Max_Submenu_Items')
232
+        let Tlist_Max_Submenu_Items = 20
233
+    endif
234
+
235
+    if !exists('Tlist_Max_Tag_Length')
236
+        let Tlist_Max_Tag_Length = 10
237
+    endif
238
+
239
+    " Do not change the name of the taglist title variable. The winmanager
240
+    " plugin relies on this name to determine the title for the taglist
241
+    " plugin.
242
+    let TagList_title = "__Tag_List__"
243
+
244
+    " Taglist debug messages
245
+    let s:tlist_msg = ''
246
+
247
+    " Define the taglist autocommand to automatically open the taglist window
248
+    " on Vim startup
249
+    if g:Tlist_Auto_Open
250
+        autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open()
251
+    endif
252
+
253
+    " Refresh the taglist
254
+    if g:Tlist_Process_File_Always
255
+        autocmd BufEnter * call s:Tlist_Refresh()
256
+    endif
257
+
258
+    if g:Tlist_Show_Menu
259
+        autocmd GUIEnter * call s:Tlist_Menu_Init()
260
+    endif
261
+
262
+    " When the taglist buffer is created when loading a Vim session file,
263
+    " the taglist buffer needs to be initialized. The BufFilePost event
264
+    " is used to handle this case.
265
+    autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load()
266
+
267
+    " Define the user commands to manage the taglist window
268
+    command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle()
269
+    command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open()
270
+    " For backwards compatiblity define the Tlist command
271
+    command! -nargs=0 -bar Tlist TlistToggle
272
+    command! -nargs=+ -complete=file TlistAddFiles
273
+                \  call s:Tlist_Add_Files(<f-args>)
274
+    command! -nargs=+ -complete=dir TlistAddFilesRecursive
275
+                \ call s:Tlist_Add_Files_Recursive(<f-args>)
276
+    command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close()
277
+    command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File()
278
+    command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag(
279
+                        \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1)
280
+    " For backwards compatiblity define the TlistSync command
281
+    command! -nargs=0 -bar TlistSync TlistHighlightTag
282
+    command! -nargs=* -complete=buffer TlistShowPrototype
283
+                \ echo Tlist_Get_Tag_Prototype_By_Line(<f-args>)
284
+    command! -nargs=* -complete=buffer TlistShowTag
285
+                \ echo Tlist_Get_Tagname_By_Line(<f-args>)
286
+    command! -nargs=* -complete=file TlistSessionLoad
287
+                \ call s:Tlist_Session_Load(<q-args>)
288
+    command! -nargs=* -complete=file TlistSessionSave
289
+                \ call s:Tlist_Session_Save(<q-args>)
290
+    command! -bar TlistLock let Tlist_Auto_Update=0
291
+    command! -bar TlistUnlock let Tlist_Auto_Update=1
292
+
293
+    " Commands for enabling/disabling debug and to display debug messages
294
+    command! -nargs=? -complete=file -bar TlistDebug
295
+                \ call s:Tlist_Debug_Enable(<q-args>)
296
+    command! -nargs=0 -bar TlistUndebug  call s:Tlist_Debug_Disable()
297
+    command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show()
298
+
299
+    " Define autocommands to autoload the taglist plugin when needed.
300
+
301
+    " Trick to get the current script ID
302
+    map <SID>xx <SID>xx
303
+    let s:tlist_sid = substitute(maparg('<SID>xx'), '<SNR>\(\d\+_\)xx$',
304
+                                \ '\1', '')
305
+    unmap <SID>xx
306
+
307
+    exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' .
308
+                \ escape(expand('<sfile>'), ' ')
309
+    exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' .
310
+                \ escape(expand('<sfile>'), ' ')
311
+    exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' .
312
+                \ escape(expand('<sfile>'), ' ')
313
+    exe 'autocmd FuncUndefined Tlist_* source ' .
314
+                \ escape(expand('<sfile>'), ' ')
315
+    exe 'autocmd FuncUndefined TagList_* source ' .
316
+                \ escape(expand('<sfile>'), ' ')
317
+
318
+    let loaded_taglist = 'fast_load_done'
319
+
320
+    if g:Tlist_Show_Menu && has('gui_running')
321
+        call s:Tlist_Menu_Init()
322
+    endif
323
+
324
+    " restore 'cpo'
325
+    let &cpo = s:cpo_save
326
+    finish
327
+endif
328
+
329
+if !exists('s:tlist_sid')
330
+    " Two or more versions of taglist plugin are installed. Don't
331
+    " load this version of the plugin.
332
+    finish
333
+endif
334
+
335
+unlet! s:tlist_sid
336
+
337
+if loaded_taglist != 'fast_load_done'
338
+    " restore 'cpo'
339
+    let &cpo = s:cpo_save
340
+    finish
341
+endif
342
+
343
+" Taglist plugin functionality is available
344
+let loaded_taglist = 'available'
345
+
346
+"------------------- end of user configurable options --------------------
347
+
348
+" Default language specific settings for supported file types and tag types
349
+"
350
+" Variable name format:
351
+"
352
+"       s:tlist_def_{vim_ftype}_settings
353
+" 
354
+" vim_ftype - Filetype detected by Vim
355
+"
356
+" Value format:
357
+"
358
+"       <ctags_ftype>;<flag>:<name>;<flag>:<name>;...
359
+"
360
+" ctags_ftype - File type supported by exuberant ctags
361
+" flag        - Flag supported by exuberant ctags to generate a tag type
362
+" name        - Name of the tag type used in the taglist window to display the
363
+"               tags of this type
364
+"
365
+
366
+" assembly language
367
+let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type'
368
+
369
+" aspperl language
370
+let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable'
371
+
372
+" aspvbs language
373
+let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable'
374
+
375
+" awk language
376
+let s:tlist_def_awk_settings = 'awk;f:function'
377
+
378
+" beta language
379
+let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern'
380
+
381
+" c language
382
+let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' .
383
+                           \ 'v:variable;f:function'
384
+
385
+" c++ language
386
+let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' .
387
+                             \ 'c:class;g:enum;s:struct;u:union;f:function'
388
+
389
+" c# language
390
+let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' .
391
+                             \ 'E:event;g:enum;s:struct;i:interface;' .
392
+                             \ 'p:properties;m:method'
393
+
394
+" cobol language
395
+let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' .
396
+                               \ 'P:program;s:section'
397
+
398
+" eiffel language
399
+let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature'
400
+
401
+" erlang language
402
+let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function'
403
+
404
+" expect (same as tcl) language
405
+let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure'
406
+
407
+" fortran language
408
+let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' .
409
+                    \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' .
410
+                    \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine'
411
+
412
+" HTML language
413
+let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function'
414
+
415
+" java language
416
+let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' .
417
+                              \ 'f:field;m:method'
418
+
419
+" javascript language
420
+let s:tlist_def_javascript_settings = 'javascript;f:function'
421
+
422
+" lisp language
423
+let s:tlist_def_lisp_settings = 'lisp;f:function'
424
+
425
+" lua language
426
+let s:tlist_def_lua_settings = 'lua;f:function'
427
+
428
+" makefiles
429
+let s:tlist_def_make_settings = 'make;m:macro'
430
+
431
+" pascal language
432
+let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure'
433
+
434
+" perl language
435
+let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine'
436
+
437
+" php language
438
+let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function'
439
+
440
+" python language
441
+let s:tlist_def_python_settings = 'python;c:class;m:member;f:function'
442
+
443
+" rexx language
444
+let s:tlist_def_rexx_settings = 'rexx;s:subroutine'
445
+
446
+" ruby language
447
+let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' .
448
+                              \ 'm:singleton method'
449
+
450
+" scheme language
451
+let s:tlist_def_scheme_settings = 'scheme;s:set;f:function'
452
+
453
+" shell language
454
+let s:tlist_def_sh_settings = 'sh;f:function'
455
+
456
+" C shell language
457
+let s:tlist_def_csh_settings = 'sh;f:function'
458
+
459
+" Z shell language
460
+let s:tlist_def_zsh_settings = 'sh;f:function'
461
+
462
+" slang language
463
+let s:tlist_def_slang_settings = 'slang;n:namespace;f:function'
464
+
465
+" sml language
466
+let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' .
467
+                             \ 'r:structure;t:type;v:value;f:function'
468
+
469
+" sql language
470
+let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' .
471
+            \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure'
472
+
473
+" tcl language
474
+let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure'
475
+
476
+" vera language
477
+let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' .
478
+                                \ 'f:function;g:enum;m:member;p:program;' .
479
+                                \ 'P:prototype;t:task;T:typedef;v:variable;' .
480
+                                \ 'x:externvar'
481
+
482
+"verilog language
483
+let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' .
484
+            \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function'
485
+
486
+" vim language
487
+let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function'
488
+
489
+" yacc language
490
+let s:tlist_def_yacc_settings = 'yacc;l:label'
491
+
492
+"------------------- end of language specific options --------------------
493
+
494
+" Vim window size is changed by the taglist plugin or not
495
+let s:tlist_winsize_chgd = -1
496
+" Taglist window is maximized or not
497
+let s:tlist_win_maximized = 0
498
+" Name of files in the taglist
499
+let s:tlist_file_names=''
500
+" Number of files in the taglist
501
+let s:tlist_file_count = 0
502
+" Number of filetypes supported by taglist
503
+let s:tlist_ftype_count = 0
504
+" Is taglist part of other plugins like winmanager or cream?
505
+let s:tlist_app_name = "none"
506
+" Are we displaying brief help text
507
+let s:tlist_brief_help = 1
508
+" List of files removed on user request
509
+let s:tlist_removed_flist = ""
510
+" Index of current file displayed in the taglist window
511
+let s:tlist_cur_file_idx = -1
512
+" Taglist menu is empty or not
513
+let s:tlist_menu_empty = 1
514
+
515
+" An autocommand is used to refresh the taglist window when entering any
516
+" buffer. We don't want to refresh the taglist window if we are entering the
517
+" file window from one of the taglist functions. The 'Tlist_Skip_Refresh'
518
+" variable is used to skip the refresh of the taglist window and is set
519
+" and cleared appropriately.
520
+let s:Tlist_Skip_Refresh = 0
521
+
522
+" Tlist_Window_Display_Help()
523
+function! s:Tlist_Window_Display_Help()
524
+    if s:tlist_app_name == "winmanager"
525
+        " To handle a bug in the winmanager plugin, add a space at the
526
+        " last line
527
+        call setline('$', ' ')
528
+    endif
529
+
530
+    if s:tlist_brief_help
531
+        " Add the brief help
532
+        call append(0, '" Press <F1> to display help text')
533
+    else
534
+        " Add the extensive help
535
+        call append(0, '" <enter> : Jump to tag definition')
536
+        call append(1, '" o : Jump to tag definition in new window')
537
+        call append(2, '" p : Preview the tag definition')
538
+        call append(3, '" <space> : Display tag prototype')
539
+        call append(4, '" u : Update tag list')
540
+        call append(5, '" s : Select sort field')
541
+        call append(6, '" d : Remove file from taglist')
542
+        call append(7, '" x : Zoom-out/Zoom-in taglist window')
543
+        call append(8, '" + : Open a fold')
544
+        call append(9, '" - : Close a fold')
545
+        call append(10, '" * : Open all folds')
546
+        call append(11, '" = : Close all folds')
547
+        call append(12, '" [[ : Move to the start of previous file')
548
+        call append(13, '" ]] : Move to the start of next file')
549
+        call append(14, '" q : Close the taglist window')
550
+        call append(15, '" <F1> : Remove help text')
551
+    endif
552
+endfunction
553
+
554
+" Tlist_Window_Toggle_Help_Text()
555
+" Toggle taglist plugin help text between the full version and the brief
556
+" version
557
+function! s:Tlist_Window_Toggle_Help_Text()
558
+    if g:Tlist_Compact_Format
559
+        " In compact display mode, do not display help
560
+        return
561
+    endif
562
+
563
+    " Include the empty line displayed after the help text
564
+    let brief_help_size = 1
565
+    let full_help_size = 16
566
+
567
+    setlocal modifiable
568
+
569
+    " Set report option to a huge value to prevent informational messages
570
+    " while deleting the lines
571
+    let old_report = &report
572
+    set report=99999
573
+
574
+    " Remove the currently highlighted tag. Otherwise, the help text
575
+    " might be highlighted by mistake
576
+    match none
577
+
578
+    " Toggle between brief and full help text
579
+    if s:tlist_brief_help
580
+        let s:tlist_brief_help = 0
581
+
582
+        " Remove the previous help
583
+        exe '1,' . brief_help_size . ' delete _'
584
+
585
+        " Adjust the start/end line numbers for the files
586
+        call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size)
587
+    else
588
+        let s:tlist_brief_help = 1
589
+
590
+        " Remove the previous help
591
+        exe '1,' . full_help_size . ' delete _'
592
+
593
+        " Adjust the start/end line numbers for the files
594
+        call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size)
595
+    endif
596
+
597
+    call s:Tlist_Window_Display_Help()
598
+
599
+    " Restore the report option
600
+    let &report = old_report
601
+
602
+    setlocal nomodifiable
603
+endfunction
604
+
605
+" Taglist debug support
606
+let s:tlist_debug = 0
607
+
608
+" File for storing the debug messages
609
+let s:tlist_debug_file = ''
610
+
611
+" Tlist_Debug_Enable
612
+" Enable logging of taglist debug messages.
613
+function! s:Tlist_Debug_Enable(...)
614
+    let s:tlist_debug = 1
615
+
616
+    " Check whether a valid file name is supplied.
617
+    if a:1 != ''
618
+        let s:tlist_debug_file = fnamemodify(a:1, ':p')
619
+
620
+        " Empty the log file
621
+        exe 'redir! > ' . s:tlist_debug_file
622
+        redir END
623
+
624
+        " Check whether the log file is present/created
625
+        if !filewritable(s:tlist_debug_file)
626
+            call s:Tlist_Warning_Msg('Taglist: Unable to create log file '
627
+                        \ . s:tlist_debug_file)
628
+            let s:tlist_debug_file = ''
629
+        endif
630
+    endif
631
+endfunction
632
+
633
+" Tlist_Debug_Disable
634
+" Disable logging of taglist debug messages.
635
+function! s:Tlist_Debug_Disable(...)
636
+    let s:tlist_debug = 0
637
+    let s:tlist_debug_file = ''
638
+endfunction
639
+
640
+" Tlist_Debug_Show
641
+" Display the taglist debug messages in a new window
642
+function! s:Tlist_Debug_Show()
643
+    if s:tlist_msg == ''
644
+        call s:Tlist_Warning_Msg('Taglist: No debug messages')
645
+        return
646
+    endif
647
+
648
+    " Open a new window to display the taglist debug messages
649
+    new taglist_debug.txt
650
+    " Delete all the lines (if the buffer already exists)
651
+    silent! %delete _
652
+    " Add the messages
653
+    silent! put =s:tlist_msg
654
+    " Move the cursor to the first line
655
+    normal! gg
656
+endfunction
657
+
658
+" Tlist_Log_Msg
659
+" Log the supplied debug message along with the time
660
+function! s:Tlist_Log_Msg(msg)
661
+    if s:tlist_debug
662
+        if s:tlist_debug_file != ''
663
+            exe 'redir >> ' . s:tlist_debug_file
664
+            silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n"
665
+            redir END
666
+        else
667
+            " Log the message into a variable
668
+            " Retain only the last 3000 characters
669
+            let len = strlen(s:tlist_msg)
670
+            if len > 3000
671
+                let s:tlist_msg = strpart(s:tlist_msg, len - 3000)
672
+            endif
673
+            let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . 
674
+                        \ a:msg . "\n"
675
+        endif
676
+    endif
677
+endfunction
678
+
679
+" Tlist_Warning_Msg()
680
+" Display a message using WarningMsg highlight group
681
+function! s:Tlist_Warning_Msg(msg)
682
+    echohl WarningMsg
683
+    echomsg a:msg
684
+    echohl None
685
+endfunction
686
+
687
+" Last returned file index for file name lookup.
688
+" Used to speed up file lookup
689
+let s:tlist_file_name_idx_cache = -1
690
+
691
+" Tlist_Get_File_Index()
692
+" Return the index of the specified filename
693
+function! s:Tlist_Get_File_Index(fname)
694
+    if s:tlist_file_count == 0 || a:fname == ''
695
+        return -1
696
+    endif
697
+
698
+    " If the new filename is same as the last accessed filename, then
699
+    " return that index
700
+    if s:tlist_file_name_idx_cache != -1 &&
701
+                \ s:tlist_file_name_idx_cache < s:tlist_file_count
702
+        if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname
703
+            " Same as the last accessed file
704
+            return s:tlist_file_name_idx_cache
705
+        endif
706
+    endif
707
+
708
+    " First, check whether the filename is present
709
+    let s_fname = a:fname . "\n"
710
+    let i = stridx(s:tlist_file_names, s_fname)
711
+    if i == -1
712
+        let s:tlist_file_name_idx_cache = -1
713
+        return -1
714
+    endif
715
+
716
+    " Second, compute the file name index
717
+    let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g')
718
+    let s:tlist_file_name_idx_cache = strlen(nl_txt)
719
+    return s:tlist_file_name_idx_cache
720
+endfunction
721
+
722
+" Last returned file index for line number lookup.
723
+" Used to speed up file lookup
724
+let s:tlist_file_lnum_idx_cache = -1
725
+
726
+" Tlist_Window_Get_File_Index_By_Linenum()
727
+" Return the index of the filename present in the specified line number
728
+" Line number refers to the line number in the taglist window
729
+function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
730
+    call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')')
731
+
732
+    " First try to see whether the new line number is within the range
733
+    " of the last returned file
734
+    if s:tlist_file_lnum_idx_cache != -1 &&
735
+                \ s:tlist_file_lnum_idx_cache < s:tlist_file_count
736
+        if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start &&
737
+                    \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end
738
+            return s:tlist_file_lnum_idx_cache
739
+        endif
740
+    endif
741
+
742
+    let fidx = -1
743
+
744
+    if g:Tlist_Show_One_File
745
+        " Displaying only one file in the taglist window. Check whether
746
+        " the line is within the tags displayed for that file
747
+        if s:tlist_cur_file_idx != -1
748
+            if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start
749
+                        \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end
750
+                let fidx = s:tlist_cur_file_idx
751
+            endif
752
+
753
+        endif
754
+    else
755
+        " Do a binary search in the taglist
756
+        let left = 0
757
+        let right = s:tlist_file_count - 1
758
+
759
+        while left < right
760
+            let mid = (left + right) / 2
761
+
762
+            if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end
763
+                let s:tlist_file_lnum_idx_cache = mid
764
+                return mid
765
+            endif
766
+
767
+            if a:lnum < s:tlist_{mid}_start
768
+                let right = mid - 1
769
+            else
770
+                let left = mid + 1
771
+            endif
772
+        endwhile
773
+
774
+        if left >= 0 && left < s:tlist_file_count
775
+                    \ && a:lnum >= s:tlist_{left}_start
776
+                    \ && a:lnum <= s:tlist_{left}_end
777
+            let fidx = left
778
+        endif
779
+    endif
780
+
781
+    let s:tlist_file_lnum_idx_cache = fidx
782
+
783
+    return fidx
784
+endfunction
785
+
786
+" Tlist_Exe_Cmd_No_Acmds
787
+" Execute the specified Ex command after disabling autocommands
788
+function! s:Tlist_Exe_Cmd_No_Acmds(cmd)
789
+    let old_eventignore = &eventignore
790
+    set eventignore=all
791
+    exe a:cmd
792
+    let &eventignore = old_eventignore
793
+endfunction
794
+
795
+" Tlist_Skip_File()
796
+" Check whether tag listing is supported for the specified file
797
+function! s:Tlist_Skip_File(filename, ftype)
798
+    " Skip buffers with no names and buffers with filetype not set
799
+    if a:filename == '' || a:ftype == ''
800
+        return 1
801
+    endif
802
+
803
+    " Skip files which are not supported by exuberant ctags
804
+    " First check whether default settings for this filetype are available.
805
+    " If it is not available, then check whether user specified settings are
806
+    " available. If both are not available, then don't list the tags for this
807
+    " filetype
808
+    let var = 's:tlist_def_' . a:ftype . '_settings'
809
+    if !exists(var)
810
+        let var = 'g:tlist_' . a:ftype . '_settings'
811
+        if !exists(var)
812
+            return 1
813
+        endif
814
+    endif
815
+
816
+    " Skip files which are not readable or files which are not yet stored
817
+    " to the disk
818
+    if !filereadable(a:filename)
819
+        return 1
820
+    endif
821
+
822
+    return 0
823
+endfunction
824
+
825
+" Tlist_User_Removed_File
826
+" Returns 1 if a file is removed by a user from the taglist
827
+function! s:Tlist_User_Removed_File(filename)
828
+    return stridx(s:tlist_removed_flist, a:filename . "\n") != -1
829
+endfunction
830
+
831
+" Tlist_Update_Remove_List
832
+" Update the list of user removed files from the taglist
833
+" add == 1, add the file to the removed list
834
+" add == 0, delete the file from the removed list
835
+function! s:Tlist_Update_Remove_List(filename, add)
836
+    if a:add
837
+        let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n"
838
+    else
839
+        let idx = stridx(s:tlist_removed_flist, a:filename . "\n")
840
+        let text_before = strpart(s:tlist_removed_flist, 0, idx)
841
+        let rem_text = strpart(s:tlist_removed_flist, idx)
842
+        let next_idx = stridx(rem_text, "\n")
843
+        let text_after = strpart(rem_text, next_idx + 1)
844
+
845
+        let s:tlist_removed_flist = text_before . text_after
846
+    endif
847
+endfunction
848
+
849
+" Tlist_FileType_Init
850
+" Initialize the ctags arguments and tag variable for the specified
851
+" file type
852
+function! s:Tlist_FileType_Init(ftype)
853
+    call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')')
854
+    " If the user didn't specify any settings, then use the default
855
+    " ctags args. Otherwise, use the settings specified by the user
856
+    let var = 'g:tlist_' . a:ftype . '_settings'
857
+    if exists(var)
858
+        " User specified ctags arguments
859
+        let settings = {var} . ';'
860
+    else
861
+        " Default ctags arguments
862
+        let var = 's:tlist_def_' . a:ftype . '_settings'
863
+        if !exists(var)
864
+            " No default settings for this file type. This filetype is
865
+            " not supported
866
+            return 0
867
+        endif
868
+        let settings = s:tlist_def_{a:ftype}_settings . ';'
869
+    endif
870
+
871
+    let msg = 'Taglist: Invalid ctags option setting - ' . settings
872
+
873
+    " Format of the option that specifies the filetype and ctags arugments:
874
+    "
875
+    "       <language_name>;flag1:name1;flag2:name2;flag3:name3
876
+    "
877
+
878
+    " Extract the file type to pass to ctags. This may be different from the
879
+    " file type detected by Vim
880
+    let pos = stridx(settings, ';')
881
+    if pos == -1
882
+        call s:Tlist_Warning_Msg(msg)
883
+        return 0
884
+    endif
885
+    let ctags_ftype = strpart(settings, 0, pos)
886
+    if ctags_ftype == ''
887
+        call s:Tlist_Warning_Msg(msg)
888
+        return 0
889
+    endif
890
+    " Make sure a valid filetype is supplied. If the user didn't specify a
891
+    " valid filetype, then the ctags option settings may be treated as the
892
+    " filetype
893
+    if ctags_ftype =~ ':'
894
+        call s:Tlist_Warning_Msg(msg)
895
+        return 0
896
+    endif
897
+
898
+    " Remove the file type from settings
899
+    let settings = strpart(settings, pos + 1)
900
+    if settings == ''
901
+        call s:Tlist_Warning_Msg(msg)
902
+        return 0
903
+    endif
904
+
905
+    " Process all the specified ctags flags. The format is
906
+    " flag1:name1;flag2:name2;flag3:name3
907
+    let ctags_flags = ''
908
+    let cnt = 0
909
+    while settings != ''
910
+        " Extract the flag
911
+        let pos = stridx(settings, ':')
912
+        if pos == -1
913
+            call s:Tlist_Warning_Msg(msg)
914
+            return 0
915
+        endif
916
+        let flag = strpart(settings, 0, pos)
917
+        if flag == ''
918
+            call s:Tlist_Warning_Msg(msg)
919
+            return 0
920
+        endif
921
+        " Remove the flag from settings
922
+        let settings = strpart(settings, pos + 1)
923
+
924
+        " Extract the tag type name
925
+        let pos = stridx(settings, ';')
926
+        if pos == -1
927
+            call s:Tlist_Warning_Msg(msg)
928
+            return 0
929
+        endif
930
+        let name = strpart(settings, 0, pos)
931
+        if name == ''
932
+            call s:Tlist_Warning_Msg(msg)
933
+            return 0
934
+        endif
935
+        let settings = strpart(settings, pos + 1)
936
+
937
+        let cnt = cnt + 1
938
+
939
+        let s:tlist_{a:ftype}_{cnt}_name = flag
940
+        let s:tlist_{a:ftype}_{cnt}_fullname = name
941
+        let ctags_flags = ctags_flags . flag
942
+    endwhile
943
+
944
+    let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype .
945
+                            \ ' --' . ctags_ftype . '-types=' . ctags_flags
946
+    let s:tlist_{a:ftype}_count = cnt
947
+    let s:tlist_{a:ftype}_ctags_flags = ctags_flags
948
+
949
+    " Save the filetype name
950
+    let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype
951
+    let s:tlist_ftype_count = s:tlist_ftype_count + 1
952
+
953
+    return 1
954
+endfunction
955
+
956
+" Tlist_Detect_Filetype
957
+" Determine the filetype for the specified file using the filetypedetect
958
+" autocmd.
959
+function! s:Tlist_Detect_Filetype(fname)
960
+    " Ignore the filetype autocommands
961
+    let old_eventignore = &eventignore
962
+    set eventignore=FileType
963
+
964
+    " Save the 'filetype', as this will be changed temporarily
965
+    let old_filetype = &filetype
966
+
967
+    " Run the filetypedetect group of autocommands to determine
968
+    " the filetype
969
+    exe 'doautocmd filetypedetect BufRead ' . a:fname
970
+
971
+    " Save the detected filetype
972
+    let ftype = &filetype
973
+
974
+    " Restore the previous state
975
+    let &filetype = old_filetype
976
+    let &eventignore = old_eventignore
977
+
978
+    return ftype
979
+endfunction
980
+
981
+" Tlist_Get_Buffer_Filetype
982
+" Get the filetype for the specified buffer
983
+function! s:Tlist_Get_Buffer_Filetype(bnum)
984
+    let buf_ft = getbufvar(a:bnum, '&filetype')
985
+
986
+    if bufloaded(a:bnum)
987
+        " For loaded buffers, the 'filetype' is already determined
988
+        return buf_ft
989
+    endif
990
+
991
+    " For unloaded buffers, if the 'filetype' option is set, return it
992
+    if buf_ft != ''
993
+        return buf_ft
994
+    endif
995
+
996
+    " Skip non-existent buffers
997
+    if !bufexists(a:bnum)
998
+        return ''
999
+    endif
1000
+
1001
+    " For buffers whose filetype is not yet determined, try to determine
1002
+    " the filetype
1003
+    let bname = bufname(a:bnum)
1004
+
1005
+    return s:Tlist_Detect_Filetype(bname)
1006
+endfunction
1007
+
1008
+" Tlist_Discard_TagInfo
1009
+" Discard the stored tag information for a file
1010
+function! s:Tlist_Discard_TagInfo(fidx)
1011
+    call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' .
1012
+                \ s:tlist_{a:fidx}_filename . ')')
1013
+    let ftype = s:tlist_{a:fidx}_filetype
1014
+
1015
+    " Discard information about the tags defined in the file
1016
+    let i = 1
1017
+    while i <= s:tlist_{a:fidx}_tag_count
1018
+        let fidx_i = 's:tlist_' . a:fidx . '_' . i
1019
+        unlet! {fidx_i}_tag
1020
+        unlet! {fidx_i}_tag_name
1021
+        unlet! {fidx_i}_tag_type
1022
+        unlet! {fidx_i}_ttype_idx
1023
+        unlet! {fidx_i}_tag_proto
1024
+        unlet! {fidx_i}_tag_searchpat
1025
+        unlet! {fidx_i}_tag_linenum
1026
+        let i = i + 1
1027
+    endwhile
1028
+
1029
+    let s:tlist_{a:fidx}_tag_count = 0
1030
+
1031
+    " Discard information about tag type groups
1032
+    let i = 1
1033
+    while i <= s:tlist_{ftype}_count
1034
+        let ttype = s:tlist_{ftype}_{i}_name
1035
+        if s:tlist_{a:fidx}_{ttype} != ''
1036
+            let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype
1037
+            let {fidx_ttype} = ''
1038
+            let {fidx_ttype}_offset = 0
1039
+            let cnt = {fidx_ttype}_count
1040
+            let {fidx_ttype}_count = 0
1041
+            let j = 1
1042
+            while j <= cnt
1043
+                unlet! {fidx_ttype}_{j}
1044
+                let j = j + 1
1045
+            endwhile
1046
+        endif
1047
+        let i = i + 1
1048
+    endwhile
1049
+
1050
+    " Discard the stored menu command also
1051
+    let s:tlist_{a:fidx}_menu_cmd = ''
1052
+endfunction
1053
+
1054
+" Tlist_Window_Update_Line_Offsets
1055
+" Update the line offsets for tags for files starting from start_idx
1056
+" and displayed in the taglist window by the specified offset
1057
+function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset)
1058
+    let i = a:start_idx
1059
+
1060
+    while i < s:tlist_file_count
1061
+        if s:tlist_{i}_visible
1062
+            " Update the start/end line number only if the file is visible
1063
+            if a:increment
1064
+                let s:tlist_{i}_start = s:tlist_{i}_start + a:offset
1065
+                let s:tlist_{i}_end = s:tlist_{i}_end + a:offset
1066
+            else
1067
+                let s:tlist_{i}_start = s:tlist_{i}_start - a:offset
1068
+                let s:tlist_{i}_end = s:tlist_{i}_end - a:offset
1069
+            endif
1070
+        endif
1071
+        let i = i + 1
1072
+    endwhile
1073
+endfunction
1074
+
1075
+" Tlist_Discard_FileInfo
1076
+" Discard the stored information for a file
1077
+function! s:Tlist_Discard_FileInfo(fidx)
1078
+    call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' .
1079
+                \ s:tlist_{a:fidx}_filename . ')')
1080
+    call s:Tlist_Discard_TagInfo(a:fidx)
1081
+
1082
+    let ftype = s:tlist_{a:fidx}_filetype
1083
+
1084
+    let i = 1
1085
+    while i <= s:tlist_{ftype}_count
1086
+        let ttype = s:tlist_{ftype}_{i}_name
1087
+        unlet! s:tlist_{a:fidx}_{ttype}
1088
+        unlet! s:tlist_{a:fidx}_{ttype}_offset
1089
+        unlet! s:tlist_{a:fidx}_{ttype}_count
1090
+        let i = i + 1
1091
+    endwhile
1092
+
1093
+    unlet! s:tlist_{a:fidx}_filename
1094
+    unlet! s:tlist_{a:fidx}_sort_type
1095
+    unlet! s:tlist_{a:fidx}_filetype
1096
+    unlet! s:tlist_{a:fidx}_mtime
1097
+    unlet! s:tlist_{a:fidx}_start
1098
+    unlet! s:tlist_{a:fidx}_end
1099
+    unlet! s:tlist_{a:fidx}_valid
1100
+    unlet! s:tlist_{a:fidx}_visible
1101
+    unlet! s:tlist_{a:fidx}_tag_count
1102
+    unlet! s:tlist_{a:fidx}_menu_cmd
1103
+endfunction
1104
+
1105
+" Tlist_Window_Remove_File_From_Display
1106
+" Remove the specified file from display
1107
+function! s:Tlist_Window_Remove_File_From_Display(fidx)
1108
+    call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' .
1109
+                \ s:tlist_{a:fidx}_filename . ')')
1110
+    " If the file is not visible then no need to remove it
1111
+    if !s:tlist_{a:fidx}_visible
1112
+        return
1113
+    endif
1114
+
1115
+    " Remove the tags displayed for the specified file from the window
1116
+    let start = s:tlist_{a:fidx}_start
1117
+    " Include the empty line after the last line also
1118
+    if g:Tlist_Compact_Format
1119
+        let end = s:tlist_{a:fidx}_end
1120
+    else
1121
+        let end = s:tlist_{a:fidx}_end + 1
1122
+    endif
1123
+
1124
+    setlocal modifiable
1125
+    exe 'silent! ' . start . ',' . end . 'delete _'
1126
+    setlocal nomodifiable
1127
+
1128
+    " Correct the start and end line offsets for all the files following
1129
+    " this file, as the tags for this file are removed
1130
+    call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1)
1131
+endfunction
1132
+
1133
+" Tlist_Remove_File
1134
+" Remove the file under the cursor or the specified file index
1135
+" user_request - User requested to remove the file from taglist
1136
+function! s:Tlist_Remove_File(file_idx, user_request)
1137
+    let fidx = a:file_idx
1138
+
1139
+    if fidx == -1
1140
+        let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
1141
+        if fidx == -1
1142
+            return
1143
+        endif
1144
+    endif
1145
+    call s:Tlist_Log_Msg('Tlist_Remove_File (' .
1146
+                \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')')
1147
+
1148
+    let save_winnr = winnr()
1149
+    let winnum = bufwinnr(g:TagList_title)
1150
+    if winnum != -1
1151
+        " Taglist window is open, remove the file from display
1152
+
1153
+        if save_winnr != winnum
1154
+            let old_eventignore = &eventignore
1155
+            set eventignore=all
1156
+            exe winnum . 'wincmd w'
1157
+        endif
1158
+
1159
+        call s:Tlist_Window_Remove_File_From_Display(fidx)
1160
+
1161
+        if save_winnr != winnum
1162
+            exe save_winnr . 'wincmd w'
1163
+            let &eventignore = old_eventignore
1164
+        endif
1165
+    endif
1166
+
1167
+    let fname = s:tlist_{fidx}_filename
1168
+
1169
+    if a:user_request
1170
+        " As the user requested to remove the file from taglist,
1171
+        " add it to the removed list
1172
+        call s:Tlist_Update_Remove_List(fname, 1)
1173
+    endif
1174
+
1175
+    " Remove the file name from the taglist list of filenames
1176
+    let idx = stridx(s:tlist_file_names, fname . "\n")
1177
+    let text_before = strpart(s:tlist_file_names, 0, idx)
1178
+    let rem_text = strpart(s:tlist_file_names, idx)
1179
+    let next_idx = stridx(rem_text, "\n")
1180
+    let text_after = strpart(rem_text, next_idx + 1)
1181
+    let s:tlist_file_names = text_before . text_after
1182
+
1183
+    call s:Tlist_Discard_FileInfo(fidx)
1184
+
1185
+    " Shift all the file variables by one index
1186
+    let i = fidx + 1
1187
+
1188
+    while i < s:tlist_file_count
1189
+        let j = i - 1
1190
+
1191
+        let s:tlist_{j}_filename = s:tlist_{i}_filename
1192
+        let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type
1193
+        let s:tlist_{j}_filetype = s:tlist_{i}_filetype
1194
+        let s:tlist_{j}_mtime = s:tlist_{i}_mtime
1195
+        let s:tlist_{j}_start = s:tlist_{i}_start
1196
+        let s:tlist_{j}_end = s:tlist_{i}_end
1197
+        let s:tlist_{j}_valid = s:tlist_{i}_valid
1198
+        let s:tlist_{j}_visible = s:tlist_{i}_visible
1199
+        let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count
1200
+        let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd
1201
+
1202
+        let k = 1
1203
+        while k <= s:tlist_{j}_tag_count
1204
+            let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag
1205
+            let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name
1206
+            let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k)
1207
+            let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx
1208
+            let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k)
1209
+            let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k)
1210
+            let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k)
1211
+            let k = k + 1
1212
+        endwhile
1213
+
1214
+        let ftype = s:tlist_{i}_filetype
1215
+
1216
+        let k = 1
1217
+        while k <= s:tlist_{ftype}_count
1218
+            let ttype = s:tlist_{ftype}_{k}_name
1219
+            let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype}
1220
+            let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset
1221
+            let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count
1222
+            if s:tlist_{j}_{ttype} != ''
1223
+                let l = 1
1224
+                while l <= s:tlist_{j}_{ttype}_count
1225
+                    let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l}
1226
+                    let l = l + 1
1227
+                endwhile
1228
+            endif
1229
+            let k = k + 1
1230
+        endwhile
1231
+
1232
+        " As the file and tag information is copied to the new index,
1233
+        " discard the previous information
1234
+        call s:Tlist_Discard_FileInfo(i)
1235
+
1236
+        let i = i + 1
1237
+    endwhile
1238
+
1239
+    " Reduce the number of files displayed
1240
+    let s:tlist_file_count = s:tlist_file_count - 1
1241
+
1242
+    if g:Tlist_Show_One_File
1243
+        " If the tags for only one file is displayed and if we just
1244
+        " now removed that file, then invalidate the current file idx
1245
+        if s:tlist_cur_file_idx == fidx
1246
+            let s:tlist_cur_file_idx = -1
1247
+        endif
1248
+    endif
1249
+endfunction
1250
+
1251
+" Tlist_Window_Goto_Window
1252
+" Goto the taglist window
1253
+function! s:Tlist_Window_Goto_Window()
1254
+    let winnum = bufwinnr(g:TagList_title)
1255
+    if winnum != -1
1256
+        if winnr() != winnum
1257
+            call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w')
1258
+        endif
1259
+    endif
1260
+endfunction
1261
+
1262
+" Tlist_Window_Create
1263
+" Create a new taglist window. If it is already open, jump to it
1264
+function! s:Tlist_Window_Create()
1265
+    call s:Tlist_Log_Msg('Tlist_Window_Create()')
1266
+    " If the window is open, jump to it
1267
+    let winnum = bufwinnr(g:TagList_title)
1268
+    if winnum != -1
1269
+        " Jump to the existing window
1270
+        if winnr() != winnum
1271
+            exe winnum . 'wincmd w'
1272
+        endif
1273
+        return
1274
+    endif
1275
+
1276
+    " If used with winmanager don't open windows. Winmanager will handle
1277
+    " the window/buffer management
1278
+    if s:tlist_app_name == "winmanager"
1279
+        return
1280
+    endif
1281
+
1282
+    " Create a new window. If user prefers a horizontal window, then open
1283
+    " a horizontally split window. Otherwise open a vertically split
1284
+    " window
1285
+    if g:Tlist_Use_Horiz_Window
1286
+        " Open a horizontally split window
1287
+        let win_dir = 'botright'
1288
+        " Horizontal window height
1289
+        let win_size = g:Tlist_WinHeight
1290
+    else
1291
+        if s:tlist_winsize_chgd == -1
1292
+            " Open a vertically split window. Increase the window size, if
1293
+            " needed, to accomodate the new window
1294
+            if g:Tlist_Inc_Winwidth &&
1295
+                        \ &columns < (80 + g:Tlist_WinWidth)
1296
+                " Save the original window position
1297
+                let s:tlist_pre_winx = getwinposx()
1298
+                let s:tlist_pre_winy = getwinposy()
1299
+
1300
+                " one extra column is needed to include the vertical split
1301
+                let &columns= &columns + g:Tlist_WinWidth + 1
1302
+
1303
+                let s:tlist_winsize_chgd = 1
1304
+            else
1305
+                let s:tlist_winsize_chgd = 0
1306
+            endif
1307
+        endif
1308
+
1309
+        if g:Tlist_Use_Right_Window
1310
+            " Open the window at the rightmost place
1311
+            let win_dir = 'botright vertical'
1312
+        else
1313
+            " Open the window at the leftmost place
1314
+            let win_dir = 'topleft vertical'
1315
+        endif
1316
+        let win_size = g:Tlist_WinWidth
1317
+    endif
1318
+
1319
+    " If the tag listing temporary buffer already exists, then reuse it.
1320
+    " Otherwise create a new buffer
1321
+    let bufnum = bufnr(g:TagList_title)
1322
+    if bufnum == -1
1323
+        " Create a new buffer
1324
+        let wcmd = g:TagList_title
1325
+    else
1326
+        " Edit the existing buffer
1327
+        let wcmd = '+buffer' . bufnum
1328
+    endif
1329
+
1330
+    " Create the taglist window
1331
+    exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd
1332
+
1333
+    " Save the new window position
1334
+    let s:tlist_winx = getwinposx()
1335
+    let s:tlist_winy = getwinposy()
1336
+
1337
+    " Initialize the taglist window
1338
+    call s:Tlist_Window_Init()
1339
+endfunction
1340
+
1341
+" Tlist_Window_Zoom
1342
+" Zoom (maximize/minimize) the taglist window
1343
+function! s:Tlist_Window_Zoom()
1344
+    if s:tlist_win_maximized
1345
+        " Restore the window back to the previous size
1346
+        if g:Tlist_Use_Horiz_Window
1347
+            exe 'resize ' . g:Tlist_WinHeight
1348
+        else
1349
+            exe 'vert resize ' . g:Tlist_WinWidth
1350
+        endif
1351
+        let s:tlist_win_maximized = 0
1352
+    else
1353
+        " Set the window size to the maximum possible without closing other
1354
+        " windows
1355
+        if g:Tlist_Use_Horiz_Window
1356
+            resize
1357
+        else
1358
+            vert resize
1359
+        endif
1360
+        let s:tlist_win_maximized = 1
1361
+    endif
1362
+endfunction
1363
+
1364
+" Tlist_Ballon_Expr
1365
+" When the mouse cursor is over a tag in the taglist window, display the
1366
+" tag prototype (balloon)
1367
+function! Tlist_Ballon_Expr()
1368
+    " Get the file index
1369
+    let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(v:beval_lnum)
1370
+    if fidx == -1
1371
+        return ''
1372
+    endif
1373
+
1374
+    " Get the tag output line for the current tag
1375
+    let tidx = s:Tlist_Window_Get_Tag_Index(fidx, v:beval_lnum)
1376
+    if tidx == 0
1377
+        return ''
1378
+    endif
1379
+
1380
+    " Get the tag search pattern and display it
1381
+    return s:Tlist_Get_Tag_Prototype(fidx, tidx)
1382
+endfunction
1383
+
1384
+" Tlist_Window_Check_Width
1385
+" Check the width of the taglist window. For horizontally split windows, the
1386
+" 'winfixheight' option is used to fix the height of the window. For
1387
+" vertically split windows, Vim doesn't support the 'winfixwidth' option. So
1388
+" need to handle window width changes from this function.
1389
+function! s:Tlist_Window_Check_Width()
1390
+    let tlist_winnr = bufwinnr(g:TagList_title)
1391
+    if tlist_winnr == -1
1392
+        return
1393
+    endif
1394
+
1395
+    let width = winwidth(tlist_winnr)
1396
+    if width != g:Tlist_WinWidth
1397
+        call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " .
1398
+                    \ "width from " . width . " to " . g:Tlist_WinWidth)
1399
+        let save_winnr = winnr()
1400
+        if save_winnr != tlist_winnr
1401
+            call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w')
1402
+        endif
1403
+        exe 'vert resize ' . g:Tlist_WinWidth
1404
+        if save_winnr != tlist_winnr
1405
+            call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
1406
+        endif
1407
+    endif
1408
+endfunction
1409
+
1410
+" Tlist_Window_Exit_Only_Window
1411
+" If the 'Tlist_Exit_OnlyWindow' option is set, then exit Vim if only the
1412
+" taglist window is present.
1413
+function! s:Tlist_Window_Exit_Only_Window()
1414
+    " Before quitting Vim, delete the taglist buffer so that
1415
+    " the '0 mark is correctly set to the previous buffer.
1416
+    if v:version < 700
1417
+	if winbufnr(2) == -1
1418
+	    bdelete
1419
+	    quit
1420
+	endif
1421
+    else
1422
+	if winbufnr(2) == -1
1423
+	    if tabpagenr('$') == 1
1424
+		" Only one tag page is present
1425
+		bdelete
1426
+		quit
1427
+	    else
1428
+		" More than one tab page is present. Close only the current
1429
+		" tab page
1430
+		close
1431
+	    endif
1432
+	endif
1433
+    endif
1434
+endfunction
1435
+
1436
+" Tlist_Window_Init
1437
+" Set the default options for the taglist window
1438
+function! s:Tlist_Window_Init()
1439
+    call s:Tlist_Log_Msg('Tlist_Window_Init()')
1440
+
1441
+    " The 'readonly' option should not be set for the taglist buffer.
1442
+    " If Vim is started as "view/gview" or if the ":view" command is
1443
+    " used, then the 'readonly' option is set for all the buffers.
1444
+    " Unset it for the taglist buffer
1445
+    setlocal noreadonly
1446
+
1447
+    " Set the taglist buffer filetype to taglist
1448
+    setlocal filetype=taglist
1449
+
1450
+    " Define taglist window element highlighting
1451
+    syntax match TagListComment '^" .*'
1452
+    syntax match TagListFileName '^[^" ].*$'
1453
+    syntax match TagListTitle '^  \S.*$'
1454
+    syntax match TagListTagScope  '\s\[.\{-\}\]$'
1455
+
1456
+    " Define the highlighting only if colors are supported
1457
+    if has('gui_running') || &t_Co > 2
1458
+        " Colors to highlight various taglist window elements
1459
+        " If user defined highlighting group exists, then use them.
1460
+        " Otherwise, use default highlight groups.
1461
+        if hlexists('MyTagListTagName')
1462
+            highlight link TagListTagName MyTagListTagName
1463
+        else
1464
+            highlight default link TagListTagName Search
1465
+        endif
1466
+        " Colors to highlight comments and titles
1467
+        if hlexists('MyTagListComment')
1468
+            highlight link TagListComment MyTagListComment
1469
+        else
1470
+            highlight clear TagListComment
1471
+            highlight default link TagListComment Comment
1472
+        endif
1473
+        if hlexists('MyTagListTitle')
1474
+            highlight link TagListTitle MyTagListTitle
1475
+        else
1476
+            highlight clear TagListTitle
1477
+            highlight default link TagListTitle Title
1478
+        endif
1479
+        if hlexists('MyTagListFileName')
1480
+            highlight link TagListFileName MyTagListFileName
1481
+        else
1482
+            highlight clear TagListFileName
1483
+            highlight default TagListFileName guibg=Grey ctermbg=darkgray
1484
+                        \ guifg=white ctermfg=white
1485
+        endif
1486
+        if hlexists('MyTagListTagScope')
1487
+            highlight link TagListTagScope MyTagListTagScope
1488
+        else
1489
+            highlight clear TagListTagScope
1490
+            highlight default link TagListTagScope Identifier
1491
+        endif
1492
+    else
1493
+        highlight default TagListTagName term=reverse cterm=reverse
1494
+    endif
1495
+
1496
+    " Folding related settings
1497
+    setlocal foldenable
1498
+    setlocal foldminlines=0
1499
+    setlocal foldmethod=manual
1500
+    setlocal foldlevel=9999
1501
+    if g:Tlist_Enable_Fold_Column
1502
+        setlocal foldcolumn=3
1503
+    else
1504
+        setlocal foldcolumn=0
1505
+    endif
1506
+    setlocal foldtext=v:folddashes.getline(v:foldstart)
1507
+
1508
+    if s:tlist_app_name != "winmanager"
1509
+        " Mark buffer as scratch
1510
+        silent! setlocal buftype=nofile
1511
+        if s:tlist_app_name == "none"
1512
+            silent! setlocal bufhidden=delete
1513
+        endif
1514
+        silent! setlocal noswapfile
1515
+        " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted
1516
+        " buffers. So if the taglist buffer is unlisted, multiple taglist
1517
+        " windows will be opened. This bug is fixed in Vim 6.1 and above
1518
+        if v:version >= 601
1519
+            silent! setlocal nobuflisted
1520
+        endif
1521
+    endif
1522
+
1523
+    silent! setlocal nowrap
1524
+
1525
+    " If the 'number' option is set in the source window, it will affect the
1526
+    " taglist window. So forcefully disable 'number' option for the taglist
1527
+    " window
1528
+    silent! setlocal nonumber
1529
+
1530
+    " Use fixed height when horizontally split window is used
1531
+    if g:Tlist_Use_Horiz_Window
1532
+        if v:version >= 602
1533
+            set winfixheight
1534
+        endif
1535
+    endif
1536
+    if !g:Tlist_Use_Horiz_Window && v:version >= 700
1537
+        set winfixwidth
1538
+    endif
1539
+
1540
+    " Setup balloon evaluation to display tag prototype
1541
+    if v:version >= 700 && has('balloon_eval')
1542
+        setlocal balloonexpr=Tlist_Ballon_Expr()
1543
+        set ballooneval
1544
+    endif
1545
+
1546
+    " Setup the cpoptions properly for the maps to work
1547
+    let old_cpoptions = &cpoptions
1548
+    set cpoptions&vim
1549
+
1550
+    " Create buffer local mappings for jumping to the tags and sorting the list
1551
+    nnoremap <buffer> <silent> <CR>
1552
+                \ :call <SID>Tlist_Window_Jump_To_Tag('useopen')<CR>
1553
+    nnoremap <buffer> <silent> o
1554
+                \ :call <SID>Tlist_Window_Jump_To_Tag('newwin')<CR>
1555
+    nnoremap <buffer> <silent> p
1556
+                \ :call <SID>Tlist_Window_Jump_To_Tag('preview')<CR>
1557
+    nnoremap <buffer> <silent> P
1558
+                \ :call <SID>Tlist_Window_Jump_To_Tag('prevwin')<CR>
1559
+    if v:version >= 700
1560
+    nnoremap <buffer> <silent> t
1561
+                \ :call <SID>Tlist_Window_Jump_To_Tag('checktab')<CR>
1562
+    nnoremap <buffer> <silent> <C-t>
1563
+                \ :call <SID>Tlist_Window_Jump_To_Tag('newtab')<CR>
1564
+    endif
1565
+    nnoremap <buffer> <silent> <2-LeftMouse>
1566
+                \ :call <SID>Tlist_Window_Jump_To_Tag('useopen')<CR>
1567
+    nnoremap <buffer> <silent> s
1568
+                \ :call <SID>Tlist_Change_Sort('cmd', 'toggle', '')<CR>
1569
+    nnoremap <buffer> <silent> + :silent! foldopen<CR>
1570
+    nnoremap <buffer> <silent> - :silent! foldclose<CR>
1571
+    nnoremap <buffer> <silent> * :silent! %foldopen!<CR>
1572
+    nnoremap <buffer> <silent> = :silent! %foldclose<CR>
1573
+    nnoremap <buffer> <silent> <kPlus> :silent! foldopen<CR>
1574
+    nnoremap <buffer> <silent> <kMinus> :silent! foldclose<CR>
1575
+    nnoremap <buffer> <silent> <kMultiply> :silent! %foldopen!<CR>
1576
+    nnoremap <buffer> <silent> <Space> :call <SID>Tlist_Window_Show_Info()<CR>
1577
+    nnoremap <buffer> <silent> u :call <SID>Tlist_Window_Update_File()<CR>
1578
+    nnoremap <buffer> <silent> d :call <SID>Tlist_Remove_File(-1, 1)<CR>
1579
+    nnoremap <buffer> <silent> x :call <SID>Tlist_Window_Zoom()<CR>
1580
+    nnoremap <buffer> <silent> [[ :call <SID>Tlist_Window_Move_To_File(-1)<CR>
1581
+    nnoremap <buffer> <silent> <BS> :call <SID>Tlist_Window_Move_To_File(-1)<CR>
1582
+    nnoremap <buffer> <silent> ]] :call <SID>Tlist_Window_Move_To_File(1)<CR>
1583
+    nnoremap <buffer> <silent> <Tab> :call <SID>Tlist_Window_Move_To_File(1)<CR>
1584
+    nnoremap <buffer> <silent> <F1> :call <SID>Tlist_Window_Toggle_Help_Text()<CR>
1585
+    nnoremap <buffer> <silent> q :close<CR>
1586
+
1587
+    " Insert mode mappings
1588
+    inoremap <buffer> <silent> <CR>
1589
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('useopen')<CR>
1590
+    " Windows needs return
1591
+    inoremap <buffer> <silent> <Return>
1592
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('useopen')<CR>
1593
+    inoremap <buffer> <silent> o
1594
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('newwin')<CR>
1595
+    inoremap <buffer> <silent> p
1596
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('preview')<CR>
1597
+    inoremap <buffer> <silent> P
1598
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('prevwin')<CR>
1599
+    if v:version >= 700
1600
+    inoremap <buffer> <silent> t
1601
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('checktab')<CR>
1602
+    inoremap <buffer> <silent> <C-t>
1603
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('newtab')<CR>
1604
+    endif
1605
+    inoremap <buffer> <silent> <2-LeftMouse>
1606
+                \ <C-o>:call <SID>Tlist_Window_Jump_To_Tag('useopen')<CR>
1607
+    inoremap <buffer> <silent> s
1608
+                \ <C-o>:call <SID>Tlist_Change_Sort('cmd', 'toggle', '')<CR>
1609
+    inoremap <buffer> <silent> +             <C-o>:silent! foldopen<CR>
1610
+    inoremap <buffer> <silent> -             <C-o>:silent! foldclose<CR>
1611
+    inoremap <buffer> <silent> *             <C-o>:silent! %foldopen!<CR>
1612
+    inoremap <buffer> <silent> =             <C-o>:silent! %foldclose<CR>
1613
+    inoremap <buffer> <silent> <kPlus>       <C-o>:silent! foldopen<CR>
1614
+    inoremap <buffer> <silent> <kMinus>      <C-o>:silent! foldclose<CR>
1615
+    inoremap <buffer> <silent> <kMultiply>   <C-o>:silent! %foldopen!<CR>
1616
+    inoremap <buffer> <silent> <Space>       <C-o>:call
1617
+                                    \ <SID>Tlist_Window_Show_Info()<CR>
1618
+    inoremap <buffer> <silent> u
1619
+                            \ <C-o>:call <SID>Tlist_Window_Update_File()<CR>
1620
+    inoremap <buffer> <silent> d    <C-o>:call <SID>Tlist_Remove_File(-1, 1)<CR>
1621
+    inoremap <buffer> <silent> x    <C-o>:call <SID>Tlist_Window_Zoom()<CR>
1622
+    inoremap <buffer> <silent> [[   <C-o>:call <SID>Tlist_Window_Move_To_File(-1)<CR>
1623
+    inoremap <buffer> <silent> <BS> <C-o>:call <SID>Tlist_Window_Move_To_File(-1)<CR>
1624
+    inoremap <buffer> <silent> ]]   <C-o>:call <SID>Tlist_Window_Move_To_File(1)<CR>
1625
+    inoremap <buffer> <silent> <Tab> <C-o>:call <SID>Tlist_Window_Move_To_File(1)<CR>
1626
+    inoremap <buffer> <silent> <F1>  <C-o>:call <SID>Tlist_Window_Toggle_Help_Text()<CR>
1627
+    inoremap <buffer> <silent> q    <C-o>:close<CR>
1628
+
1629
+    " Map single left mouse click if the user wants this functionality
1630
+    if g:Tlist_Use_SingleClick == 1
1631
+        " Contributed by Bindu Wavell
1632
+        " attempt to perform single click mapping, it would be much
1633
+        " nicer if we could nnoremap <buffer> ... however vim does
1634
+        " not fire the <buffer> <leftmouse> when you use the mouse
1635
+        " to enter a buffer.
1636
+        let clickmap = ':if bufname("%") =~ "__Tag_List__" <bar> ' .
1637
+                    \ 'call <SID>Tlist_Window_Jump_To_Tag("useopen") ' .
1638
+                    \ '<bar> endif <CR>'
1639
+        if maparg('<leftmouse>', 'n') == ''
1640
+            " no mapping for leftmouse
1641
+            exe ':nnoremap <silent> <leftmouse> <leftmouse>' . clickmap
1642
+        else
1643
+            " we have a mapping
1644
+            let mapcmd = ':nnoremap <silent> <leftmouse> <leftmouse>'
1645
+            let mapcmd = mapcmd . substitute(substitute(
1646
+                        \ maparg('<leftmouse>', 'n'), '|', '<bar>', 'g'),
1647
+                        \ '\c^<leftmouse>', '', '')
1648
+            let mapcmd = mapcmd . clickmap
1649
+            exe mapcmd
1650
+        endif
1651
+    endif
1652
+
1653
+    " Define the taglist autocommands
1654
+    augroup TagListAutoCmds
1655
+        autocmd!
1656
+        " Display the tag prototype for the tag under the cursor.
1657
+        autocmd CursorHold __Tag_List__ call s:Tlist_Window_Show_Info()
1658
+        " Highlight the current tag periodically
1659
+        autocmd CursorHold * silent call s:Tlist_Window_Highlight_Tag(
1660
+                            \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0)
1661
+
1662
+        " Adjust the Vim window width when taglist window is closed
1663
+        autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup()
1664
+        " Close the fold for this buffer when leaving the buffer
1665
+        if g:Tlist_File_Fold_Auto_Close
1666
+            autocmd BufEnter * silent
1667
+                \ call s:Tlist_Window_Open_File_Fold(expand('<abuf>'))
1668
+        endif
1669
+        " Exit Vim itself if only the taglist window is present (optional)
1670
+        if g:Tlist_Exit_OnlyWindow
1671
+	    autocmd BufEnter __Tag_List__ nested
1672
+			\ call s:Tlist_Window_Exit_Only_Window()
1673
+        endif
1674
+        if s:tlist_app_name != "winmanager" &&
1675
+                    \ !g:Tlist_Process_File_Always &&
1676
+                    \ (!has('gui_running') || !g:Tlist_Show_Menu)
1677
+            " Auto refresh the taglist window
1678
+            autocmd BufEnter * call s:Tlist_Refresh()
1679
+        endif
1680
+
1681
+        if !g:Tlist_Use_Horiz_Window
1682
+            if v:version < 700
1683
+                autocmd WinEnter * call s:Tlist_Window_Check_Width()
1684
+            endif
1685
+        endif
1686
+        if v:version >= 700
1687
+            autocmd TabEnter * silent call s:Tlist_Refresh_Folds()
1688
+        endif
1689
+    augroup end
1690
+
1691
+    " Restore the previous cpoptions settings
1692
+    let &cpoptions = old_cpoptions
1693
+endfunction
1694
+
1695
+" Tlist_Window_Refresh
1696
+" Display the tags for all the files in the taglist window
1697
+function! s:Tlist_Window_Refresh()
1698
+    call s:Tlist_Log_Msg('Tlist_Window_Refresh()')
1699
+    " Set report option to a huge value to prevent informational messages
1700
+    " while deleting the lines
1701
+    let old_report = &report
1702
+    set report=99999
1703
+
1704
+    " Mark the buffer as modifiable
1705
+    setlocal modifiable
1706
+
1707
+    " Delete the contents of the buffer to the black-hole register
1708
+    silent! %delete _
1709
+
1710
+    " As we have cleared the taglist window, mark all the files
1711
+    " as not visible
1712
+    let i = 0
1713
+    while i < s:tlist_file_count
1714
+        let s:tlist_{i}_visible = 0
1715
+        let i = i + 1
1716
+    endwhile
1717
+
1718
+    if g:Tlist_Compact_Format == 0
1719
+        " Display help in non-compact mode
1720
+        call s:Tlist_Window_Display_Help()
1721
+    endif
1722
+
1723
+    " Mark the buffer as not modifiable
1724
+    setlocal nomodifiable
1725
+
1726
+    " Restore the report option
1727
+    let &report = old_report
1728
+
1729
+    " If the tags for only one file should be displayed in the taglist
1730
+    " window, then no need to add the tags here. The bufenter autocommand
1731
+    " will add the tags for that file.
1732
+    if g:Tlist_Show_One_File
1733
+        return
1734
+    endif
1735
+
1736
+    " List all the tags for the previously processed files
1737
+    " Do this only if taglist is configured to display tags for more than
1738
+    " one file. Otherwise, when Tlist_Show_One_File is configured,
1739
+    " tags for the wrong file will be displayed.
1740
+    let i = 0
1741
+    while i < s:tlist_file_count
1742
+        call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename,
1743
+                    \ s:tlist_{i}_filetype)
1744
+        let i = i + 1
1745
+    endwhile
1746
+
1747
+    if g:Tlist_Auto_Update
1748
+        " Add and list the tags for all buffers in the Vim buffer list
1749
+        let i = 1
1750
+        let last_bufnum = bufnr('$')
1751
+        while i <= last_bufnum
1752
+            if buflisted(i)
1753
+                let fname = fnamemodify(bufname(i), ':p')
1754
+                let ftype = s:Tlist_Get_Buffer_Filetype(i)
1755
+                " If the file doesn't support tag listing, skip it
1756
+                if !s:Tlist_Skip_File(fname, ftype)
1757
+                    call s:Tlist_Window_Refresh_File(fname, ftype)
1758
+                endif
1759
+            endif
1760
+            let i = i + 1
1761
+        endwhile
1762
+    endif
1763
+
1764
+    " If Tlist_File_Fold_Auto_Close option is set, then close all the folds
1765
+    if g:Tlist_File_Fold_Auto_Close
1766
+        " Close all the folds
1767
+        silent! %foldclose
1768
+    endif
1769
+
1770
+    " Move the cursor to the top of the taglist window
1771
+    normal! gg
1772
+endfunction
1773
+
1774
+" Tlist_Post_Close_Cleanup()
1775
+" Close the taglist window and adjust the Vim window width
1776
+function! s:Tlist_Post_Close_Cleanup()
1777
+    call s:Tlist_Log_Msg('Tlist_Post_Close_Cleanup()')
1778
+    " Mark all the files as not visible
1779
+    let i = 0
1780
+    while i < s:tlist_file_count
1781
+        let s:tlist_{i}_visible = 0
1782
+        let i = i + 1
1783
+    endwhile
1784
+
1785
+    " Remove the taglist autocommands
1786
+    silent! autocmd! TagListAutoCmds
1787
+
1788
+    " Clear all the highlights
1789
+    match none
1790
+
1791
+    silent! syntax clear TagListTitle
1792
+    silent! syntax clear TagListComment
1793
+    silent! syntax clear TagListTagScope
1794
+
1795
+    " Remove the left mouse click mapping if it was setup initially
1796
+    if g:Tlist_Use_SingleClick
1797
+        if hasmapto('<LeftMouse>')
1798
+            nunmap <LeftMouse>
1799
+        endif
1800
+    endif
1801
+
1802
+    if s:tlist_app_name != "winmanager"
1803
+    if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 ||
1804
+                \ s:tlist_winsize_chgd != 1 ||
1805
+                \ &columns < (80 + g:Tlist_WinWidth)
1806
+        " No need to adjust window width if using horizontally split taglist
1807
+        " window or if columns is less than 101 or if the user chose not to
1808
+        " adjust the window width
1809
+    else
1810
+        " If the user didn't manually move the window, then restore the window
1811
+        " position to the pre-taglist position
1812
+        if s:tlist_pre_winx != -1 && s:tlist_pre_winy != -1 &&
1813
+                    \ getwinposx() == s:tlist_winx &&
1814
+                    \ getwinposy() == s:tlist_winy
1815
+            exe 'winpos ' . s:tlist_pre_winx . ' ' . s:tlist_pre_winy
1816
+        endif
1817
+
1818
+        " Adjust the Vim window width
1819
+        let &columns= &columns - (g:Tlist_WinWidth + 1)
1820
+    endif
1821
+    endif
1822
+
1823
+    let s:tlist_winsize_chgd = -1
1824
+
1825
+    " Reset taglist state variables
1826
+    if s:tlist_app_name == "winmanager"
1827
+        let s:tlist_app_name = "none"
1828
+    endif
1829
+    let s:tlist_window_initialized = 0
1830
+endfunction
1831
+
1832
+" Tlist_Window_Refresh_File()
1833
+" List the tags defined in the specified file in a Vim window
1834
+function! s:Tlist_Window_Refresh_File(filename, ftype)
1835
+    call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')')
1836
+    " First check whether the file already exists
1837
+    let fidx = s:Tlist_Get_File_Index(a:filename)
1838
+    if fidx != -1
1839
+        let file_listed = 1
1840
+    else
1841
+        let file_listed = 0
1842
+    endif
1843
+
1844
+    if !file_listed
1845
+        " Check whether this file is removed based on user request
1846
+        " If it is, then don't display the tags for this file
1847
+        if s:Tlist_User_Removed_File(a:filename)
1848
+            return
1849
+        endif
1850
+    endif
1851
+
1852
+    if file_listed && s:tlist_{fidx}_visible
1853
+        " Check whether the file tags are currently valid
1854
+        if s:tlist_{fidx}_valid
1855
+            " Goto the first line in the file
1856
+            exe s:tlist_{fidx}_start
1857
+
1858
+            " If the line is inside a fold, open the fold
1859
+            if foldclosed('.') != -1
1860
+                exe "silent! " . s:tlist_{fidx}_start . "," .
1861
+                            \ s:tlist_{fidx}_end . "foldopen!"
1862
+            endif
1863
+            return
1864
+        endif
1865
+
1866
+        " Discard and remove the tags for this file from display
1867
+        call s:Tlist_Discard_TagInfo(fidx)
1868
+        call s:Tlist_Window_Remove_File_From_Display(fidx)
1869
+    endif
1870
+
1871
+    " Process and generate a list of tags defined in the file
1872
+    if !file_listed || !s:tlist_{fidx}_valid
1873
+        let ret_fidx = s:Tlist_Process_File(a:filename, a:ftype)
1874
+        if ret_fidx == -1
1875
+            return
1876
+        endif
1877
+        let fidx = ret_fidx
1878
+    endif
1879
+
1880
+    " Set report option to a huge value to prevent informational messages
1881
+    " while adding lines to the taglist window
1882
+    let old_report = &report
1883
+    set report=99999
1884
+
1885
+    if g:Tlist_Show_One_File
1886
+        " Remove the previous file
1887
+        if s:tlist_cur_file_idx != -1
1888
+            call s:Tlist_Window_Remove_File_From_Display(s:tlist_cur_file_idx)
1889
+            let s:tlist_{s:tlist_cur_file_idx}_visible = 0
1890
+            let s:tlist_{s:tlist_cur_file_idx}_start = 0
1891
+            let s:tlist_{s:tlist_cur_file_idx}_end = 0
1892
+        endif
1893
+        let s:tlist_cur_file_idx = fidx
1894
+    endif
1895
+
1896
+    " Mark the buffer as modifiable
1897
+    setlocal modifiable
1898
+
1899
+    " Add new files to the end of the window. For existing files, add them at
1900
+    " the same line where they were previously present. If the file is not
1901
+    " visible, then add it at the end
1902
+    if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible
1903
+        if g:Tlist_Compact_Format
1904
+            let s:tlist_{fidx}_start = line('$')
1905
+        else
1906
+            let s:tlist_{fidx}_start = line('$') + 1
1907
+        endif
1908
+    endif
1909
+
1910
+    let s:tlist_{fidx}_visible = 1
1911
+
1912
+    " Goto the line where this file should be placed
1913
+    if g:Tlist_Compact_Format
1914
+        exe s:tlist_{fidx}_start
1915
+    else
1916
+        exe s:tlist_{fidx}_start - 1
1917
+    endif
1918
+
1919
+    let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' .
1920
+                \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')'
1921
+    if g:Tlist_Compact_Format == 0
1922
+        silent! put =txt
1923
+    else
1924
+        silent! put! =txt
1925
+        " Move to the next line
1926
+        exe line('.') + 1
1927
+    endif
1928
+    let file_start = s:tlist_{fidx}_start
1929
+
1930
+    " Add the tag names grouped by tag type to the buffer with a title
1931
+    let i = 1
1932
+    let ttype_cnt = s:tlist_{a:ftype}_count
1933
+    while i <= ttype_cnt
1934
+        let ttype = s:tlist_{a:ftype}_{i}_name
1935
+        " Add the tag type only if there are tags for that type
1936
+        let fidx_ttype = 's:tlist_' . fidx . '_' . ttype
1937
+        let ttype_txt = {fidx_ttype}
1938
+        if ttype_txt != ''
1939
+            let txt = '  ' . s:tlist_{a:ftype}_{i}_fullname
1940
+            if g:Tlist_Compact_Format == 0
1941
+                let ttype_start_lnum = line('.') + 1
1942
+                silent! put =txt
1943
+            else
1944
+                let ttype_start_lnum = line('.')
1945
+                silent! put! =txt
1946
+            endif
1947
+            silent! put =ttype_txt
1948
+
1949
+            let {fidx_ttype}_offset = ttype_start_lnum - file_start
1950
+
1951
+            " create a fold for this tag type
1952
+            let fold_start = ttype_start_lnum
1953
+            let fold_end = fold_start + {fidx_ttype}_count
1954
+            exe fold_start . ',' . fold_end  . 'fold'
1955
+
1956
+            " Adjust the cursor position
1957
+            if g:Tlist_Compact_Format == 0
1958
+                exe ttype_start_lnum + {fidx_ttype}_count
1959
+            else
1960
+                exe ttype_start_lnum + {fidx_ttype}_count + 1
1961
+            endif
1962
+
1963
+            if g:Tlist_Compact_Format == 0
1964
+                " Separate the tag types by a empty line
1965
+                silent! put =''
1966
+            endif
1967
+        endif
1968
+        let i = i + 1
1969
+    endwhile
1970
+
1971
+    if s:tlist_{fidx}_tag_count == 0
1972
+        if g:Tlist_Compact_Format == 0
1973
+            silent! put =''
1974
+        endif
1975
+    endif
1976
+
1977
+    let s:tlist_{fidx}_end = line('.') - 1
1978
+
1979
+    " Create a fold for the entire file
1980
+    exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold'
1981
+    exe 'silent! ' . s:tlist_{fidx}_start . ',' .
1982
+                \ s:tlist_{fidx}_end . 'foldopen!'
1983
+
1984
+    " Goto the starting line for this file,
1985
+    exe s:tlist_{fidx}_start
1986
+
1987
+    if s:tlist_app_name == "winmanager"
1988
+        " To handle a bug in the winmanager plugin, add a space at the
1989
+        " last line
1990
+        call setline('$', ' ')
1991
+    endif
1992
+
1993
+    " Mark the buffer as not modifiable
1994
+    setlocal nomodifiable
1995
+
1996
+    " Restore the report option
1997
+    let &report = old_report
1998
+
1999
+    " Update the start and end line numbers for all the files following this
2000
+    " file
2001
+    let start = s:tlist_{fidx}_start
2002
+    " include the empty line after the last line
2003
+    if g:Tlist_Compact_Format
2004
+        let end = s:tlist_{fidx}_end
2005
+    else
2006
+        let end = s:tlist_{fidx}_end + 1
2007
+    endif
2008
+    call s:Tlist_Window_Update_Line_Offsets(fidx + 1, 1, end - start + 1)
2009
+
2010
+    " Now that we have updated the taglist window, update the tags
2011
+    " menu (if present)
2012
+    if g:Tlist_Show_Menu
2013
+        call s:Tlist_Menu_Update_File(1)
2014
+    endif
2015
+endfunction
2016
+
2017
+" Tlist_Init_File
2018
+" Initialize the variables for a new file
2019
+function! s:Tlist_Init_File(filename, ftype)
2020
+    call s:Tlist_Log_Msg('Tlist_Init_File (' . a:filename . ')')
2021
+    " Add new files at the end of the list
2022
+    let fidx = s:tlist_file_count
2023
+    let s:tlist_file_count = s:tlist_file_count + 1
2024
+    " Add the new file name to the taglist list of file names
2025
+    let s:tlist_file_names = s:tlist_file_names . a:filename . "\n"
2026
+
2027
+    " Initialize the file variables
2028
+    let s:tlist_{fidx}_filename = a:filename
2029
+    let s:tlist_{fidx}_sort_type = g:Tlist_Sort_Type
2030
+    let s:tlist_{fidx}_filetype = a:ftype
2031
+    let s:tlist_{fidx}_mtime = -1
2032
+    let s:tlist_{fidx}_start = 0
2033
+    let s:tlist_{fidx}_end = 0
2034
+    let s:tlist_{fidx}_valid = 0
2035
+    let s:tlist_{fidx}_visible = 0
2036
+    let s:tlist_{fidx}_tag_count = 0
2037
+    let s:tlist_{fidx}_menu_cmd = ''
2038
+
2039
+    " Initialize the tag type variables
2040
+    let i = 1
2041
+    while i <= s:tlist_{a:ftype}_count
2042
+        let ttype = s:tlist_{a:ftype}_{i}_name
2043
+        let s:tlist_{fidx}_{ttype} = ''
2044
+        let s:tlist_{fidx}_{ttype}_offset = 0
2045
+        let s:tlist_{fidx}_{ttype}_count = 0
2046
+        let i = i + 1
2047
+    endwhile
2048
+
2049
+    return fidx
2050
+endfunction
2051
+
2052
+" Tlist_Get_Tag_Type_By_Tag
2053
+" Return the tag type for the specified tag index
2054
+function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx)
2055
+    let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type'
2056
+
2057
+    " Already parsed and have the tag name
2058
+    if exists(ttype_var)
2059
+        return {ttype_var}
2060
+    endif
2061
+
2062
+    let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
2063
+    let {ttype_var} = s:Tlist_Extract_Tagtype(tag_line)
2064
+
2065
+    return {ttype_var}
2066
+endfunction
2067
+
2068
+" Tlist_Get_Tag_Prototype
2069
+function! s:Tlist_Get_Tag_Prototype(fidx, tidx)
2070
+    let tproto_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_proto'
2071
+
2072
+    " Already parsed and have the tag prototype
2073
+    if exists(tproto_var)
2074
+        return {tproto_var}
2075
+    endif
2076
+
2077
+    " Parse and extract the tag prototype
2078
+    let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
2079
+    let start = stridx(tag_line, '/^') + 2
2080
+    let end = stridx(tag_line, '/;"' . "\t")
2081
+    if tag_line[end - 1] == '$'
2082
+        let end = end -1
2083
+    endif
2084
+    let tag_proto = strpart(tag_line, start, end - start)
2085
+    let {tproto_var} = substitute(tag_proto, '\s*', '', '')
2086
+
2087
+    return {tproto_var}
2088
+endfunction
2089
+
2090
+" Tlist_Get_Tag_SearchPat
2091
+function! s:Tlist_Get_Tag_SearchPat(fidx, tidx)
2092
+    let tpat_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_searchpat'
2093
+
2094
+    " Already parsed and have the tag search pattern
2095
+    if exists(tpat_var)
2096
+        return {tpat_var}
2097
+    endif
2098
+
2099
+    " Parse and extract the tag search pattern
2100
+    let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
2101
+    let start = stridx(tag_line, '/^') + 2
2102
+    let end = stridx(tag_line, '/;"' . "\t")
2103
+    if tag_line[end - 1] == '$'
2104
+        let end = end -1
2105
+    endif
2106
+    let {tpat_var} = '\V\^' . strpart(tag_line, start, end - start) .
2107
+                        \ (tag_line[end] == '$' ? '\$' : '')
2108
+
2109
+    return {tpat_var}
2110
+endfunction
2111
+
2112
+" Tlist_Get_Tag_Linenum
2113
+" Return the tag line number, given the tag index
2114
+function! s:Tlist_Get_Tag_Linenum(fidx, tidx)
2115
+    let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum'
2116
+
2117
+    " Already parsed and have the tag line number
2118
+    if exists(tline_var)
2119
+        return {tline_var}
2120
+    endif
2121
+
2122
+    " Parse and extract the tag line number
2123
+    let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
2124
+    let start = strridx(tag_line, 'line:') + 5
2125
+    let end = strridx(tag_line, "\t")
2126
+    if end < start
2127
+        let {tline_var} = strpart(tag_line, start) + 0
2128
+    else
2129
+        let {tline_var} = strpart(tag_line, start, end - start) + 0
2130
+    endif
2131
+
2132
+    return {tline_var}
2133
+endfunction
2134
+
2135
+" Tlist_Parse_Tagline
2136
+" Parse a tag line from the ctags output. Separate the tag output based on the
2137
+" tag type and store it in the tag type variable.
2138
+" The format of each line in the ctags output is:
2139
+"
2140
+"     tag_name<TAB>file_name<TAB>ex_cmd;"<TAB>extension_fields
2141
+"
2142
+function! s:Tlist_Parse_Tagline(tag_line)
2143
+    if a:tag_line == ''
2144
+        " Skip empty lines
2145
+        return
2146
+    endif
2147
+
2148
+    " Extract the tag type
2149
+    let ttype = s:Tlist_Extract_Tagtype(a:tag_line)
2150
+
2151
+    " Make sure the tag type is a valid and supported one
2152
+    if ttype == '' || stridx(s:ctags_flags, ttype) == -1
2153
+        " Line is not in proper tags format or Tag type is not supported
2154
+        return
2155
+    endif
2156
+
2157
+    " Update the total tag count
2158
+    let s:tidx = s:tidx + 1
2159
+
2160
+    " The following variables are used to optimize this code.  Vim is slow in
2161
+    " using curly brace names. To reduce the amount of processing needed, the
2162
+    " curly brace variables are pre-processed here
2163
+    let fidx_tidx = 's:tlist_' . s:fidx . '_' . s:tidx
2164
+    let fidx_ttype = 's:tlist_' . s:fidx . '_' . ttype
2165
+
2166
+    " Update the count of this tag type
2167
+    let ttype_idx = {fidx_ttype}_count + 1
2168
+    let {fidx_ttype}_count = ttype_idx
2169
+
2170
+    " Store the ctags output for this tag
2171
+    let {fidx_tidx}_tag = a:tag_line
2172
+
2173
+    " Store the tag index and the tag type index (back pointers)
2174
+    let {fidx_ttype}_{ttype_idx} = s:tidx
2175
+    let {fidx_tidx}_ttype_idx = ttype_idx
2176
+
2177
+    " Extract the tag name
2178
+    let tag_name = strpart(a:tag_line, 0, stridx(a:tag_line, "\t"))
2179
+
2180
+    " Extract the tag scope/prototype
2181
+    if g:Tlist_Display_Prototype
2182
+        let ttxt = '    ' . s:Tlist_Get_Tag_Prototype(s:fidx, s:tidx)
2183
+    else
2184
+        let ttxt = '    ' . tag_name
2185
+
2186
+        " Add the tag scope, if it is available and is configured. Tag
2187
+        " scope is the last field after the 'line:<num>\t' field
2188
+        if g:Tlist_Display_Tag_Scope
2189
+            let tag_scope = s:Tlist_Extract_Tag_Scope(a:tag_line)
2190
+            if tag_scope != ''
2191
+                let ttxt = ttxt . ' [' . tag_scope . ']'
2192
+            endif
2193
+        endif
2194
+    endif
2195
+
2196
+    " Add this tag to the tag type variable
2197
+    let {fidx_ttype} = {fidx_ttype} . ttxt . "\n"
2198
+
2199
+    " Save the tag name
2200
+    let {fidx_tidx}_tag_name = tag_name
2201
+endfunction
2202
+
2203
+" Tlist_Process_File
2204
+" Get the list of tags defined in the specified file and store them
2205
+" in Vim variables. Returns the file index where the tags are stored.
2206
+function! s:Tlist_Process_File(filename, ftype)
2207
+    call s:Tlist_Log_Msg('Tlist_Process_File (' . a:filename . ', ' .
2208
+                \ a:ftype . ')')
2209
+    " Check whether this file is supported
2210
+    if s:Tlist_Skip_File(a:filename, a:ftype)
2211
+        return -1
2212
+    endif
2213
+
2214
+    " If the tag types for this filetype are not yet created, then create
2215
+    " them now
2216
+    let var = 's:tlist_' . a:ftype . '_count'
2217
+    if !exists(var)
2218
+        if s:Tlist_FileType_Init(a:ftype) == 0
2219
+            return -1
2220
+        endif
2221
+    endif
2222
+
2223
+    " If this file is already processed, then use the cached values
2224
+    let fidx = s:Tlist_Get_File_Index(a:filename)
2225
+    if fidx == -1
2226
+        " First time, this file is loaded
2227
+        let fidx = s:Tlist_Init_File(a:filename, a:ftype)
2228
+    else
2229
+        " File was previously processed. Discard the tag information
2230
+        call s:Tlist_Discard_TagInfo(fidx)
2231
+    endif
2232
+
2233
+    let s:tlist_{fidx}_valid = 1
2234
+
2235
+    " Exuberant ctags arguments to generate a tag list
2236
+    let ctags_args = ' -f - --format=2 --excmd=pattern --fields=nks '
2237
+
2238
+    " Form the ctags argument depending on the sort type
2239
+    if s:tlist_{fidx}_sort_type == 'name'
2240
+        let ctags_args = ctags_args . '--sort=yes'
2241
+    else
2242
+        let ctags_args = ctags_args . '--sort=no'
2243
+    endif
2244
+
2245
+    " Add the filetype specific arguments
2246
+    let ctags_args = ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args
2247
+
2248
+    " Ctags command to produce output with regexp for locating the tags
2249
+    let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args
2250
+    let ctags_cmd = ctags_cmd . ' "' . a:filename . '"'
2251
+
2252
+    if &shellxquote == '"'
2253
+        " Double-quotes within double-quotes will not work in the
2254
+        " command-line.If the 'shellxquote' option is set to double-quotes,
2255
+        " then escape the double-quotes in the ctags command-line.
2256
+        let ctags_cmd = escape(ctags_cmd, '"')
2257
+    endif
2258
+
2259
+    " In Windows 95, if not using cygwin, disable the 'shellslash'
2260
+    " option. Otherwise, this will cause problems when running the
2261
+    " ctags command.
2262
+    if has('win95') && !has('win32unix')
2263
+        let old_shellslash = &shellslash
2264
+        set noshellslash
2265
+    endif
2266
+
2267
+    if has('win32') && !has('win32unix') && !has('win95')
2268
+                \ && (&shell =~ 'cmd.exe')
2269
+        " Windows does not correctly deal with commands that have more than 1
2270
+        " set of double quotes.  It will strip them all resulting in:
2271
+        " 'C:\Program' is not recognized as an internal or external command
2272
+        " operable program or batch file.  To work around this, place the
2273
+        " command inside a batch file and call the batch file.
2274
+        " Do this only on Win2K, WinXP and above.
2275
+        " Contributed by: David Fishburn.
2276
+        let s:taglist_tempfile = fnamemodify(tempname(), ':h') .
2277
+                    \ '\taglist.cmd'
2278
+        exe 'redir! > ' . s:taglist_tempfile
2279
+        silent echo ctags_cmd
2280
+        redir END
2281
+
2282
+        call s:Tlist_Log_Msg('Cmd inside batch file: ' . ctags_cmd)
2283
+        let ctags_cmd = '"' . s:taglist_tempfile . '"'
2284
+    endif
2285
+
2286
+    call s:Tlist_Log_Msg('Cmd: ' . ctags_cmd)
2287
+
2288
+    " Run ctags and get the tag list
2289
+    let cmd_output = system(ctags_cmd)
2290
+
2291
+    " Restore the value of the 'shellslash' option.
2292
+    if has('win95') && !has('win32unix')
2293
+        let &shellslash = old_shellslash
2294
+    endif
2295
+
2296
+    if exists('s:taglist_tempfile')
2297
+        " Delete the temporary cmd file created on MS-Windows
2298
+        call delete(s:taglist_tempfile)
2299
+    endif
2300
+
2301
+    " Handle errors
2302
+    if v:shell_error
2303
+        let msg = "Taglist: Failed to generate tags for " . a:filename
2304
+        call s:Tlist_Warning_Msg(msg)
2305
+        if cmd_output != ''
2306
+            call s:Tlist_Warning_Msg(cmd_output)
2307
+        endif
2308
+        return fidx
2309
+    endif
2310
+
2311
+    " Store the modification time for the file
2312
+    let s:tlist_{fidx}_mtime = getftime(a:filename)
2313
+
2314
+    " No tags for current file
2315
+    if cmd_output == ''
2316
+        call s:Tlist_Log_Msg('No tags defined in ' . a:filename)
2317
+        return fidx
2318
+    endif
2319
+
2320
+    call s:Tlist_Log_Msg('Generated tags information for ' . a:filename)
2321
+
2322
+    if v:version > 601
2323
+        " The following script local variables are used by the
2324
+        " Tlist_Parse_Tagline() function.
2325
+        let s:ctags_flags = s:tlist_{a:ftype}_ctags_flags
2326
+        let s:fidx = fidx
2327
+        let s:tidx = 0
2328
+
2329
+        " Process the ctags output one line at a time.  The substitute()
2330
+        " command is used to parse the tag lines instead of using the
2331
+        " matchstr()/stridx()/strpart() functions for performance reason
2332
+        call substitute(cmd_output, "\\([^\n]\\+\\)\n",
2333
+                    \ '\=s:Tlist_Parse_Tagline(submatch(1))', 'g')
2334
+
2335
+        " Save the number of tags for this file
2336
+        let s:tlist_{fidx}_tag_count = s:tidx
2337
+
2338
+        " The following script local variables are no longer needed
2339
+        unlet! s:ctags_flags
2340
+        unlet! s:tidx
2341
+        unlet! s:fidx
2342
+    else
2343
+        " Due to a bug in Vim earlier than version 6.1,
2344
+        " we cannot use substitute() to parse the ctags output.
2345
+        " Instead the slow str*() functions are used
2346
+        let ctags_flags = s:tlist_{a:ftype}_ctags_flags
2347
+        let tidx = 0
2348
+
2349
+        while cmd_output != ''
2350
+            " Extract one line at a time
2351
+            let idx = stridx(cmd_output, "\n")
2352
+            let one_line = strpart(cmd_output, 0, idx)
2353
+            " Remove the line from the tags output
2354
+            let cmd_output = strpart(cmd_output, idx + 1)
2355
+
2356
+            if one_line == ''
2357
+                " Line is not in proper tags format
2358
+                continue
2359
+            endif
2360
+
2361
+            " Extract the tag type
2362
+            let ttype = s:Tlist_Extract_Tagtype(one_line)
2363
+
2364
+            " Make sure the tag type is a valid and supported one
2365
+            if ttype == '' || stridx(ctags_flags, ttype) == -1
2366
+                " Line is not in proper tags format or Tag type is not
2367
+                " supported
2368
+                continue
2369
+            endif
2370
+
2371
+            " Update the total tag count
2372
+            let tidx = tidx + 1
2373
+
2374
+            " The following variables are used to optimize this code.  Vim is
2375
+            " slow in using curly brace names. To reduce the amount of
2376
+            " processing needed, the curly brace variables are pre-processed
2377
+            " here
2378
+            let fidx_tidx = 's:tlist_' . fidx . '_' . tidx
2379
+            let fidx_ttype = 's:tlist_' . fidx . '_' . ttype
2380
+
2381
+            " Update the count of this tag type
2382
+            let ttype_idx = {fidx_ttype}_count + 1
2383
+            let {fidx_ttype}_count = ttype_idx
2384
+
2385
+            " Store the ctags output for this tag
2386
+            let {fidx_tidx}_tag = one_line
2387
+
2388
+            " Store the tag index and the tag type index (back pointers)
2389
+            let {fidx_ttype}_{ttype_idx} = tidx
2390
+            let {fidx_tidx}_ttype_idx = ttype_idx
2391
+
2392
+            " Extract the tag name
2393
+            let tag_name = strpart(one_line, 0, stridx(one_line, "\t"))
2394
+
2395
+            " Extract the tag scope/prototype
2396
+            if g:Tlist_Display_Prototype
2397
+                let ttxt = '    ' . s:Tlist_Get_Tag_Prototype(fidx, tidx)
2398
+            else
2399
+                let ttxt = '    ' . tag_name
2400
+
2401
+                " Add the tag scope, if it is available and is configured. Tag
2402
+                " scope is the last field after the 'line:<num>\t' field
2403
+                if g:Tlist_Display_Tag_Scope
2404
+                    let tag_scope = s:Tlist_Extract_Tag_Scope(one_line)
2405
+                    if tag_scope != ''
2406
+                        let ttxt = ttxt . ' [' . tag_scope . ']'
2407
+                    endif
2408
+                endif
2409
+            endif
2410
+
2411
+            " Add this tag to the tag type variable
2412
+            let {fidx_ttype} = {fidx_ttype} . ttxt . "\n"
2413
+
2414
+            " Save the tag name
2415
+            let {fidx_tidx}_tag_name = tag_name
2416
+        endwhile
2417
+
2418
+        " Save the number of tags for this file
2419
+        let s:tlist_{fidx}_tag_count = tidx
2420
+    endif
2421
+
2422
+    call s:Tlist_Log_Msg('Processed ' . s:tlist_{fidx}_tag_count . 
2423
+                \ ' tags in ' . a:filename)
2424
+
2425
+    return fidx
2426
+endfunction
2427
+
2428
+" Tlist_Update_File
2429
+" Update the tags for a file (if needed)
2430
+function! Tlist_Update_File(filename, ftype)
2431
+    call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')')
2432
+    " If the file doesn't support tag listing, skip it
2433
+    if s:Tlist_Skip_File(a:filename, a:ftype)
2434
+        return
2435
+    endif
2436
+
2437
+    " Convert the file name to a full path
2438
+    let fname = fnamemodify(a:filename, ':p')
2439
+
2440
+    " First check whether the file already exists
2441
+    let fidx = s:Tlist_Get_File_Index(fname)
2442
+
2443
+    if fidx != -1 && s:tlist_{fidx}_valid
2444
+        " File exists and the tags are valid
2445
+        " Check whether the file was modified after the last tags update
2446
+        " If it is modified, then update the tags
2447
+        if s:tlist_{fidx}_mtime == getftime(fname)
2448
+            return
2449
+        endif
2450
+    else
2451
+        " If the tags were removed previously based on a user request,
2452
+        " as we are going to update the tags (based on the user request),
2453
+        " remove the filename from the deleted list
2454
+        call s:Tlist_Update_Remove_List(fname, 0)
2455
+    endif
2456
+
2457
+    " If the taglist window is opened, update it
2458
+    let winnum = bufwinnr(g:TagList_title)
2459
+    if winnum == -1
2460
+        " Taglist window is not present. Just update the taglist
2461
+        " and return
2462
+        call s:Tlist_Process_File(fname, a:ftype)
2463
+    else
2464
+        if g:Tlist_Show_One_File && s:tlist_cur_file_idx != -1
2465
+            " If tags for only one file are displayed and we are not
2466
+            " updating the tags for that file, then no need to
2467
+            " refresh the taglist window. Otherwise, the taglist
2468
+            " window should be updated.
2469
+            if s:tlist_{s:tlist_cur_file_idx}_filename != fname
2470
+                call s:Tlist_Process_File(fname, a:ftype)
2471
+                return
2472
+            endif
2473
+        endif
2474
+
2475
+        " Save the current window number
2476
+        let save_winnr = winnr()
2477
+
2478
+        " Goto the taglist window
2479
+        call s:Tlist_Window_Goto_Window()
2480
+
2481
+        " Save the cursor position
2482
+        let save_line = line('.')
2483
+        let save_col = col('.')
2484
+
2485
+        " Update the taglist window
2486
+        call s:Tlist_Window_Refresh_File(fname, a:ftype)
2487
+
2488
+        " Restore the cursor position
2489
+        if v:version >= 601
2490
+            call cursor(save_line, save_col)
2491
+        else
2492
+            exe save_line
2493
+            exe 'normal! ' . save_col . '|'
2494
+        endif
2495
+
2496
+        if winnr() != save_winnr
2497
+            " Go back to the original window
2498
+            call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w')
2499
+        endif
2500
+    endif
2501
+
2502
+    " Update the taglist menu
2503
+    if g:Tlist_Show_Menu
2504
+        call s:Tlist_Menu_Update_File(1)
2505
+    endif
2506
+endfunction
2507
+
2508
+" Tlist_Window_Close
2509
+" Close the taglist window
2510
+function! s:Tlist_Window_Close()
2511
+    call s:Tlist_Log_Msg('Tlist_Window_Close()')
2512
+    " Make sure the taglist window exists
2513
+    let winnum = bufwinnr(g:TagList_title)
2514
+    if winnum == -1
2515
+        call s:Tlist_Warning_Msg('Error: Taglist window is not open')
2516
+        return
2517
+    endif
2518
+
2519
+    if winnr() == winnum
2520
+        " Already in the taglist window. Close it and return
2521
+        if winbufnr(2) != -1
2522
+            " If a window other than the taglist window is open,
2523
+            " then only close the taglist window.
2524
+            close
2525
+        endif
2526
+    else
2527
+        " Goto the taglist window, close it and then come back to the
2528
+        " original window
2529
+        let curbufnr = bufnr('%')
2530
+        exe winnum . 'wincmd w'
2531
+        close
2532
+        " Need to jump back to the original window only if we are not
2533
+        " already in that window
2534
+        let winnum = bufwinnr(curbufnr)
2535
+        if winnr() != winnum
2536
+            exe winnum . 'wincmd w'
2537
+        endif
2538
+    endif
2539
+endfunction
2540
+
2541
+" Tlist_Window_Mark_File_Window
2542
+" Mark the current window as the file window to use when jumping to a tag.
2543
+" Only if the current window is a non-plugin, non-preview and non-taglist
2544
+" window
2545
+function! s:Tlist_Window_Mark_File_Window()
2546
+    if getbufvar('%', '&buftype') == '' && !&previewwindow
2547
+        let w:tlist_file_window = "yes"
2548
+    endif
2549
+endfunction
2550
+
2551
+" Tlist_Window_Open
2552
+" Open and refresh the taglist window
2553
+function! s:Tlist_Window_Open()
2554
+    call s:Tlist_Log_Msg('Tlist_Window_Open()')
2555
+    " If the window is open, jump to it
2556
+    let winnum = bufwinnr(g:TagList_title)
2557
+    if winnum != -1
2558
+        " Jump to the existing window
2559
+        if winnr() != winnum
2560
+            exe winnum . 'wincmd w'
2561
+        endif
2562
+        return
2563
+    endif
2564
+
2565
+    if s:tlist_app_name == "winmanager"
2566
+        " Taglist plugin is no longer part of the winmanager app
2567
+        let s:tlist_app_name = "none"
2568
+    endif
2569
+
2570
+    " Get the filename and filetype for the specified buffer
2571
+    let curbuf_name = fnamemodify(bufname('%'), ':p')
2572
+    let curbuf_ftype = s:Tlist_Get_Buffer_Filetype('%')
2573
+    let cur_lnum = line('.')
2574
+
2575
+    " Mark the current window as the desired window to open a file when a tag
2576
+    " is selected.
2577
+    call s:Tlist_Window_Mark_File_Window()
2578
+
2579
+    " Open the taglist window
2580
+    call s:Tlist_Window_Create()
2581
+
2582
+    call s:Tlist_Window_Refresh()
2583
+
2584
+    if g:Tlist_Show_One_File
2585
+        " Add only the current buffer and file
2586
+        "
2587
+        " If the file doesn't support tag listing, skip it
2588
+        if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype)
2589
+            call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype)
2590
+        endif
2591
+    endif
2592
+
2593
+    if g:Tlist_File_Fold_Auto_Close
2594
+        " Open the fold for the current file, as all the folds in
2595
+        " the taglist window are closed
2596
+        let fidx = s:Tlist_Get_File_Index(curbuf_name)
2597
+        if fidx != -1
2598
+            exe "silent! " . s:tlist_{fidx}_start . "," .
2599
+                        \ s:tlist_{fidx}_end . "foldopen!"
2600
+        endif
2601
+    endif
2602
+
2603
+    " Highlight the current tag
2604
+    call s:Tlist_Window_Highlight_Tag(curbuf_name, cur_lnum, 1, 1)
2605
+endfunction
2606
+
2607
+" Tlist_Window_Toggle()
2608
+" Open or close a taglist window
2609
+function! s:Tlist_Window_Toggle()
2610
+    call s:Tlist_Log_Msg('Tlist_Window_Toggle()')
2611
+    " If taglist window is open then close it.
2612
+    let winnum = bufwinnr(g:TagList_title)
2613
+    if winnum != -1
2614
+        call s:Tlist_Window_Close()
2615
+        return
2616
+    endif
2617
+
2618
+    call s:Tlist_Window_Open()
2619
+
2620
+    " Go back to the original window, if Tlist_GainFocus_On_ToggleOpen is not
2621
+    " set
2622
+    if !g:Tlist_GainFocus_On_ToggleOpen
2623
+        call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
2624
+    endif
2625
+
2626
+    " Update the taglist menu
2627
+    if g:Tlist_Show_Menu
2628
+        call s:Tlist_Menu_Update_File(0)
2629
+    endif
2630
+endfunction
2631
+
2632
+" Tlist_Process_Filelist
2633
+" Process multiple files. Each filename is separated by "\n"
2634
+" Returns the number of processed files
2635
+function! s:Tlist_Process_Filelist(file_names)
2636
+    let flist = a:file_names
2637
+
2638
+    " Enable lazy screen updates
2639
+    let old_lazyredraw = &lazyredraw
2640
+    set lazyredraw
2641
+
2642
+    " Keep track of the number of processed files
2643
+    let fcnt = 0
2644
+
2645
+    " Process one file at a time
2646
+    while flist != ''
2647
+        let nl_idx = stridx(flist, "\n")
2648
+        let one_file = strpart(flist, 0, nl_idx)
2649
+
2650
+        " Remove the filename from the list
2651
+        let flist = strpart(flist, nl_idx + 1)
2652
+
2653
+        if one_file == ''
2654
+            continue
2655
+        endif
2656
+
2657
+        " Skip directories
2658
+        if isdirectory(one_file)
2659
+            continue
2660
+        endif
2661
+
2662
+        let ftype = s:Tlist_Detect_Filetype(one_file)
2663
+
2664
+        echon "\r                                                              "
2665
+        echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t')
2666
+
2667
+        let fcnt = fcnt + 1
2668
+
2669
+        call Tlist_Update_File(one_file, ftype)
2670
+    endwhile
2671
+
2672
+    " Clear the displayed informational messages
2673
+    echon "\r                                                            "
2674
+
2675
+    " Restore the previous state
2676
+    let &lazyredraw = old_lazyredraw
2677
+
2678
+    return fcnt
2679
+endfunction
2680
+
2681
+" Tlist_Process_Dir
2682
+" Process the files in a directory matching the specified pattern
2683
+function! s:Tlist_Process_Dir(dir_name, pat)
2684
+    let flist = glob(a:dir_name . '/' . a:pat) . "\n"
2685
+
2686
+    let fcnt = s:Tlist_Process_Filelist(flist)
2687
+
2688
+    let len = strlen(a:dir_name)
2689
+    if a:dir_name[len - 1] == '\' || a:dir_name[len - 1] == '/'
2690
+        let glob_expr = a:dir_name . '*'
2691
+    else
2692
+        let glob_expr = a:dir_name . '/*'
2693
+    endif
2694
+    let all_files = glob(glob_expr) . "\n"
2695
+
2696
+    while all_files != ''
2697
+        let nl_idx = stridx(all_files, "\n")
2698
+        let one_file = strpart(all_files, 0, nl_idx)
2699
+
2700
+        let all_files = strpart(all_files, nl_idx + 1)
2701
+        if one_file == ''
2702
+            continue
2703
+        endif
2704
+
2705
+        " Skip non-directory names
2706
+        if !isdirectory(one_file)
2707
+            continue
2708
+        endif
2709
+
2710
+        echon "\r                                                              "
2711
+        echon "\rProcessing files in directory " . fnamemodify(one_file, ':t')
2712
+        let fcnt = fcnt + s:Tlist_Process_Dir(one_file, a:pat)
2713
+    endwhile
2714
+
2715
+    return fcnt
2716
+endfunction
2717
+
2718
+" Tlist_Add_Files_Recursive
2719
+" Add files recursively from a directory
2720
+function! s:Tlist_Add_Files_Recursive(dir, ...)
2721
+    let dir_name = fnamemodify(a:dir, ':p')
2722
+    if !isdirectory(dir_name)
2723
+        call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory')
2724
+        return
2725
+    endif
2726
+
2727
+    if a:0 == 1
2728
+        " User specified file pattern
2729
+        let pat = a:1
2730
+    else
2731
+        " Default file pattern
2732
+        let pat = '*'
2733
+    endif
2734
+
2735
+    echon "\r                                                              "
2736
+    echon "\rProcessing files in directory " . fnamemodify(dir_name, ':t')
2737
+    let fcnt = s:Tlist_Process_Dir(dir_name, pat)
2738
+
2739
+    echon "\rAdded " . fcnt . " files to the taglist"
2740
+endfunction
2741
+
2742
+" Tlist_Add_Files
2743
+" Add the specified list of files to the taglist
2744
+function! s:Tlist_Add_Files(...)
2745
+    let flist = ''
2746
+    let i = 1
2747
+
2748
+    " Get all the files matching the file patterns supplied as argument
2749
+    while i <= a:0
2750
+        let flist = flist . glob(a:{i}) . "\n"
2751
+        let i = i + 1
2752
+    endwhile
2753
+
2754
+    if flist == ''
2755
+        call s:Tlist_Warning_Msg('Error: No matching files are found')
2756
+        return
2757
+    endif
2758
+
2759
+    let fcnt = s:Tlist_Process_Filelist(flist)
2760
+    echon "\rAdded " . fcnt . " files to the taglist"
2761
+endfunction
2762
+
2763
+" Tlist_Extract_Tagtype
2764
+" Extract the tag type from the tag text
2765
+function! s:Tlist_Extract_Tagtype(tag_line)
2766
+    " The tag type is after the tag prototype field. The prototype field
2767
+    " ends with the /;"\t string. We add 4 at the end to skip the characters
2768
+    " in this special string..
2769
+    let start = strridx(a:tag_line, '/;"' . "\t") + 4
2770
+    let end = strridx(a:tag_line, 'line:') - 1
2771
+    let ttype = strpart(a:tag_line, start, end - start)
2772
+
2773
+    return ttype
2774
+endfunction
2775
+
2776
+" Tlist_Extract_Tag_Scope
2777
+" Extract the tag scope from the tag text
2778
+function! s:Tlist_Extract_Tag_Scope(tag_line)
2779
+    let start = strridx(a:tag_line, 'line:')
2780
+    let end = strridx(a:tag_line, "\t")
2781
+    if end <= start
2782
+        return ''
2783
+    endif
2784
+
2785
+    let tag_scope = strpart(a:tag_line, end + 1)
2786
+    let tag_scope = strpart(tag_scope, stridx(tag_scope, ':') + 1)
2787
+
2788
+    return tag_scope
2789
+endfunction
2790
+
2791
+" Tlist_Refresh()
2792
+" Refresh the taglist
2793
+function! s:Tlist_Refresh()
2794
+    call s:Tlist_Log_Msg('Tlist_Refresh (Skip_Refresh = ' .
2795
+                \ s:Tlist_Skip_Refresh . ', ' . bufname('%') . ')')
2796
+    " If we are entering the buffer from one of the taglist functions, then
2797
+    " no need to refresh the taglist window again.
2798
+    if s:Tlist_Skip_Refresh
2799
+        " We still need to update the taglist menu
2800
+        if g:Tlist_Show_Menu
2801
+            call s:Tlist_Menu_Update_File(0)
2802
+        endif
2803
+        return
2804
+    endif
2805
+
2806
+    " If part of the winmanager plugin and not configured to process
2807
+    " tags always and not configured to display the tags menu, then return
2808
+    if (s:tlist_app_name == 'winmanager') && !g:Tlist_Process_File_Always
2809
+                \ && !g:Tlist_Show_Menu
2810
+        return
2811
+    endif
2812
+
2813
+    " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help
2814
+    if &buftype != ''
2815
+        return
2816
+    endif
2817
+
2818
+    let filename = fnamemodify(bufname('%'), ':p')
2819
+    let ftype = s:Tlist_Get_Buffer_Filetype('%')
2820
+
2821
+    " If the file doesn't support tag listing, skip it
2822
+    if s:Tlist_Skip_File(filename, ftype)
2823
+        return
2824
+    endif
2825
+
2826
+    let tlist_win = bufwinnr(g:TagList_title)
2827
+
2828
+    " If the taglist window is not opened and not configured to process
2829
+    " tags always and not displaying the tags menu, then return
2830
+    if tlist_win == -1 && !g:Tlist_Process_File_Always && !g:Tlist_Show_Menu
2831
+        return
2832
+    endif
2833
+
2834
+    let fidx = s:Tlist_Get_File_Index(filename)
2835
+    if fidx == -1
2836
+        " Check whether this file is removed based on user request
2837
+        " If it is, then don't display the tags for this file
2838
+        if s:Tlist_User_Removed_File(filename)
2839
+            return
2840
+        endif
2841
+
2842
+        " If the taglist should not be auto updated, then return
2843
+        if !g:Tlist_Auto_Update
2844
+            return
2845
+        endif
2846
+    endif
2847
+
2848
+    let cur_lnum = line('.')
2849
+
2850
+    if fidx == -1
2851
+        " Update the tags for the file
2852
+        let fidx = s:Tlist_Process_File(filename, ftype)
2853
+    else
2854
+        let mtime = getftime(filename)
2855
+        if s:tlist_{fidx}_mtime != mtime
2856
+            " Invalidate the tags listed for this file
2857
+            let s:tlist_{fidx}_valid = 0
2858
+
2859
+            " Update the taglist and the window
2860
+            call Tlist_Update_File(filename, ftype)
2861
+
2862
+            " Store the new file modification time
2863
+            let s:tlist_{fidx}_mtime = mtime
2864
+        endif
2865
+    endif
2866
+
2867
+    " Update the taglist window
2868
+    if tlist_win != -1
2869
+        " Disable screen updates
2870
+        let old_lazyredraw = &lazyredraw
2871
+        set nolazyredraw
2872
+
2873
+        " Save the current window number
2874
+        let save_winnr = winnr()
2875
+
2876
+        " Goto the taglist window
2877
+        call s:Tlist_Window_Goto_Window()
2878
+
2879
+        if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter
2880
+            " Save the cursor position
2881
+            let save_line = line('.')
2882
+            let save_col = col('.')
2883
+        endif
2884
+
2885
+        " Update the taglist window
2886
+        call s:Tlist_Window_Refresh_File(filename, ftype)
2887
+
2888
+        " Open the fold for the file
2889
+        exe "silent! " . s:tlist_{fidx}_start . "," .
2890
+                    \ s:tlist_{fidx}_end . "foldopen!"
2891
+
2892
+        if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag
2893
+            if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx
2894
+                " If displaying tags for only one file in the taglist
2895
+                " window and about to display the tags for a new file,
2896
+                " then center the current tag line for the new file
2897
+                let center_tag_line = 1
2898
+            else
2899
+                let center_tag_line = 0
2900
+            endif
2901
+
2902
+            " Highlight the current tag
2903
+            call s:Tlist_Window_Highlight_Tag(filename, cur_lnum, 1, center_tag_line)
2904
+        else
2905
+            " Restore the cursor position
2906
+            if v:version >= 601
2907
+                call cursor(save_line, save_col)
2908
+            else
2909
+                exe save_line
2910
+                exe 'normal! ' . save_col . '|'
2911
+            endif
2912
+        endif
2913
+
2914
+        " Jump back to the original window
2915
+        if save_winnr != winnr()
2916
+            call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w')
2917
+        endif
2918
+
2919
+        " Restore screen updates
2920
+        let &lazyredraw = old_lazyredraw
2921
+    endif
2922
+
2923
+    " Update the taglist menu
2924
+    if g:Tlist_Show_Menu
2925
+        call s:Tlist_Menu_Update_File(0)
2926
+    endif
2927
+endfunction
2928
+
2929
+" Tlist_Change_Sort()
2930
+" Change the sort order of the tag listing
2931
+" caller == 'cmd', command used in the taglist window
2932
+" caller == 'menu', taglist menu
2933
+" action == 'toggle', toggle sort from name to order and vice versa
2934
+" action == 'set', set the sort order to sort_type
2935
+function! s:Tlist_Change_Sort(caller, action, sort_type)
2936
+    call s:Tlist_Log_Msg('Tlist_Change_Sort (caller = ' . a:caller .
2937
+            \ ', action = ' . a:action . ', sort_type = ' . a:sort_type . ')')
2938
+    if a:caller == 'cmd'
2939
+        let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
2940
+        if fidx == -1
2941
+            return
2942
+        endif
2943
+
2944
+        " Remove the previous highlighting
2945
+        match none
2946
+    elseif a:caller == 'menu'
2947
+        let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
2948
+        if fidx == -1
2949
+            return
2950
+        endif
2951
+    endif
2952
+
2953
+    if a:action == 'toggle'
2954
+        let sort_type = s:tlist_{fidx}_sort_type
2955
+
2956
+        " Toggle the sort order from 'name' to 'order' and vice versa
2957
+        if sort_type == 'name'
2958
+            let s:tlist_{fidx}_sort_type = 'order'
2959
+        else
2960
+            let s:tlist_{fidx}_sort_type = 'name'
2961
+        endif
2962
+    else
2963
+        let s:tlist_{fidx}_sort_type = a:sort_type
2964
+    endif
2965
+
2966
+    " Invalidate the tags listed for this file
2967
+    let s:tlist_{fidx}_valid = 0
2968
+
2969
+    if a:caller  == 'cmd'
2970
+        " Save the current line for later restoration
2971
+        let curline = '\V\^' . getline('.') . '\$'
2972
+
2973
+        call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename,
2974
+                    \   s:tlist_{fidx}_filetype)
2975
+
2976
+        exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!'
2977
+
2978
+        " Go back to the cursor line before the tag list is sorted
2979
+        call search(curline, 'w')
2980
+
2981
+        call s:Tlist_Menu_Update_File(1)
2982
+    else
2983
+        call s:Tlist_Menu_Remove_File()
2984
+
2985
+        call s:Tlist_Refresh()
2986
+    endif
2987
+endfunction
2988
+
2989
+" Tlist_Update_Current_File()
2990
+" Update taglist for the current buffer by regenerating the tag list
2991
+" Contributed by WEN Guopeng.
2992
+function! s:Tlist_Update_Current_File()
2993
+    call s:Tlist_Log_Msg('Tlist_Update_Current_File()')
2994
+    if winnr() == bufwinnr(g:TagList_title)
2995
+        " In the taglist window. Update the current file
2996
+        call s:Tlist_Window_Update_File()
2997
+    else
2998
+        " Not in the taglist window. Update the current buffer
2999
+        let filename = fnamemodify(bufname('%'), ':p')
3000
+        let fidx = s:Tlist_Get_File_Index(filename)
3001
+        if fidx != -1
3002
+            let s:tlist_{fidx}_valid = 0
3003
+        endif
3004
+        let ft = s:Tlist_Get_Buffer_Filetype('%')
3005
+        call Tlist_Update_File(filename, ft)
3006
+    endif
3007
+endfunction
3008
+
3009
+" Tlist_Window_Update_File()
3010
+" Update the tags displayed in the taglist window
3011
+function! s:Tlist_Window_Update_File()
3012
+    call s:Tlist_Log_Msg('Tlist_Window_Update_File()')
3013
+    let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
3014
+    if fidx == -1
3015
+        return
3016
+    endif
3017
+
3018
+    " Remove the previous highlighting
3019
+    match none
3020
+
3021
+    " Save the current line for later restoration
3022
+    let curline = '\V\^' . getline('.') . '\$'
3023
+
3024
+    let s:tlist_{fidx}_valid = 0
3025
+
3026
+    " Update the taglist window
3027
+    call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename,
3028
+                \ s:tlist_{fidx}_filetype)
3029
+
3030
+    exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!'
3031
+
3032
+    " Go back to the tag line before the list is updated
3033
+    call search(curline, 'w')
3034
+endfunction
3035
+
3036
+" Tlist_Window_Get_Tag_Type_By_Linenum()
3037
+" Return the tag type index for the specified line in the taglist window
3038
+function! s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum)
3039
+    let ftype = s:tlist_{a:fidx}_filetype
3040
+
3041
+    " Determine to which tag type the current line number belongs to using the
3042
+    " tag type start line number and the number of tags in a tag type
3043
+    let i = 1
3044
+    while i <= s:tlist_{ftype}_count
3045
+        let ttype = s:tlist_{ftype}_{i}_name
3046
+        let start_lnum =
3047
+                    \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset
3048
+        let end =  start_lnum + s:tlist_{a:fidx}_{ttype}_count
3049
+        if a:lnum >= start_lnum && a:lnum <= end
3050
+            break
3051
+        endif
3052
+        let i = i + 1
3053
+    endwhile
3054
+
3055
+    " Current line doesn't belong to any of the displayed tag types
3056
+    if i > s:tlist_{ftype}_count
3057
+        return ''
3058
+    endif
3059
+
3060
+    return ttype
3061
+endfunction
3062
+
3063
+" Tlist_Window_Get_Tag_Index()
3064
+" Return the tag index for the specified line in the taglist window
3065
+function! s:Tlist_Window_Get_Tag_Index(fidx, lnum)
3066
+    let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(a:fidx, a:lnum)
3067
+
3068
+    " Current line doesn't belong to any of the displayed tag types
3069
+    if ttype == ''
3070
+        return 0
3071
+    endif
3072
+
3073
+    " Compute the index into the displayed tags for the tag type
3074
+    let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset
3075
+    let tidx = a:lnum - ttype_lnum
3076
+    if tidx == 0
3077
+        return 0
3078
+    endif
3079
+
3080
+    " Get the corresponding tag line and return it
3081
+    return s:tlist_{a:fidx}_{ttype}_{tidx}
3082
+endfunction
3083
+
3084
+" Tlist_Window_Highlight_Line
3085
+" Highlight the current line
3086
+function! s:Tlist_Window_Highlight_Line()
3087
+    " Clear previously selected name
3088
+    match none
3089
+
3090
+    " Highlight the current line
3091
+    if g:Tlist_Display_Prototype == 0
3092
+        let pat = '/\%' . line('.') . 'l\s\+\zs.*/'
3093
+    else
3094
+        let pat = '/\%' . line('.') . 'l.*/'
3095
+    endif
3096
+
3097
+    exe 'match TagListTagName ' . pat
3098
+endfunction
3099
+
3100
+" Tlist_Window_Open_File
3101
+" Open the specified file in either a new window or an existing window
3102
+" and place the cursor at the specified tag pattern
3103
+function! s:Tlist_Window_Open_File(win_ctrl, filename, tagpat)
3104
+    call s:Tlist_Log_Msg('Tlist_Window_Open_File (' . a:filename . ',' .
3105
+                \ a:win_ctrl . ')')
3106
+    let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh
3107
+    let s:Tlist_Skip_Refresh = 1
3108
+
3109
+    if s:tlist_app_name == "winmanager"
3110
+        " Let the winmanager edit the file
3111
+        call WinManagerFileEdit(a:filename, a:win_ctrl == 'newwin')
3112
+    else
3113
+
3114
+    if a:win_ctrl == 'newtab'
3115
+        " Create a new tab
3116
+        exe 'tabnew ' . escape(a:filename, ' ')
3117
+        " Open the taglist window in the new tab
3118
+        call s:Tlist_Window_Open()
3119
+    endif
3120
+
3121
+    if a:win_ctrl == 'checktab'
3122
+        " Check whether the file is present in any of the tabs.
3123
+        " If the file is present in the current tab, then use the
3124
+        " current tab.
3125
+        if bufwinnr(a:filename) != -1
3126
+            let file_present_in_tab = 1
3127
+            let i = tabpagenr()
3128
+        else
3129
+            let i = 1
3130
+            let bnum = bufnr(a:filename)
3131
+            let file_present_in_tab = 0
3132
+            while i <= tabpagenr('$')
3133
+                if index(tabpagebuflist(i), bnum) != -1
3134
+                    let file_present_in_tab = 1
3135
+                    break
3136
+                endif
3137
+                let i += 1
3138
+            endwhile
3139
+        endif
3140
+
3141
+        if file_present_in_tab
3142
+            " Goto the tab containing the file
3143
+            exe 'tabnext ' . i
3144
+        else
3145
+            " Open a new tab
3146
+            exe 'tabnew ' . escape(a:filename, ' ')
3147
+
3148
+            " Open the taglist window
3149
+            call s:Tlist_Window_Open()
3150
+        endif
3151
+    endif
3152
+
3153
+    let winnum = -1
3154
+    if a:win_ctrl == 'prevwin'
3155
+        " Open the file in the previous window, if it is usable
3156
+        let cur_win = winnr()
3157
+        wincmd p
3158
+        if &buftype == '' && !&previewwindow
3159
+            exe "edit " . escape(a:filename, ' ')
3160
+            let winnum = winnr()
3161
+        else
3162
+            " Previous window is not usable
3163
+            exe cur_win . 'wincmd w'
3164
+        endif
3165
+    endif
3166
+
3167
+    " Goto the window containing the file.  If the window is not there, open a
3168
+    " new window
3169
+    if winnum == -1
3170
+        let winnum = bufwinnr(a:filename)
3171
+    endif
3172
+
3173
+    if winnum == -1
3174
+        " Locate the previously used window for opening a file
3175
+        let fwin_num = 0
3176
+        let first_usable_win = 0
3177
+
3178
+        let i = 1
3179
+        let bnum = winbufnr(i)
3180
+        while bnum != -1
3181
+            if getwinvar(i, 'tlist_file_window') == 'yes'
3182
+                let fwin_num = i
3183
+                break
3184
+            endif
3185
+            if first_usable_win == 0 &&
3186
+                        \ getbufvar(bnum, '&buftype') == '' &&
3187
+                        \ !getwinvar(i, '&previewwindow')
3188
+                " First non-taglist, non-plugin and non-preview window
3189
+                let first_usable_win = i
3190
+            endif
3191
+            let i = i + 1
3192
+            let bnum = winbufnr(i)
3193
+        endwhile
3194
+
3195
+        " If a previously used window is not found, then use the first
3196
+        " non-taglist window
3197
+        if fwin_num == 0
3198
+            let fwin_num = first_usable_win
3199
+        endif
3200
+
3201
+        if fwin_num != 0
3202
+            " Jump to the file window
3203
+            exe fwin_num . "wincmd w"
3204
+
3205
+            " If the user asked to jump to the tag in a new window, then split
3206
+            " the existing window into two.
3207
+            if a:win_ctrl == 'newwin'
3208
+                split
3209
+            endif
3210
+            exe "edit " . escape(a:filename, ' ')
3211
+        else
3212
+            " Open a new window
3213
+            if g:Tlist_Use_Horiz_Window
3214
+                exe 'leftabove split ' . escape(a:filename, ' ')
3215
+            else
3216
+                if winbufnr(2) == -1
3217
+                    " Only the taglist window is present
3218
+                    if g:Tlist_Use_Right_Window
3219
+                        exe 'leftabove vertical split ' .
3220
+                                    \ escape(a:filename, ' ')
3221
+                    else
3222
+                        exe 'rightbelow vertical split ' .
3223
+                                    \ escape(a:filename, ' ')
3224
+                    endif
3225
+
3226
+                    " Go to the taglist window to change the window size to
3227
+                    " the user configured value
3228
+                    call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
3229
+                    if g:Tlist_Use_Horiz_Window
3230
+                        exe 'resize ' . g:Tlist_WinHeight
3231
+                    else
3232
+                        exe 'vertical resize ' . g:Tlist_WinWidth
3233
+                    endif
3234
+                    " Go back to the file window
3235
+                    call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
3236
+                else
3237
+                    " A plugin or help window is also present
3238
+                    wincmd w
3239
+                    exe 'leftabove split ' . escape(a:filename, ' ')
3240
+                endif
3241
+            endif
3242
+        endif
3243
+        " Mark the window, so that it can be reused.
3244
+        call s:Tlist_Window_Mark_File_Window()
3245
+    else
3246
+        if v:version >= 700
3247
+            " If the file is opened in more than one window, then check
3248
+            " whether the last accessed window has the selected file.
3249
+            " If it does, then use that window.
3250
+            let lastwin_bufnum = winbufnr(winnr('#'))
3251
+            if bufnr(a:filename) == lastwin_bufnum
3252
+                let winnum = winnr('#')
3253
+            endif
3254
+        endif
3255
+        exe winnum . 'wincmd w'
3256
+
3257
+        " If the user asked to jump to the tag in a new window, then split the
3258
+        " existing window into two.
3259
+        if a:win_ctrl == 'newwin'
3260
+            split
3261
+        endif
3262
+    endif
3263
+    endif
3264
+
3265
+    " Jump to the tag
3266
+    if a:tagpat != ''
3267
+        " Add the current cursor position to the jump list, so that user can
3268
+        " jump back using the ' and ` marks.
3269
+        mark '
3270
+        silent call search(a:tagpat, 'w')
3271
+
3272
+        " Bring the line to the middle of the window
3273
+        normal! z.
3274
+
3275
+        " If the line is inside a fold, open the fold
3276
+        if foldclosed('.') != -1
3277
+            .foldopen
3278
+        endif
3279
+    endif
3280
+
3281
+    " If the user selects to preview the tag then jump back to the
3282
+    " taglist window
3283
+    if a:win_ctrl == 'preview'
3284
+        " Go back to the taglist window
3285
+        let winnum = bufwinnr(g:TagList_title)
3286
+        exe winnum . 'wincmd w'
3287
+    else
3288
+        " If the user has selected to close the taglist window, when a
3289
+        " tag is selected, close the taglist  window
3290
+        if g:Tlist_Close_On_Select
3291
+            call s:Tlist_Window_Goto_Window()
3292
+            close
3293
+
3294
+            " Go back to the window displaying the selected file
3295
+            let wnum = bufwinnr(a:filename)
3296
+            if wnum != -1 && wnum != winnr()
3297
+                call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w')
3298
+            endif
3299
+        endif
3300
+    endif
3301
+
3302
+    let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh
3303
+endfunction
3304
+
3305
+" Tlist_Window_Jump_To_Tag()
3306
+" Jump to the location of the current tag
3307
+" win_ctrl == useopen - Reuse the existing file window
3308
+" win_ctrl == newwin - Open a new window
3309
+" win_ctrl == preview - Preview the tag
3310
+" win_ctrl == prevwin - Open in previous window
3311
+" win_ctrl == newtab - Open in new tab
3312
+function! s:Tlist_Window_Jump_To_Tag(win_ctrl)
3313
+    call s:Tlist_Log_Msg('Tlist_Window_Jump_To_Tag(' . a:win_ctrl . ')')
3314
+    " Do not process comment lines and empty lines
3315
+    let curline = getline('.')
3316
+    if curline =~ '^\s*$' || curline[0] == '"'
3317
+        return
3318
+    endif
3319
+
3320
+    " If inside a closed fold, then use the first line of the fold
3321
+    " and jump to the file.
3322
+    let lnum = foldclosed('.')
3323
+    if lnum == -1
3324
+        " Jump to the selected tag or file
3325
+        let lnum = line('.')
3326
+    else
3327
+        " Open the closed fold
3328
+        .foldopen!
3329
+    endif
3330
+
3331
+    let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
3332
+    if fidx == -1
3333
+        return
3334
+    endif
3335
+
3336
+    " Get the tag output for the current tag
3337
+    let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum)
3338
+    if tidx != 0
3339
+        let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx)
3340
+
3341
+        " Highlight the tagline
3342
+        call s:Tlist_Window_Highlight_Line()
3343
+    else
3344
+        " Selected a line which is not a tag name. Just edit the file
3345
+        let tagpat = ''
3346
+    endif
3347
+
3348
+    call s:Tlist_Window_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat)
3349
+endfunction
3350
+
3351
+" Tlist_Window_Show_Info()
3352
+" Display information about the entry under the cursor
3353
+function! s:Tlist_Window_Show_Info()
3354
+    call s:Tlist_Log_Msg('Tlist_Window_Show_Info()')
3355
+
3356
+    " Clear the previously displayed line
3357
+    echo
3358
+
3359
+    " Do not process comment lines and empty lines
3360
+    let curline = getline('.')
3361
+    if curline =~ '^\s*$' || curline[0] == '"'
3362
+        return
3363
+    endif
3364
+
3365
+    " If inside a fold, then don't display the prototype
3366
+    if foldclosed('.') != -1
3367
+        return
3368
+    endif
3369
+
3370
+    let lnum = line('.')
3371
+
3372
+    " Get the file index
3373
+    let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
3374
+    if fidx == -1
3375
+        return
3376
+    endif
3377
+
3378
+    if lnum == s:tlist_{fidx}_start
3379
+        " Cursor is on a file name
3380
+        let fname = s:tlist_{fidx}_filename
3381
+        if strlen(fname) > 50
3382
+            let fname = fnamemodify(fname, ':t')
3383
+        endif
3384
+        echo fname . ', Filetype=' . s:tlist_{fidx}_filetype .
3385
+                    \  ', Tag count=' . s:tlist_{fidx}_tag_count
3386
+        return
3387
+    endif
3388
+
3389
+    " Get the tag output line for the current tag
3390
+    let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum)
3391
+    if tidx == 0
3392
+        " Cursor is on a tag type
3393
+        let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum)
3394
+        if ttype == ''
3395
+            return
3396
+        endif
3397
+
3398
+        let ttype_name = ''
3399
+
3400
+        let ftype = s:tlist_{fidx}_filetype
3401
+        let i = 1
3402
+        while i <= s:tlist_{ftype}_count
3403
+            if ttype == s:tlist_{ftype}_{i}_name
3404
+                let ttype_name = s:tlist_{ftype}_{i}_fullname
3405
+                break
3406
+            endif
3407
+            let i = i + 1
3408
+        endwhile
3409
+
3410
+        echo 'Tag type=' . ttype_name .
3411
+                    \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count
3412
+        return
3413
+    endif
3414
+
3415
+    " Get the tag search pattern and display it
3416
+    echo s:Tlist_Get_Tag_Prototype(fidx, tidx)
3417
+endfunction
3418
+
3419
+" Tlist_Find_Nearest_Tag_Idx
3420
+" Find the tag idx nearest to the supplied line number
3421
+" Returns -1, if a tag couldn't be found for the specified line number
3422
+function! s:Tlist_Find_Nearest_Tag_Idx(fidx, linenum)
3423
+    let sort_type = s:tlist_{a:fidx}_sort_type
3424
+
3425
+    let left = 1
3426
+    let right = s:tlist_{a:fidx}_tag_count
3427
+
3428
+    if sort_type == 'order'
3429
+        " Tags sorted by order, use a binary search.
3430
+        " The idea behind this function is taken from the ctags.vim script (by
3431
+        " Alexey Marinichev) available at the Vim online website.
3432
+
3433
+        " If the current line is the less than the first tag, then no need to
3434
+        " search
3435
+        let first_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, 1)
3436
+
3437
+        if a:linenum < first_lnum
3438
+            return -1
3439
+        endif
3440
+
3441
+        while left < right
3442
+            let middle = (right + left + 1) / 2
3443
+            let middle_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, middle)
3444
+
3445
+            if middle_lnum == a:linenum
3446
+                let left = middle
3447
+                break
3448
+            endif
3449
+
3450
+            if middle_lnum > a:linenum
3451
+                let right = middle - 1
3452
+            else
3453
+                let left = middle
3454
+            endif
3455
+        endwhile
3456
+    else
3457
+        " Tags sorted by name, use a linear search. (contributed by Dave
3458
+        " Eggum).
3459
+        " Look for a tag with a line number less than or equal to the supplied
3460
+        " line number. If multiple tags are found, then use the tag with the
3461
+        " line number closest to the supplied line number. IOW, use the tag
3462
+        " with the highest line number.
3463
+        let closest_lnum = 0
3464
+        let final_left = 0
3465
+        while left <= right
3466
+            let lnum = s:Tlist_Get_Tag_Linenum(a:fidx, left)
3467
+
3468
+            if lnum < a:linenum && lnum > closest_lnum
3469
+                let closest_lnum = lnum
3470
+                let final_left = left
3471
+            elseif lnum == a:linenum
3472
+                let closest_lnum = lnum
3473
+                let final_left = left
3474
+                break
3475
+            else
3476
+                let left = left + 1
3477
+            endif
3478
+        endwhile
3479
+        if closest_lnum == 0
3480
+            return -1
3481
+        endif
3482
+        if left >= right
3483
+            let left = final_left
3484
+        endif
3485
+    endif
3486
+
3487
+    return left
3488
+endfunction
3489
+
3490
+" Tlist_Window_Highlight_Tag()
3491
+" Highlight the current tag
3492
+" cntx == 1, Called by the taglist plugin itself
3493
+" cntx == 2, Forced by the user through the TlistHighlightTag command
3494
+" center = 1, move the tag line to the center of the taglist window
3495
+function! s:Tlist_Window_Highlight_Tag(filename, cur_lnum, cntx, center)
3496
+    " Highlight the current tag only if the user configured the
3497
+    " taglist plugin to do so or if the user explictly invoked the
3498
+    " command to highlight the current tag.
3499
+    if !g:Tlist_Auto_Highlight_Tag && a:cntx == 1
3500
+        return
3501
+    endif
3502
+
3503
+    if a:filename == ''
3504
+        return
3505
+    endif
3506
+
3507
+    " Make sure the taglist window is present
3508
+    let winnum = bufwinnr(g:TagList_title)
3509
+    if winnum == -1
3510
+        call s:Tlist_Warning_Msg('Error: Taglist window is not open')
3511
+        return
3512
+    endif
3513
+
3514
+    let fidx = s:Tlist_Get_File_Index(a:filename)
3515
+    if fidx == -1
3516
+        return
3517
+    endif
3518
+
3519
+    " If the file is currently not displayed in the taglist window, then retrn
3520
+    if !s:tlist_{fidx}_visible
3521
+        return
3522
+    endif
3523
+
3524
+    " If there are no tags for this file, then no need to proceed further
3525
+    if s:tlist_{fidx}_tag_count == 0
3526
+        return
3527
+    endif
3528
+
3529
+    " Ignore all autocommands
3530
+    let old_ei = &eventignore
3531
+    set eventignore=all
3532
+
3533
+    " Save the original window number
3534
+    let org_winnr = winnr()
3535
+
3536
+    if org_winnr == winnum
3537
+        let in_taglist_window = 1
3538
+    else
3539
+        let in_taglist_window = 0
3540
+    endif
3541
+
3542
+    " Go to the taglist window
3543
+    if !in_taglist_window
3544
+        exe winnum . 'wincmd w'
3545
+    endif
3546
+
3547
+    " Clear previously selected name
3548
+    match none
3549
+
3550
+    let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, a:cur_lnum)
3551
+    if tidx == -1
3552
+        " Make sure the current tag line is visible in the taglist window.
3553
+        " Calling the winline() function makes the line visible.  Don't know
3554
+        " of a better way to achieve this.
3555
+        let lnum = line('.')
3556
+
3557
+        if lnum < s:tlist_{fidx}_start || lnum > s:tlist_{fidx}_end
3558
+            " Move the cursor to the beginning of the file
3559
+            exe s:tlist_{fidx}_start
3560
+        endif
3561
+
3562
+        if foldclosed('.') != -1
3563
+            .foldopen
3564
+        endif
3565
+
3566
+        call winline()
3567
+
3568
+        if !in_taglist_window
3569
+            exe org_winnr . 'wincmd w'
3570
+        endif
3571
+
3572
+        " Restore the autocommands
3573
+        let &eventignore = old_ei
3574
+        return
3575
+    endif
3576
+
3577
+    " Extract the tag type
3578
+    let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx)
3579
+
3580
+    " Compute the line number
3581
+    " Start of file + Start of tag type + offset
3582
+    let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset +
3583
+                \ s:tlist_{fidx}_{tidx}_ttype_idx
3584
+
3585
+    " Goto the line containing the tag
3586
+    exe lnum
3587
+
3588
+    " Open the fold
3589
+    if foldclosed('.') != -1
3590
+        .foldopen
3591
+    endif
3592
+
3593
+    if a:center
3594
+        " Move the tag line to the center of the taglist window
3595
+        normal! z.
3596
+    else
3597
+        " Make sure the current tag line is visible in the taglist window.
3598
+        " Calling the winline() function makes the line visible.  Don't know
3599
+        " of a better way to achieve this.
3600
+        call winline()
3601
+    endif
3602
+
3603
+    " Highlight the tag name
3604
+    call s:Tlist_Window_Highlight_Line()
3605
+
3606
+    " Go back to the original window
3607
+    if !in_taglist_window
3608
+        exe org_winnr . 'wincmd w'
3609
+    endif
3610
+
3611
+    " Restore the autocommands
3612
+    let &eventignore = old_ei
3613
+    return
3614
+endfunction
3615
+
3616
+" Tlist_Get_Tag_Prototype_By_Line
3617
+" Get the prototype for the tag on or before the specified line number in the
3618
+" current buffer
3619
+function! Tlist_Get_Tag_Prototype_By_Line(...)
3620
+    if a:0 == 0
3621
+        " Arguments are not supplied. Use the current buffer name
3622
+        " and line number
3623
+        let filename = bufname('%')
3624
+        let linenr = line('.')
3625
+    elseif a:0 == 2
3626
+        " Filename and line number are specified
3627
+        let filename = a:1
3628
+        let linenr = a:2
3629
+        if linenr !~ '\d\+'
3630
+            " Invalid line number
3631
+            return ""
3632
+        endif
3633
+    else
3634
+        " Sufficient arguments are not supplied
3635
+        let msg =  'Usage: Tlist_Get_Tag_Prototype_By_Line <filename> ' .
3636
+                                \ '<line_number>'
3637
+        call s:Tlist_Warning_Msg(msg)
3638
+        return ""
3639
+    endif
3640
+
3641
+    " Expand the file to a fully qualified name
3642
+    let filename = fnamemodify(filename, ':p')
3643
+    if filename == ''
3644
+        return ""
3645
+    endif
3646
+
3647
+    let fidx = s:Tlist_Get_File_Index(filename)
3648
+    if fidx == -1
3649
+        return ""
3650
+    endif
3651
+
3652
+    " If there are no tags for this file, then no need to proceed further
3653
+    if s:tlist_{fidx}_tag_count == 0
3654
+        return ""
3655
+    endif
3656
+
3657
+    " Get the tag text using the line number
3658
+    let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr)
3659
+    if tidx == -1
3660
+        return ""
3661
+    endif
3662
+
3663
+    return s:Tlist_Get_Tag_Prototype(fidx, tidx)
3664
+endfunction
3665
+
3666
+" Tlist_Get_Tagname_By_Line
3667
+" Get the tag name on or before the specified line number in the
3668
+" current buffer
3669
+function! Tlist_Get_Tagname_By_Line(...)
3670
+    if a:0 == 0
3671
+        " Arguments are not supplied. Use the current buffer name
3672
+        " and line number
3673
+        let filename = bufname('%')
3674
+        let linenr = line('.')
3675
+    elseif a:0 == 2
3676
+        " Filename and line number are specified
3677
+        let filename = a:1
3678
+        let linenr = a:2
3679
+        if linenr !~ '\d\+'
3680
+            " Invalid line number
3681
+            return ""
3682
+        endif
3683
+    else
3684
+        " Sufficient arguments are not supplied
3685
+        let msg =  'Usage: Tlist_Get_Tagname_By_Line <filename> <line_number>'
3686
+        call s:Tlist_Warning_Msg(msg)
3687
+        return ""
3688
+    endif
3689
+
3690
+    " Make sure the current file has a name
3691
+    let filename = fnamemodify(filename, ':p')
3692
+    if filename == ''
3693
+        return ""
3694
+    endif
3695
+
3696
+    let fidx = s:Tlist_Get_File_Index(filename)
3697
+    if fidx == -1
3698
+        return ""
3699
+    endif
3700
+
3701
+    " If there are no tags for this file, then no need to proceed further
3702
+    if s:tlist_{fidx}_tag_count == 0
3703
+        return ""
3704
+    endif
3705
+
3706
+    " Get the tag name using the line number
3707
+    let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr)
3708
+    if tidx == -1
3709
+        return ""
3710
+    endif
3711
+
3712
+    return s:tlist_{fidx}_{tidx}_tag_name
3713
+endfunction
3714
+
3715
+" Tlist_Window_Move_To_File
3716
+" Move the cursor to the beginning of the current file or the next file
3717
+" or the previous file in the taglist window
3718
+" dir == -1, move to start of current or previous function
3719
+" dir == 1, move to start of next function
3720
+function! s:Tlist_Window_Move_To_File(dir)
3721
+    if foldlevel('.') == 0
3722
+        " Cursor is on a non-folded line (it is not in any of the files)
3723
+        " Move it to a folded line
3724
+        if a:dir == -1
3725
+            normal! zk
3726
+        else
3727
+            " While moving down to the start of the next fold,
3728
+            " no need to do go to the start of the next file.
3729
+            normal! zj
3730
+            return
3731
+        endif
3732
+    endif
3733
+
3734
+    let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
3735
+    if fidx == -1
3736
+        return
3737
+    endif
3738
+
3739
+    let cur_lnum = line('.')
3740
+
3741
+    if a:dir == -1
3742
+        if cur_lnum > s:tlist_{fidx}_start
3743
+            " Move to the beginning of the current file
3744
+            exe s:tlist_{fidx}_start
3745
+            return
3746
+        endif
3747
+
3748
+        if fidx != 0
3749
+            " Move to the beginning of the previous file
3750
+            let fidx = fidx - 1
3751
+        else
3752
+            " Cursor is at the first file, wrap around to the last file
3753
+            let fidx = s:tlist_file_count - 1
3754
+        endif
3755
+
3756
+        exe s:tlist_{fidx}_start
3757
+        return
3758
+    else
3759
+        " Move to the beginning of the next file
3760
+        let fidx = fidx + 1
3761
+
3762
+        if fidx >= s:tlist_file_count
3763
+            " Cursor is at the last file, wrap around to the first file
3764
+            let fidx = 0
3765
+        endif
3766
+
3767
+        if s:tlist_{fidx}_start != 0
3768
+            exe s:tlist_{fidx}_start
3769
+        endif
3770
+        return
3771
+    endif
3772
+endfunction
3773
+
3774
+" Tlist_Session_Load
3775
+" Load a taglist session (information about all the displayed files
3776
+" and the tags) from the specified file
3777
+function! s:Tlist_Session_Load(...)
3778
+    if a:0 == 0 || a:1 == ''
3779
+        call s:Tlist_Warning_Msg('Usage: TlistSessionLoad <filename>')
3780
+        return
3781
+    endif
3782
+
3783
+    let sessionfile = a:1
3784
+
3785
+    if !filereadable(sessionfile)
3786
+        let msg = 'Taglist: Error - Unable to open file ' . sessionfile
3787
+        call s:Tlist_Warning_Msg(msg)
3788
+        return
3789
+    endif
3790
+
3791
+    " Mark the current window as the file window
3792
+    call s:Tlist_Window_Mark_File_Window()
3793
+
3794
+    " Source the session file
3795
+    exe 'source ' . sessionfile
3796
+
3797
+    let new_file_count = g:tlist_file_count
3798
+    unlet! g:tlist_file_count
3799
+
3800
+    let i = 0
3801
+    while i < new_file_count
3802
+        let ftype = g:tlist_{i}_filetype
3803
+        unlet! g:tlist_{i}_filetype
3804
+
3805
+        if !exists('s:tlist_' . ftype . '_count')
3806
+            if s:Tlist_FileType_Init(ftype) == 0
3807
+                let i = i + 1
3808
+                continue
3809
+            endif
3810
+        endif
3811
+
3812
+        let fname = g:tlist_{i}_filename
3813
+        unlet! g:tlist_{i}_filename
3814
+
3815
+        let fidx = s:Tlist_Get_File_Index(fname)
3816
+        if fidx != -1
3817
+            let s:tlist_{fidx}_visible = 0
3818
+            let i = i + 1
3819
+            continue
3820
+        else
3821
+            " As we are loading the tags from the session file, if this
3822
+            " file was previously deleted by the user, now we need to
3823
+            " add it back. So remove the file from the deleted list.
3824
+            call s:Tlist_Update_Remove_List(fname, 0)
3825
+        endif
3826
+
3827
+        let fidx = s:Tlist_Init_File(fname, ftype)
3828
+
3829
+        let s:tlist_{fidx}_filename = fname
3830
+
3831
+        let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type
3832
+        unlet! g:tlist_{i}_sort_type
3833
+
3834
+        let s:tlist_{fidx}_filetype = ftype
3835
+        let s:tlist_{fidx}_mtime = getftime(fname)
3836
+
3837
+        let s:tlist_{fidx}_start = 0
3838
+        let s:tlist_{fidx}_end = 0
3839
+
3840
+        let s:tlist_{fidx}_valid = 1
3841
+
3842
+        let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count
3843
+        unlet! g:tlist_{i}_tag_count
3844
+
3845
+        let j = 1
3846
+        while j <= s:tlist_{fidx}_tag_count
3847
+            let s:tlist_{fidx}_{j}_tag = g:tlist_{i}_{j}_tag
3848
+            let s:tlist_{fidx}_{j}_tag_name = g:tlist_{i}_{j}_tag_name
3849
+            let s:tlist_{fidx}_{j}_ttype_idx = g:tlist_{i}_{j}_ttype_idx
3850
+            unlet! g:tlist_{i}_{j}_tag
3851
+            unlet! g:tlist_{i}_{j}_tag_name
3852
+            unlet! g:tlist_{i}_{j}_ttype_idx
3853
+            let j = j + 1
3854
+        endwhile
3855
+
3856
+        let j = 1
3857
+        while j <= s:tlist_{ftype}_count
3858
+            let ttype = s:tlist_{ftype}_{j}_name
3859
+
3860
+            if exists('g:tlist_' . i . '_' . ttype)
3861
+                let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype}
3862
+                unlet! g:tlist_{i}_{ttype}
3863
+                let s:tlist_{fidx}_{ttype}_offset = 0
3864
+                let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count
3865
+                unlet! g:tlist_{i}_{ttype}_count
3866
+
3867
+                let k = 1
3868
+                while k <= s:tlist_{fidx}_{ttype}_count
3869
+                    let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k}
3870
+                    unlet! g:tlist_{i}_{ttype}_{k}
3871
+                    let k = k + 1
3872
+                endwhile
3873
+            else
3874
+                let s:tlist_{fidx}_{ttype} = ''
3875
+                let s:tlist_{fidx}_{ttype}_offset = 0
3876
+                let s:tlist_{fidx}_{ttype}_count = 0
3877
+            endif
3878
+
3879
+            let j = j + 1
3880
+        endwhile
3881
+
3882
+        let i = i + 1
3883
+    endwhile
3884
+
3885
+    " If the taglist window is open, then update it
3886
+    let winnum = bufwinnr(g:TagList_title)
3887
+    if winnum != -1
3888
+        let save_winnr = winnr()
3889
+
3890
+        " Goto the taglist window
3891
+        call s:Tlist_Window_Goto_Window()
3892
+
3893
+        " Refresh the taglist window
3894
+        call s:Tlist_Window_Refresh()
3895
+
3896
+        " Go back to the original window
3897
+        if save_winnr != winnr()
3898
+            call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
3899
+        endif
3900
+    endif
3901
+endfunction
3902
+
3903
+" Tlist_Session_Save
3904
+" Save a taglist session (information about all the displayed files
3905
+" and the tags) into the specified file
3906
+function! s:Tlist_Session_Save(...)
3907
+    if a:0 == 0 || a:1 == ''
3908
+        call s:Tlist_Warning_Msg('Usage: TlistSessionSave <filename>')
3909
+        return
3910
+    endif
3911
+
3912
+    let sessionfile = a:1
3913
+
3914
+    if s:tlist_file_count == 0
3915
+        " There is nothing to save
3916
+        call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.')
3917
+        return
3918
+    endif
3919
+
3920
+    if filereadable(sessionfile)
3921
+        let ans = input('Do you want to overwrite ' . sessionfile . ' (Y/N)?')
3922
+        if ans !=? 'y'
3923
+            return
3924
+        endif
3925
+
3926
+        echo "\n"
3927
+    endif
3928
+
3929
+    let old_verbose = &verbose
3930
+    set verbose&vim
3931
+
3932
+    exe 'redir! > ' . sessionfile
3933
+
3934
+    silent! echo '" Taglist session file. This file is auto-generated.'
3935
+    silent! echo '" File information'
3936
+    silent! echo 'let tlist_file_count = ' . s:tlist_file_count
3937
+
3938
+    let i = 0
3939
+
3940
+    while i < s:tlist_file_count
3941
+        " Store information about the file
3942
+        silent! echo 'let tlist_' . i . "_filename = '" .
3943
+                                            \ s:tlist_{i}_filename . "'"
3944
+        silent! echo 'let tlist_' . i . '_sort_type = "' .
3945
+                                                \ s:tlist_{i}_sort_type . '"'
3946
+        silent! echo 'let tlist_' . i . '_filetype = "' .
3947
+                                            \ s:tlist_{i}_filetype . '"'
3948
+        silent! echo 'let tlist_' . i . '_tag_count = ' .
3949
+                                                        \ s:tlist_{i}_tag_count
3950
+        " Store information about all the tags
3951
+        let j = 1
3952
+        while j <= s:tlist_{i}_tag_count
3953
+            let txt = escape(s:tlist_{i}_{j}_tag, '"\\')
3954
+            silent! echo 'let tlist_' . i . '_' . j . '_tag = "' . txt . '"'
3955
+            silent! echo 'let tlist_' . i . '_' . j . '_tag_name = "' .
3956
+                        \ s:tlist_{i}_{j}_tag_name . '"'
3957
+            silent! echo 'let tlist_' . i . '_' . j . '_ttype_idx' . ' = ' .
3958
+                        \ s:tlist_{i}_{j}_ttype_idx
3959
+            let j = j + 1
3960
+        endwhile
3961
+
3962
+        " Store information about all the tags grouped by their type
3963
+        let ftype = s:tlist_{i}_filetype
3964
+        let j = 1
3965
+        while j <= s:tlist_{ftype}_count
3966
+            let ttype = s:tlist_{ftype}_{j}_name
3967
+            if s:tlist_{i}_{ttype}_count != 0
3968
+                let txt = escape(s:tlist_{i}_{ttype}, '"\')
3969
+                let txt = substitute(txt, "\n", "\\\\n", 'g')
3970
+                silent! echo 'let tlist_' . i . '_' . ttype . ' = "' .
3971
+                                                \ txt . '"'
3972
+                silent! echo 'let tlist_' . i . '_' . ttype . '_count = ' .
3973
+                                                     \ s:tlist_{i}_{ttype}_count
3974
+                let k = 1
3975
+                while k <= s:tlist_{i}_{ttype}_count
3976
+                    silent! echo 'let tlist_' . i . '_' . ttype . '_' . k .
3977
+                                \ ' = ' . s:tlist_{i}_{ttype}_{k}
3978
+                    let k = k + 1
3979
+                endwhile
3980
+            endif
3981
+            let j = j + 1
3982
+        endwhile
3983
+
3984
+        silent! echo
3985
+
3986
+        let i = i + 1
3987
+    endwhile
3988
+
3989
+    redir END
3990
+
3991
+    let &verbose = old_verbose
3992
+endfunction
3993
+
3994
+" Tlist_Buffer_Removed
3995
+" A buffer is removed from the Vim buffer list. Remove the tags defined
3996
+" for that file
3997
+function! s:Tlist_Buffer_Removed(filename)
3998
+    call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename .  ')')
3999
+
4000
+    " Make sure a valid filename is supplied
4001
+    if a:filename == ''
4002
+        return
4003
+    endif
4004
+
4005
+    " Get tag list index of the specified file
4006
+    let fidx = s:Tlist_Get_File_Index(a:filename)
4007
+    if fidx == -1
4008
+        " File not present in the taglist
4009
+        return
4010
+    endif
4011
+
4012
+    " Remove the file from the list
4013
+    call s:Tlist_Remove_File(fidx, 0)
4014
+endfunction
4015
+
4016
+" When a buffer is deleted, remove the file from the taglist
4017
+autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand('<afile>:p'))
4018
+
4019
+" Tlist_Window_Open_File_Fold
4020
+" Open the fold for the specified file and close the fold for all the
4021
+" other files
4022
+function! s:Tlist_Window_Open_File_Fold(acmd_bufnr)
4023
+    call s:Tlist_Log_Msg('Tlist_Window_Open_File_Fold (' . a:acmd_bufnr . ')')
4024
+
4025
+    " Make sure the taglist window is present
4026
+    let winnum = bufwinnr(g:TagList_title)
4027
+    if winnum == -1
4028
+        call s:Tlist_Warning_Msg('Taglist: Error - Taglist window is not open')
4029
+        return
4030
+    endif
4031
+
4032
+    " Save the original window number
4033
+    let org_winnr = winnr()
4034
+    if org_winnr == winnum
4035
+        let in_taglist_window = 1
4036
+    else
4037
+        let in_taglist_window = 0
4038
+    endif
4039
+
4040
+    if in_taglist_window
4041
+        " When entering the taglist window, no need to update the folds
4042
+        return
4043
+    endif
4044
+
4045
+    " Go to the taglist window
4046
+    if !in_taglist_window
4047
+        call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w')
4048
+    endif
4049
+
4050
+    " Close all the folds
4051
+    silent! %foldclose
4052
+
4053
+    " Get tag list index of the specified file
4054
+    let fname = fnamemodify(bufname(a:acmd_bufnr + 0), ':p')
4055
+    if filereadable(fname)
4056
+        let fidx = s:Tlist_Get_File_Index(fname)
4057
+        if fidx != -1
4058
+            " Open the fold for the file
4059
+            exe "silent! " . s:tlist_{fidx}_start . "," .
4060
+                        \ s:tlist_{fidx}_end . "foldopen"
4061
+        endif
4062
+    endif
4063
+
4064
+    " Go back to the original window
4065
+    if !in_taglist_window
4066
+        call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w')
4067
+    endif
4068
+endfunction
4069
+
4070
+" Tlist_Window_Check_Auto_Open
4071
+" Open the taglist window automatically on Vim startup.
4072
+" Open the window only when files present in any of the Vim windows support
4073
+" tags.
4074
+function! s:Tlist_Window_Check_Auto_Open()
4075
+    let open_window = 0
4076
+
4077
+    let i = 1
4078
+    let buf_num = winbufnr(i)
4079
+    while buf_num != -1
4080
+        let filename = fnamemodify(bufname(buf_num), ':p')
4081
+        let ft = s:Tlist_Get_Buffer_Filetype(buf_num)
4082
+        if !s:Tlist_Skip_File(filename, ft)
4083
+            let open_window = 1
4084
+            break
4085
+        endif
4086
+        let i = i + 1
4087
+        let buf_num = winbufnr(i)
4088
+    endwhile
4089
+
4090
+    if open_window
4091
+        call s:Tlist_Window_Toggle()
4092
+    endif
4093
+endfunction
4094
+
4095
+" Tlist_Refresh_Folds
4096
+" Remove and create the folds for all the files displayed in the taglist
4097
+" window. Used after entering a tab. If this is not done, then the folds
4098
+" are not properly created for taglist windows displayed in multiple tabs.
4099
+function! s:Tlist_Refresh_Folds()
4100
+    let winnum = bufwinnr(g:TagList_title)
4101
+    if winnum == -1
4102
+        return
4103
+    endif
4104
+
4105
+    let save_wnum = winnr()
4106
+    exe winnum . 'wincmd w'
4107
+
4108
+    " First remove all the existing folds
4109
+    normal! zE
4110
+
4111
+    " Create the folds for each in the tag list
4112
+    let fidx = 0
4113
+    while fidx < s:tlist_file_count
4114
+        let ftype = s:tlist_{fidx}_filetype
4115
+
4116
+        " Create the folds for each tag type in a file
4117
+        let j = 1
4118
+        while j <= s:tlist_{ftype}_count
4119
+            let ttype = s:tlist_{ftype}_{j}_name
4120
+            if s:tlist_{fidx}_{ttype}_count
4121
+                let s = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset
4122
+                let e = s + s:tlist_{fidx}_{ttype}_count
4123
+                exe s . ',' . e . 'fold'
4124
+            endif
4125
+            let j = j + 1
4126
+        endwhile
4127
+
4128
+        exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold'
4129
+        exe 'silent! ' . s:tlist_{fidx}_start . ',' .
4130
+                    \ s:tlist_{fidx}_end . 'foldopen!'
4131
+        let fidx = fidx + 1
4132
+    endwhile
4133
+
4134
+    exe save_wnum . 'wincmd w'
4135
+endfunction
4136
+
4137
+function! s:Tlist_Menu_Add_Base_Menu()
4138
+    call s:Tlist_Log_Msg('Adding the base menu')
4139
+
4140
+    " Add the menu
4141
+    anoremenu <silent> T&ags.Refresh\ menu :call <SID>Tlist_Menu_Refresh()<CR>
4142
+    anoremenu <silent> T&ags.Sort\ menu\ by.Name
4143
+                    \ :call <SID>Tlist_Change_Sort('menu', 'set', 'name')<CR>
4144
+    anoremenu <silent> T&ags.Sort\ menu\ by.Order
4145
+                    \ :call <SID>Tlist_Change_Sort('menu', 'set', 'order')<CR>
4146
+    anoremenu T&ags.-SEP1-           :
4147
+
4148
+    if &mousemodel =~ 'popup'
4149
+        anoremenu <silent> PopUp.T&ags.Refresh\ menu
4150
+                    \ :call <SID>Tlist_Menu_Refresh()<CR>
4151
+        anoremenu <silent> PopUp.T&ags.Sort\ menu\ by.Name
4152
+                  \ :call <SID>Tlist_Change_Sort('menu', 'set', 'name')<CR>
4153
+        anoremenu <silent> PopUp.T&ags.Sort\ menu\ by.Order
4154
+                  \ :call <SID>Tlist_Change_Sort('menu', 'set', 'order')<CR>
4155
+        anoremenu PopUp.T&ags.-SEP1-           :
4156
+    endif
4157
+endfunction
4158
+
4159
+let s:menu_char_prefix =
4160
+            \ '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
4161
+
4162
+" Tlist_Menu_Get_Tag_Type_Cmd
4163
+" Get the menu command for the specified tag type
4164
+" fidx - File type index
4165
+" ftype - File Type
4166
+" add_ttype_name - To add or not to add the tag type name to the menu entries
4167
+" ttype_idx - Tag type index
4168
+function! s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, ttype_idx)
4169
+    " Curly brace variable name optimization
4170
+    let ftype_ttype_idx = a:ftype . '_' . a:ttype_idx
4171
+
4172
+    let ttype = s:tlist_{ftype_ttype_idx}_name
4173
+    if a:add_ttype_name
4174
+        " If the tag type name contains space characters, escape it. This
4175
+        " will be used to create the menu entries.
4176
+        let ttype_fullname = escape(s:tlist_{ftype_ttype_idx}_fullname, ' ')
4177
+    endif
4178
+
4179
+    " Curly brace variable name optimization
4180
+    let fidx_ttype = a:fidx . '_' . ttype
4181
+
4182
+    " Number of tag entries for this tag type
4183
+    let tcnt = s:tlist_{fidx_ttype}_count
4184
+    if tcnt == 0 " No entries for this tag type
4185
+        return ''
4186
+    endif
4187
+
4188
+    let mcmd = ''
4189
+
4190
+    " Create the menu items for the tags.
4191
+    " Depending on the number of tags of this type, split the menu into
4192
+    " multiple sub-menus, if needed.
4193
+    if tcnt > g:Tlist_Max_Submenu_Items
4194
+        let j = 1
4195
+        while j <= tcnt
4196
+            let final_index = j + g:Tlist_Max_Submenu_Items - 1
4197
+            if final_index > tcnt
4198
+                let final_index = tcnt
4199
+            endif
4200
+
4201
+            " Extract the first and last tag name and form the
4202
+            " sub-menu name
4203
+            let tidx = s:tlist_{fidx_ttype}_{j}
4204
+            let first_tag = s:tlist_{a:fidx}_{tidx}_tag_name
4205
+
4206
+            let tidx = s:tlist_{fidx_ttype}_{final_index}
4207
+            let last_tag = s:tlist_{a:fidx}_{tidx}_tag_name
4208
+
4209
+            " Truncate the names, if they are greater than the
4210
+            " max length
4211
+            let first_tag = strpart(first_tag, 0, g:Tlist_Max_Tag_Length)
4212
+            let last_tag = strpart(last_tag, 0, g:Tlist_Max_Tag_Length)
4213
+
4214
+            " Form the menu command prefix
4215
+            let m_prefix = 'anoremenu <silent> T\&ags.'
4216
+            if a:add_ttype_name
4217
+                let m_prefix = m_prefix . ttype_fullname . '.'
4218
+            endif
4219
+            let m_prefix = m_prefix . first_tag . '\.\.\.' . last_tag . '.'
4220
+
4221
+            " Character prefix used to number the menu items (hotkey)
4222
+            let m_prefix_idx = 0
4223
+
4224
+            while j <= final_index
4225
+                let tidx = s:tlist_{fidx_ttype}_{j}
4226
+
4227
+                let tname = s:tlist_{a:fidx}_{tidx}_tag_name
4228
+
4229
+                let mcmd = mcmd . m_prefix . '\&' .
4230
+                            \ s:menu_char_prefix[m_prefix_idx] . '\.' .
4231
+                            \ tname . ' :call <SID>Tlist_Menu_Jump_To_Tag(' .
4232
+                            \ tidx . ')<CR>|'
4233
+
4234
+                let m_prefix_idx = m_prefix_idx + 1
4235
+                let j = j + 1
4236
+            endwhile
4237
+        endwhile
4238
+    else
4239
+        " Character prefix used to number the menu items (hotkey)
4240
+        let m_prefix_idx = 0
4241
+
4242
+        let m_prefix = 'anoremenu <silent> T\&ags.'
4243
+        if a:add_ttype_name
4244
+            let m_prefix = m_prefix . ttype_fullname . '.'
4245
+        endif
4246
+        let j = 1
4247
+        while j <= tcnt
4248
+            let tidx = s:tlist_{fidx_ttype}_{j}
4249
+
4250
+            let tname = s:tlist_{a:fidx}_{tidx}_tag_name
4251
+
4252
+            let mcmd = mcmd . m_prefix . '\&' .
4253
+                        \ s:menu_char_prefix[m_prefix_idx] . '\.' .
4254
+                        \ tname . ' :call <SID>Tlist_Menu_Jump_To_Tag(' . tidx
4255
+                        \ . ')<CR>|'
4256
+
4257
+            let m_prefix_idx = m_prefix_idx + 1
4258
+            let j = j + 1
4259
+        endwhile
4260
+    endif
4261
+
4262
+    return mcmd
4263
+endfunction
4264
+
4265
+" Update the taglist menu with the tags for the specified file
4266
+function! s:Tlist_Menu_File_Refresh(fidx)
4267
+    call s:Tlist_Log_Msg('Refreshing the tag menu for ' . s:tlist_{a:fidx}_filename)
4268
+    " The 'B' flag is needed in the 'cpoptions' option
4269
+    let old_cpoptions = &cpoptions
4270
+    set cpoptions&vim
4271
+
4272
+    exe s:tlist_{a:fidx}_menu_cmd
4273
+
4274
+    " Update the popup menu (if enabled)
4275
+    if &mousemodel =~ 'popup'
4276
+        let cmd = substitute(s:tlist_{a:fidx}_menu_cmd, ' T\\&ags\.',
4277
+                                        \ ' PopUp.T\\\&ags.', "g")
4278
+        exe cmd
4279
+    endif
4280
+
4281
+    " The taglist menu is not empty now
4282
+    let s:tlist_menu_empty = 0
4283
+
4284
+    " Restore the 'cpoptions' settings
4285
+    let &cpoptions = old_cpoptions
4286
+endfunction
4287
+
4288
+" Tlist_Menu_Update_File
4289
+" Add the taglist menu
4290
+function! s:Tlist_Menu_Update_File(clear_menu)
4291
+    if !has('gui_running')
4292
+        " Not running in GUI mode
4293
+        return
4294
+    endif
4295
+
4296
+    call s:Tlist_Log_Msg('Updating the tag menu, clear_menu = ' . a:clear_menu)
4297
+
4298
+    " Remove the tags menu
4299
+    if a:clear_menu
4300
+        call s:Tlist_Menu_Remove_File()
4301
+
4302
+    endif
4303
+
4304
+    " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help
4305
+    if &buftype != ''
4306
+        return
4307
+    endif
4308
+
4309
+    let filename = fnamemodify(bufname('%'), ':p')
4310
+    let ftype = s:Tlist_Get_Buffer_Filetype('%')
4311
+
4312
+    " If the file doesn't support tag listing, skip it
4313
+    if s:Tlist_Skip_File(filename, ftype)
4314
+        return
4315
+    endif
4316
+
4317
+    let fidx = s:Tlist_Get_File_Index(filename)
4318
+    if fidx == -1 || !s:tlist_{fidx}_valid
4319
+        " Check whether this file is removed based on user request
4320
+        " If it is, then don't display the tags for this file
4321
+        if s:Tlist_User_Removed_File(filename)
4322
+            return
4323
+        endif
4324
+
4325
+        " Process the tags for the file
4326
+        let fidx = s:Tlist_Process_File(filename, ftype)
4327
+        if fidx == -1
4328
+            return
4329
+        endif
4330
+    endif
4331
+
4332
+    let fname = escape(fnamemodify(bufname('%'), ':t'), '.')
4333
+    if fname != ''
4334
+        exe 'anoremenu T&ags.' .  fname . ' <Nop>'
4335
+        anoremenu T&ags.-SEP2-           :
4336
+    endif
4337
+
4338
+    if !s:tlist_{fidx}_tag_count
4339
+        return
4340
+    endif
4341
+
4342
+    if s:tlist_{fidx}_menu_cmd != ''
4343
+        " Update the menu with the cached command
4344
+        call s:Tlist_Menu_File_Refresh(fidx)
4345
+
4346
+        return
4347
+    endif
4348
+
4349
+    " We are going to add entries to the tags menu, so the menu won't be
4350
+    " empty
4351
+    let s:tlist_menu_empty = 0
4352
+
4353
+    let cmd = ''
4354
+
4355
+    " Determine whether the tag type name needs to be added to the menu
4356
+    " If more than one tag type is present in the taglisting for a file,
4357
+    " then the tag type name needs to be present
4358
+    let add_ttype_name = -1
4359
+    let i = 1
4360
+    while i <= s:tlist_{ftype}_count && add_ttype_name < 1
4361
+        let ttype = s:tlist_{ftype}_{i}_name
4362
+        if s:tlist_{fidx}_{ttype}_count
4363
+            let add_ttype_name = add_ttype_name + 1
4364
+        endif
4365
+        let i = i + 1
4366
+    endwhile
4367
+
4368
+    " Process the tags by the tag type and get the menu command
4369
+    let i = 1
4370
+    while i <= s:tlist_{ftype}_count
4371
+        let mcmd = s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, i)
4372
+        if mcmd != ''
4373
+            let cmd = cmd . mcmd
4374
+        endif
4375
+
4376
+        let i = i + 1
4377
+    endwhile
4378
+
4379
+    " Cache the menu command for reuse
4380
+    let s:tlist_{fidx}_menu_cmd = cmd
4381
+
4382
+    " Update the menu
4383
+    call s:Tlist_Menu_File_Refresh(fidx)
4384
+endfunction
4385
+
4386
+" Tlist_Menu_Remove_File
4387
+" Remove the tags displayed in the tags menu
4388
+function! s:Tlist_Menu_Remove_File()
4389
+    if !has('gui_running') || s:tlist_menu_empty
4390
+        return
4391
+    endif
4392
+
4393
+    call s:Tlist_Log_Msg('Removing the tags menu for a file')
4394
+
4395
+    " Cleanup the Tags menu
4396
+    silent! unmenu T&ags
4397
+    if &mousemodel =~ 'popup'
4398
+        silent! unmenu PopUp.T&ags
4399
+    endif
4400
+
4401
+    " Add a dummy menu item to retain teared off menu
4402
+    noremenu T&ags.Dummy l
4403
+
4404
+    silent! unmenu! T&ags
4405
+    if &mousemodel =~ 'popup'
4406
+        silent! unmenu! PopUp.T&ags
4407
+    endif
4408
+
4409
+    call s:Tlist_Menu_Add_Base_Menu()
4410
+
4411
+    " Remove the dummy menu item
4412
+    unmenu T&ags.Dummy
4413
+
4414
+    let s:tlist_menu_empty = 1
4415
+endfunction
4416
+
4417
+" Tlist_Menu_Refresh
4418
+" Refresh the taglist menu
4419
+function! s:Tlist_Menu_Refresh()
4420
+    call s:Tlist_Log_Msg('Refreshing the tags menu')
4421
+    let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
4422
+    if fidx != -1
4423
+        " Invalidate the cached menu command
4424
+        let s:tlist_{fidx}_menu_cmd = ''
4425
+    endif
4426
+
4427
+    " Update the taglist, menu and window
4428
+    call s:Tlist_Update_Current_File()
4429
+endfunction
4430
+
4431
+" Tlist_Menu_Jump_To_Tag
4432
+" Jump to the selected tag
4433
+function! s:Tlist_Menu_Jump_To_Tag(tidx)
4434
+    let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
4435
+    if fidx == -1
4436
+        return
4437
+    endif
4438
+
4439
+    let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, a:tidx)
4440
+    if tagpat == ''
4441
+        return
4442
+    endif
4443
+
4444
+    " Add the current cursor position to the jump list, so that user can
4445
+    " jump back using the ' and ` marks.
4446
+    mark '
4447
+
4448
+    silent call search(tagpat, 'w')
4449
+
4450
+    " Bring the line to the middle of the window
4451
+    normal! z.
4452
+
4453
+    " If the line is inside a fold, open the fold
4454
+    if foldclosed('.') != -1
4455
+        .foldopen
4456
+    endif
4457
+endfunction
4458
+
4459
+" Tlist_Menu_Init
4460
+" Initialize the taglist menu
4461
+function! s:Tlist_Menu_Init()
4462
+    call s:Tlist_Menu_Add_Base_Menu()
4463
+
4464
+    " Automatically add the tags defined in the current file to the menu
4465
+    augroup TagListMenuCmds
4466
+        autocmd!
4467
+
4468
+        if !g:Tlist_Process_File_Always
4469
+            autocmd BufEnter * call s:Tlist_Refresh()
4470
+        endif
4471
+        autocmd BufLeave * call s:Tlist_Menu_Remove_File()
4472
+    augroup end
4473
+
4474
+    call s:Tlist_Menu_Update_File(0)
4475
+endfunction
4476
+
4477
+" Tlist_Vim_Session_Load
4478
+" Initialize the taglist window/buffer, which is created when loading
4479
+" a Vim session file.
4480
+function! s:Tlist_Vim_Session_Load()
4481
+    call s:Tlist_Log_Msg('Tlist_Vim_Session_Load')
4482
+
4483
+    " Initialize the taglist window
4484
+    call s:Tlist_Window_Init()
4485
+
4486
+    " Refresh the taglist window
4487
+    call s:Tlist_Window_Refresh()
4488
+endfunction
4489
+
4490
+" Tlist_Set_App
4491
+" Set the name of the external plugin/application to which taglist
4492
+" belongs.
4493
+" Taglist plugin is part of another plugin like cream or winmanager.
4494
+function! Tlist_Set_App(name)
4495
+    if a:name == ""
4496
+        return
4497
+    endif
4498
+
4499
+    let s:tlist_app_name = a:name
4500
+endfunction
4501
+
4502
+" Winmanager integration
4503
+
4504
+" Initialization required for integration with winmanager
4505
+function! TagList_Start()
4506
+    " If current buffer is not taglist buffer, then don't proceed
4507
+    if bufname('%') != '__Tag_List__'
4508
+        return
4509
+    endif
4510
+
4511
+    call Tlist_Set_App('winmanager')
4512
+
4513
+    " Get the current filename from the winmanager plugin
4514
+    let bufnum = WinManagerGetLastEditedFile()
4515
+    if bufnum != -1
4516
+        let filename = fnamemodify(bufname(bufnum), ':p')
4517
+        let ftype = s:Tlist_Get_Buffer_Filetype(bufnum)
4518
+    endif
4519
+
4520
+    " Initialize the taglist window, if it is not already initialized
4521
+    if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized
4522
+        call s:Tlist_Window_Init()
4523
+        call s:Tlist_Window_Refresh()
4524
+        let s:tlist_window_initialized = 1
4525
+    endif
4526
+
4527
+    " Update the taglist window
4528
+    if bufnum != -1
4529
+        if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update
4530
+            call s:Tlist_Window_Refresh_File(filename, ftype)
4531
+        endif
4532
+    endif
4533
+endfunction
4534
+
4535
+function! TagList_IsValid()
4536
+    return 0
4537
+endfunction
4538
+
4539
+function! TagList_WrapUp()
4540
+    return 0
4541
+endfunction
4542
+
4543
+" restore 'cpo'
4544
+let &cpo = s:cpo_save
4545
+unlet s:cpo_save
4546
+
... ...
@@ -0,0 +1,2 @@
1
+doc/tags
2
+*.cache
... ...
@@ -0,0 +1,114 @@
1
+===================
2
+DEPRECATION WARNING
3
+===================
4
+
5
+Plugin is currently in maintenance mode, no feature requests will be accepted.
6
+Vim-powerline will be deprecated in favour of https://github.com/Lokaltog/powerline once it is ready.
7
+
8
+=================
9
+Powerline for vim
10
+=================
11
+
12
+:Author: Kim Silkebækken (kim.silkebaekken+vim@gmail.com)
13
+:Source: https://github.com/Lokaltog/vim-powerline
14
+:Version: β
15
+
16
+Introduction
17
+------------
18
+
19
+Powerline is a utility plugin which allows you to create better-looking, 
20
+more functional vim statuslines. See the screenshots below for 
21
+a demonstration of the plugin's capabilities.
22
+
23
+It's recommended that you install the plugin using Pathogen_ or Vundle_.  
24
+After the plugin is installed update your help tags and see ``:help 
25
+Powerline`` for instructions on how to enable and configure the plugin.
26
+
27
+See the `Troubleshooting`_ section below if you're having any issues with 
28
+the plugin or the font patcher.
29
+
30
+**Note:** You need a patched font to be able to use the symbols in the 
31
+statusline. An experimental Python/fontforge-based font patcher is included 
32
+in the ``fontpatcher`` directory. See ``fontpatcher/README.rst`` for usage 
33
+instructions.
34
+
35
+.. _Pathogen: https://github.com/tpope/vim-pathogen
36
+.. _Vundle: https://github.com/gmarik/vundle
37
+
38
+Screenshots
39
+-----------
40
+
41
+.. image:: http://i.imgur.com/MsuIB.png
42
+
43
+Troubleshooting
44
+---------------
45
+
46
+I can't see the fancy symbols, what's wrong?
47
+    Make sure that you have ``let g:Powerline_symbols = 'fancy'`` in your 
48
+    ``vimrc`` file. The settings may be loaded too late if you have this in 
49
+    ``gvimrc``, so always put this in your ``vimrc``.
50
+
51
+    Clear the cache using ``:PowerlineClearCache`` and restart vim.
52
+
53
+    Make sure that you've configured gvim or your terminal emulator to use 
54
+    a patched font.
55
+
56
+    Make sure that vim is compiled with the ``--with-features=big`` flag.
57
+
58
+The fancy symbols look a bit blurry or "off"!
59
+    Make sure that you have patched all variants of your font (i.e. both the 
60
+    regular and the bold font files).
61
+
62
+I'm unable to patch my font, what should I do?
63
+    Font patching is only known to work on most Linux and OS X machines. If 
64
+    you have followed the instructions in the fontpatcher README and still 
65
+    have problems, please submit an issue on GitHub.
66
+
67
+    You can download some community-contributed patched fonts from the 
68
+    `Powerline wiki`_ if you don't want to mess around with the font 
69
+    patcher.
70
+
71
+The Syntastic/Fugitive statusline flags don't work!
72
+    These flags should work without any configuration. If you installed 
73
+    either plugin after Powerline, you'll have to clear the cache using 
74
+    ``:PowerlineClearCache`` and restart vim.
75
+
76
+The colors are weird in the default OS X Terminal app!
77
+    The default OS X Terminal app is known to have some issues with the 
78
+    Powerline colors. Please use another terminal emulator. iTerm2 should 
79
+    work fine.
80
+
81
+    The arrows may have the wrong colors if you have changed the "minimum 
82
+    contrast" slider in the color tab of  your OS X settings.
83
+
84
+The statusline has strange characters like ``^B`` in it!
85
+    Please add ``set encoding=utf-8`` to your ``vimrc``.
86
+
87
+    You may also need to set your ``LANG`` and ``LC_*`` environment 
88
+    variables to a UTF-8 locale (e.g. ``LANG=en_US.utf8``). Consult your 
89
+    Linux distro's documentation for information about setting these 
90
+    variables correctly.
91
+
92
+The statusline has a lot of ``^`` or underline characters in it!
93
+    You need to configure the ``fillchars`` setting to disable statusline 
94
+    fillchars (see ``:h fillchars`` for details). Add this to your 
95
+    ``vimrc`` to solve this issue::
96
+
97
+        set fillchars+=stl:\ ,stlnc:\ 
98
+
99
+The statusline is hidden/only appears in split windows!
100
+    Make sure that you have ``set laststatus=2`` in your ``vimrc``.
101
+
102
+I'm using tmux and Powerline looks like crap, what's wrong?
103
+    You need to tell tmux that it has 256-color capabilities. Add this to 
104
+    your ``.tmux.conf`` to solve this issue::
105
+
106
+        set -g default-terminal "screen-256color"
107
+
108
+    If you use iTerm2, make sure that you have enabled the setting 'Set 
109
+    locale variables automatically' in Profiles > Terminal > Environment.
110
+
111
+If you have any other issues and you can't find the answer in the docs, 
112
+please submit an issue on GitHub.
113
+
114
+.. _`Powerline wiki`: https://github.com/Lokaltog/vim-powerline/wiki/Patched-fonts
... ...
@@ -0,0 +1,184 @@
1
+" Powerline - The ultimate statusline utility
2
+"
3
+" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
4
+" Source repository: https://github.com/Lokaltog/vim-powerline
5
+
6
+" Script variables {{{
7
+	let g:Pl#OLD_STL = ''
8
+	let g:Pl#THEME = []
9
+	let g:Pl#THEME_CALLBACKS = []
10
+	let g:Pl#HL = []
11
+
12
+	" Cache revision, this must be incremented whenever the cache format is changed
13
+	let s:CACHE_REVISION = 7
14
+" }}}
15
+" Script initialization {{{
16
+	function! Pl#LoadCache() " {{{
17
+		if filereadable(g:Powerline_cache_file) && g:Powerline_cache_enabled
18
+			exec 'source' escape(g:Powerline_cache_file, ' \')
19
+
20
+			if ! exists('g:Powerline_cache_revision') || g:Powerline_cache_revision != s:CACHE_REVISION
21
+				" Cache revision differs, cache is invalid
22
+				unlet! g:Powerline_cache_revision
23
+
24
+				return 0
25
+			endif
26
+
27
+			" Create highlighting groups
28
+			for hi_cmd in g:Pl#HL
29
+				exec hi_cmd
30
+			endfor
31
+
32
+			" Run theme callbacks
33
+			for callback in g:Pl#THEME_CALLBACKS
34
+				" Substitute {{NEWLINE}} with newlines (strings must be
35
+				" stored without newlines characters to avoid vim errors)
36
+				exec substitute(callback[0], "{{NEWLINE}}", "\n", 'g')
37
+				exec substitute(callback[1], "{{NEWLINE}}", "\n", 'g')
38
+			endfor
39
+
40
+			return 1
41
+		endif
42
+
43
+		return 0
44
+	endfunction " }}}
45
+	function! Pl#ClearCache() " {{{
46
+		if filereadable(g:Powerline_cache_file)
47
+			" Delete the cache file
48
+			call delete(g:Powerline_cache_file)
49
+		endif
50
+
51
+		echo 'Powerline cache cleared. Please restart vim for the changes to take effect.'
52
+	endfunction " }}}
53
+	function! Pl#ReloadColorscheme() " {{{
54
+		call Pl#ClearCache()
55
+
56
+		" The colorscheme and theme files must be manually sourced because
57
+		" vim won't reload previously autoloaded files
58
+		"
59
+		" This is a bit hackish, but it works
60
+		unlet! g:Powerline#Colorschemes#{g:Powerline_colorscheme}#colorscheme
61
+		exec "source" split(globpath(&rtp, 'autoload/Powerline/Colorschemes/'. g:Powerline_colorscheme .'.vim', 1), '\n')[0]
62
+
63
+		unlet! g:Powerline#Themes#{g:Powerline_theme}#theme
64
+		exec "source" split(globpath(&rtp, 'autoload/Powerline/Themes/'. g:Powerline_theme .'.vim', 1), '\n')[0]
65
+
66
+		let g:Pl#THEME = []
67
+
68
+		call Pl#Load()
69
+	endfunction " }}}
70
+	function! Pl#Load() " {{{
71
+		if empty(g:Pl#OLD_STL)
72
+			" Store old statusline
73
+			let g:Pl#OLD_STL = &statusline
74
+		endif
75
+
76
+		if ! Pl#LoadCache()
77
+			try
78
+				" Autoload the theme dict first
79
+				let raw_theme = g:Powerline#Themes#{g:Powerline_theme}#theme
80
+			catch
81
+				echom 'Invalid Powerline theme! Please check your theme and colorscheme settings.'
82
+
83
+				return
84
+			endtry
85
+
86
+			" Create list with parsed statuslines
87
+			for buffer_statusline in raw_theme
88
+				unlet! mode_statuslines
89
+				let mode_statuslines = Pl#Parser#GetStatusline(buffer_statusline.segments)
90
+
91
+				if ! empty(buffer_statusline.callback)
92
+					" The callback function passes its arguments on to
93
+					" Pl#StatuslineCallback along with the normal/current mode
94
+					" statusline.
95
+					let s:cb_func  = "function! PowerlineStatuslineCallback_". buffer_statusline.callback[1] ."(...)\n"
96
+					let s:cb_func .= "return Pl#StatuslineCallback(". string(mode_statuslines['n']) .", a:000)\n"
97
+					let s:cb_func .= "endfunction"
98
+
99
+					" The callback expression should be used to initialize any
100
+					" variables that will use the callback function. The
101
+					" expression requires a %s which will be replaced by the
102
+					" callback function name.
103
+					let s:cb_expr  = printf(buffer_statusline.callback[2], 'PowerlineStatuslineCallback_'. buffer_statusline.callback[1])
104
+
105
+					exec s:cb_func
106
+					exec s:cb_expr
107
+
108
+					" Newlines must be substituted with another character
109
+					" because vim doesn't like newlines in strings
110
+					call add(g:Pl#THEME_CALLBACKS, [substitute(s:cb_func, "\n", "{{NEWLINE}}", 'g'), substitute(s:cb_expr, "\n", "{{NEWLINE}}", 'g')])
111
+
112
+					unlet! s:cb_func s:cb_expr
113
+
114
+					continue
115
+				endif
116
+
117
+				" Store the statuslines for matching specific buffers
118
+				call add(g:Pl#THEME, {
119
+					\ 'matches': buffer_statusline.matches,
120
+					\ 'mode_statuslines': mode_statuslines
121
+					\ })
122
+			endfor
123
+
124
+			if ! g:Powerline_cache_enabled
125
+				" Don't cache anything if caching is disabled or cache file isn't writeable
126
+				return
127
+			endif
128
+
129
+			" Prepare commands and statuslines for caching
130
+			let cache = [
131
+				\ 'let g:Powerline_cache_revision = '. string(s:CACHE_REVISION),
132
+				\ 'let g:Pl#HL = '. string(g:Pl#HL),
133
+				\ 'let g:Pl#THEME  = '. string(g:Pl#THEME),
134
+				\ 'let g:Pl#THEME_CALLBACKS  = '. string(g:Pl#THEME_CALLBACKS),
135
+			\ ]
136
+
137
+			call writefile(cache, g:Powerline_cache_file)
138
+		endif
139
+	endfunction " }}}
140
+" }}}
141
+" Statusline updater {{{
142
+	function! Pl#Statusline(statusline, current) " {{{
143
+		let mode = mode()
144
+
145
+		if ! a:current
146
+			let mode = 'N' " Normal (non-current)
147
+		elseif mode =~# '\v(v|V|)'
148
+			let mode = 'v' " Visual mode
149
+		elseif mode =~# '\v(s|S|)'
150
+			let mode = 's' " Select mode
151
+		elseif mode =~# '\vi'
152
+			let mode = 'i' " Insert mode
153
+		elseif mode =~# '\v(R|Rv)'
154
+			let mode = 'r' " Replace mode
155
+		else
156
+			" Fallback to normal mode
157
+			let mode = 'n' " Normal (current)
158
+		endif
159
+
160
+		return g:Pl#THEME[a:statusline].mode_statuslines[mode]
161
+	endfunction " }}}
162
+	function! Pl#StatuslineCallback(statusline, args) " {{{
163
+		" Replace %1, %2, etc. in the statusline with the callback args
164
+		return substitute(
165
+			\ a:statusline,
166
+			\ '\v\%(\d+)',
167
+			\ '\=a:args[submatch(1)]',
168
+			\ 'g')
169
+	endfunction " }}}
170
+	function! Pl#UpdateStatusline(current, ...) " {{{
171
+		if empty(g:Pl#THEME)
172
+			" Load statuslines if they aren't loaded yet
173
+			call Pl#Load()
174
+		endif
175
+
176
+		for i in range(len(g:Pl#THEME))
177
+			if Pl#Match#Validate(g:Pl#THEME[i], a:0 ? a:1 : 0)
178
+				" Update window-local statusline
179
+				call setwinvar(a:0 ? a:1 : 0, '&statusline',
180
+				            \  '%!Pl#Statusline('. i .','. a:current .')')
181
+			endif
182
+		endfor
183
+	endfunction " }}}
184
+" }}}
... ...
@@ -0,0 +1,145 @@
1
+function! Pl#Colorscheme#Init(hi) " {{{
2
+	let colorscheme = {}
3
+
4
+	for hi in a:hi
5
+		" Ensure that the segments are a list
6
+		let segments = type(hi[0]) == type('') ? [ hi[0] ] : hi[0]
7
+		let mode_hi_dict = hi[1]
8
+
9
+		for segment in segments
10
+			let colorscheme[segment] = mode_hi_dict
11
+		endfor
12
+	endfor
13
+
14
+	return colorscheme
15
+endfunction " }}}
16
+function! Pl#Colorscheme#Apply(colorscheme, buffer_segments) " {{{
17
+	" Set color parameters for all segments in a:buffer_segments
18
+
19
+	" TODO This function should be recursive and work on both segments and groups
20
+	" TODO We could probably handle the NS stuff here...
21
+
22
+	try
23
+		let colorscheme = g:Powerline#Colorschemes#{a:colorscheme}#colorscheme
24
+	catch
25
+		echom 'Color scheme "'. a:colorscheme .'" doesn''t exist!'
26
+
27
+		return
28
+	endtry
29
+
30
+	let buffer_segments = a:buffer_segments
31
+
32
+	" This is a bit complex, I'll walk you through exactly what happens here...
33
+	"
34
+	" First of all we loop through the buffer_segments, which are the segments that
35
+	" this specific buffer will have.
36
+	for buffer_segment in buffer_segments
37
+		" The buffer_segment consists of a 'matches' list and a 'segments' list.
38
+		" The 'matches' list has conditions to limit this statusline to specific buffers/windows.
39
+		" The 'segments' list has each segment and segment group for this buffer
40
+		for segment in buffer_segment.segments
41
+			let type = get(segment, 'type', '')
42
+
43
+			if type == 'segment_group'
44
+				" We're going to handle segment groups different from single segments. Segment groups
45
+				" have child segments which may have their own highlighting (e.g. fileinfo.flags),
46
+				" and these child segments may be grouped (e.g. fileinfo.flags.ro) to provide very
47
+				" specific highlighting. So here we'll handle all that:
48
+
49
+				" Set the default/fallback colors for this group
50
+				for i in range(len(segment.variants), 0, -1)
51
+					" Check for available highlighting for the main group segment
52
+					"
53
+					" This works like the segment highlighting below
54
+					" TODO Create a function for this
55
+					let seg_variants = join(segment.variants[0:i], '.')
56
+
57
+					let seg_name = i > 0 ? segment.name .'.'. seg_variants : segment.name
58
+					let seg_ns_name = len(segment.ns) > 0 ? segment.ns .':'. seg_name : seg_name
59
+
60
+					if has_key(colorscheme, seg_ns_name)
61
+						" We have a namespaced highlight group
62
+						let segment.colors = colorscheme[seg_ns_name]
63
+						break
64
+					elseif has_key(colorscheme, seg_name)
65
+						" We have a non-namespaced group
66
+						let segment.colors = colorscheme[seg_name]
67
+						break
68
+					endif
69
+				endfor
70
+
71
+				" The reason why we need to deepcopy the group's segments is that the child segments
72
+				" all point to the same base segments and that screws up highlighting if we highlight
73
+				" some child segments with different namespaced colors
74
+				let segment.segments = deepcopy(segment.segments)
75
+
76
+				" Apply colors to each child segment
77
+				for child_segment in segment.segments
78
+					" Check if this child segment is grouped (e.g. fileinfo.flags.group.subgroup)
79
+					" We're going to prioritize the most specific grouping and then work back to the
80
+					" most common group (e.g. fileinfo.flags)
81
+
82
+					" FIXME We don't have the variants from before because group children aren't run through Pl#Segment#Get
83
+					let child_segment.variants = [seg_name] + split(child_segment.name, '\.')
84
+
85
+					" Use the parent group's namespace
86
+					let child_segment.ns = segment.ns
87
+
88
+					for i in range(len(child_segment.variants), 0, -1)
89
+						" Check for available highlighting for the main group segment
90
+						let child_seg_name = join(child_segment.variants[0:i], '.')
91
+
92
+						let child_seg_ns_name = len(child_segment.ns) > 0 ? child_segment.ns .':'. child_seg_name : child_seg_name
93
+
94
+						if has_key(colorscheme, child_seg_ns_name)
95
+							" We have a namespaced highlight group
96
+							let child_segment.colors = colorscheme[child_seg_ns_name]
97
+							break
98
+						elseif has_key(colorscheme, child_seg_name)
99
+							" We have a non-namespaced group
100
+							let child_segment.colors = colorscheme[child_seg_name]
101
+							break
102
+						endif
103
+					endfor
104
+				endfor
105
+			elseif type == 'segment'
106
+				for i in range(len(segment.variants), 0, -1)
107
+					" Check for available highlighting
108
+					"
109
+					" This is done in the following manner, using the segment gundo:static_filename.text.buffer as an example:
110
+					"
111
+					" * Look for the hl group: gundo:static_filename.text.buffer
112
+					" * Look for the hl group:       static_filename.text.buffer
113
+					" * Look for the hl group: gundo:static_filename.text
114
+					" * Look for the hl group:       static_filename.text
115
+					" * Look for the hl group: gundo:static_filename
116
+					" * Look for the hl group:       static_filename
117
+					" * Return the segment without highlighting, causing an error in the parser
118
+					let seg_variants = join(segment.variants[0:i], '.')
119
+
120
+					let seg_name = i > 0 ? segment.name .'.'. seg_variants : segment.name
121
+					let seg_ns_name = len(segment.ns) > 0 ? segment.ns .':'. seg_name : seg_name
122
+
123
+					if has_key(colorscheme, seg_ns_name)
124
+						" We have a namespaced highlight group
125
+						let segment.colors = colorscheme[seg_ns_name]
126
+						break
127
+					elseif has_key(colorscheme, seg_name)
128
+						" We have a non-namespaced group
129
+						let segment.colors = colorscheme[seg_name]
130
+						break
131
+					endif
132
+				endfor
133
+			endif
134
+
135
+			unlet! segment
136
+		endfor
137
+	endfor
138
+
139
+	" Good luck parsing this return value
140
+	"
141
+	" It's a huge dict with all segments for all buffers with their respective syntax highlighting.
142
+	" It will be parsed by the main Powerline code, where all the data will be shortened to a simple
143
+	" array consiting of a statusline for each mode, with generated highlighting groups and dividers.
144
+	return buffer_segments
145
+endfunction " }}}
... ...
@@ -0,0 +1,140 @@
1
+" cterm -> gui color dict {{{
2
+let s:cterm2gui_dict = {
3
+	\ 16:  0x000000, 17:  0x00005f, 18:  0x000087, 19:  0x0000af, 20:  0x0000d7, 21:  0x0000ff,
4
+	\ 22:  0x005f00, 23:  0x005f5f, 24:  0x005f87, 25:  0x005faf, 26:  0x005fd7, 27:  0x005fff,
5
+	\ 28:  0x008700, 29:  0x00875f, 30:  0x008787, 31:  0x0087af, 32:  0x0087d7, 33:  0x0087ff,
6
+	\ 34:  0x00af00, 35:  0x00af5f, 36:  0x00af87, 37:  0x00afaf, 38:  0x00afd7, 39:  0x00afff,
7
+	\ 40:  0x00d700, 41:  0x00d75f, 42:  0x00d787, 43:  0x00d7af, 44:  0x00d7d7, 45:  0x00d7ff,
8
+	\ 46:  0x00ff00, 47:  0x00ff5f, 48:  0x00ff87, 49:  0x00ffaf, 50:  0x00ffd7, 51:  0x00ffff,
9
+	\ 52:  0x5f0000, 53:  0x5f005f, 54:  0x5f0087, 55:  0x5f00af, 56:  0x5f00d7, 57:  0x5f00ff,
10
+	\ 58:  0x5f5f00, 59:  0x5f5f5f, 60:  0x5f5f87, 61:  0x5f5faf, 62:  0x5f5fd7, 63:  0x5f5fff,
11
+	\ 64:  0x5f8700, 65:  0x5f875f, 66:  0x5f8787, 67:  0x5f87af, 68:  0x5f87d7, 69:  0x5f87ff,
12
+	\ 70:  0x5faf00, 71:  0x5faf5f, 72:  0x5faf87, 73:  0x5fafaf, 74:  0x5fafd7, 75:  0x5fafff,
13
+	\ 76:  0x5fd700, 77:  0x5fd75f, 78:  0x5fd787, 79:  0x5fd7af, 80:  0x5fd7d7, 81:  0x5fd7ff,
14
+	\ 82:  0x5fff00, 83:  0x5fff5f, 84:  0x5fff87, 85:  0x5fffaf, 86:  0x5fffd7, 87:  0x5fffff,
15
+	\ 88:  0x870000, 89:  0x87005f, 90:  0x870087, 91:  0x8700af, 92:  0x8700d7, 93:  0x8700ff,
16
+	\ 94:  0x875f00, 95:  0x875f5f, 96:  0x875f87, 97:  0x875faf, 98:  0x875fd7, 99:  0x875fff,
17
+	\ 100: 0x878700, 101: 0x87875f, 102: 0x878787, 103: 0x8787af, 104: 0x8787d7, 105: 0x8787ff,
18
+	\ 106: 0x87af00, 107: 0x87af5f, 108: 0x87af87, 109: 0x87afaf, 110: 0x87afd7, 111: 0x87afff,
19
+	\ 112: 0x87d700, 113: 0x87d75f, 114: 0x87d787, 115: 0x87d7af, 116: 0x87d7d7, 117: 0x87d7ff,
20
+	\ 118: 0x87ff00, 119: 0x87ff5f, 120: 0x87ff87, 121: 0x87ffaf, 122: 0x87ffd7, 123: 0x87ffff,
21
+	\ 124: 0xaf0000, 125: 0xaf005f, 126: 0xaf0087, 127: 0xaf00af, 128: 0xaf00d7, 129: 0xaf00ff,
22
+	\ 130: 0xaf5f00, 131: 0xaf5f5f, 132: 0xaf5f87, 133: 0xaf5faf, 134: 0xaf5fd7, 135: 0xaf5fff,
23
+	\ 136: 0xaf8700, 137: 0xaf875f, 138: 0xaf8787, 139: 0xaf87af, 140: 0xaf87d7, 141: 0xaf87ff,
24
+	\ 142: 0xafaf00, 143: 0xafaf5f, 144: 0xafaf87, 145: 0xafafaf, 146: 0xafafd7, 147: 0xafafff,
25
+	\ 148: 0xafd700, 149: 0xafd75f, 150: 0xafd787, 151: 0xafd7af, 152: 0xafd7d7, 153: 0xafd7ff,
26
+	\ 154: 0xafff00, 155: 0xafff5f, 156: 0xafff87, 157: 0xafffaf, 158: 0xafffd7, 159: 0xafffff,
27
+	\ 160: 0xd70000, 161: 0xd7005f, 162: 0xd70087, 163: 0xd700af, 164: 0xd700d7, 165: 0xd700ff,
28
+	\ 166: 0xd75f00, 167: 0xd75f5f, 168: 0xd75f87, 169: 0xd75faf, 170: 0xd75fd7, 171: 0xd75fff,
29
+	\ 172: 0xd78700, 173: 0xd7875f, 174: 0xd78787, 175: 0xd787af, 176: 0xd787d7, 177: 0xd787ff,
30
+	\ 178: 0xd7af00, 179: 0xd7af5f, 180: 0xd7af87, 181: 0xd7afaf, 182: 0xd7afd7, 183: 0xd7afff,
31
+	\ 184: 0xd7d700, 185: 0xd7d75f, 186: 0xd7d787, 187: 0xd7d7af, 188: 0xd7d7d7, 189: 0xd7d7ff,
32
+	\ 190: 0xd7ff00, 191: 0xd7ff5f, 192: 0xd7ff87, 193: 0xd7ffaf, 194: 0xd7ffd7, 195: 0xd7ffff,
33
+	\ 196: 0xff0000, 197: 0xff005f, 198: 0xff0087, 199: 0xff00af, 200: 0xff00d7, 201: 0xff00ff,
34
+	\ 202: 0xff5f00, 203: 0xff5f5f, 204: 0xff5f87, 205: 0xff5faf, 206: 0xff5fd7, 207: 0xff5fff,
35
+	\ 208: 0xff8700, 209: 0xff875f, 210: 0xff8787, 211: 0xff87af, 212: 0xff87d7, 213: 0xff87ff,
36
+	\ 214: 0xffaf00, 215: 0xffaf5f, 216: 0xffaf87, 217: 0xffafaf, 218: 0xffafd7, 219: 0xffafff,
37
+	\ 220: 0xffd700, 221: 0xffd75f, 222: 0xffd787, 223: 0xffd7af, 224: 0xffd7d7, 225: 0xffd7ff,
38
+	\ 226: 0xffff00, 227: 0xffff5f, 228: 0xffff87, 229: 0xffffaf, 230: 0xffffd7, 231: 0xffffff,
39
+	\ 232: 0x080808, 233: 0x121212, 234: 0x1c1c1c, 235: 0x262626, 236: 0x303030, 237: 0x3a3a3a,
40
+	\ 238: 0x444444, 239: 0x4e4e4e, 240: 0x585858, 241: 0x626262, 242: 0x6c6c6c, 243: 0x767676,
41
+	\ 244: 0x808080, 245: 0x8a8a8a, 246: 0x949494, 247: 0x9e9e9e, 248: 0xa8a8a8, 249: 0xb2b2b2,
42
+	\ 250: 0xbcbcbc, 251: 0xc6c6c6, 252: 0xd0d0d0, 253: 0xdadada, 254: 0xe4e4e4, 255: 0xeeeeee
43
+\ }
44
+" }}}
45
+" Allocated color dict {{{
46
+let s:allocated_colors = {
47
+	\ 'NONE': 'NONE',
48
+	\ }
49
+" }}}
50
+function! s:Cterm2GUI(cterm) " {{{
51
+	if toupper(a:cterm) == 'NONE'
52
+		return 'NONE'
53
+	endif
54
+
55
+	if ! has_key(s:cterm2gui_dict, a:cterm)
56
+		return 0xff0000
57
+	endif
58
+
59
+	return s:cterm2gui_dict[a:cterm]
60
+endfunction " }}}
61
+function! Pl#Hi#Segments(segments, mode_colors) " {{{
62
+	let mode_translate = {
63
+		\ 'normal':     'n',
64
+		\ 'noncurrent': 'N',
65
+		\ 'insert':     'i',
66
+		\ 'visual':     'v',
67
+		\ 'replace':    'r',
68
+		\ 'select':     's',
69
+		\ }
70
+
71
+	let attributes = ['bold', 'italic', 'underline']
72
+
73
+	let segments = a:segments
74
+	let mode_hi_dict = {}
75
+
76
+	" Mode dict
77
+	for [mode, colors] in items(a:mode_colors)
78
+		if has_key(mode_translate, mode)
79
+			let mode = mode_translate[mode]
80
+		endif
81
+
82
+		unlet! fg
83
+		let fg = s:allocated_colors[colors[0]]
84
+
85
+		let hi = {
86
+			\ 'cterm': [fg['cterm'], ''],
87
+			\ 'gui'  : [fg['gui'], ''],
88
+			\ 'attr' : []
89
+			\ }
90
+
91
+		if exists('colors[1]')
92
+			if type(colors[1]) == type([])
93
+				" We don't have a BG color, but we have attributes
94
+				let hi.attr = colors[1]
95
+			else
96
+				" The second parameter is the background color
97
+				unlet! bg
98
+				let bg = s:allocated_colors[colors[1]]
99
+
100
+				let hi.cterm[1] = bg['cterm']
101
+				let hi.gui[1] = bg['gui']
102
+			endif
103
+		endif
104
+
105
+		if exists('colors[2]') && type(colors[2]) == type([])
106
+			" The third parameter is always an attribute list
107
+			let hi.attr = colors[2]
108
+		endif
109
+
110
+		let mode_hi_dict[mode] = {
111
+			\ 'ctermfg': (empty(hi['cterm'][0]) ? '' : (string(hi['cterm'][0]) == 'NONE' ? 'NONE' : hi['cterm'][0])),
112
+			\ 'ctermbg': (empty(hi['cterm'][1]) ? '' : (string(hi['cterm'][1]) == 'NONE' ? 'NONE' : hi['cterm'][1])),
113
+			\ 'guifg'  : (empty(hi['gui'][0]) ? '' : (string(hi['gui'][0]) == 'NONE' ? 'NONE' : hi['gui'][0])),
114
+			\ 'guibg'  : (empty(hi['gui'][1]) ? '' : (string(hi['gui'][1]) == 'NONE' ? 'NONE' : hi['gui'][1])),
115
+			\ 'attr'   : (! len(hi['attr']) ? 'NONE' : join(hi['attr'], ','))
116
+			\ }
117
+	endfor
118
+
119
+	return [segments, mode_hi_dict]
120
+endfunction " }}}
121
+function! Pl#Hi#Allocate(colors) " {{{
122
+	for [key, color] in items(a:colors)
123
+		if type(color) == type(0)
124
+			" Only terminal color
125
+			let cterm = color
126
+			let gui = s:Cterm2GUI(color)
127
+		elseif type(color) == type([]) && len(color) == 2
128
+			" Terminal and GUI colors
129
+			let cterm = color[0]
130
+			let gui = color[1]
131
+		endif
132
+
133
+		let s:allocated_colors[key] = {
134
+			\ 'cterm': cterm,
135
+			\ 'gui': gui,
136
+			\ }
137
+
138
+		unlet! color
139
+	endfor
140
+endfunction " }}}
... ...
@@ -0,0 +1,43 @@
1
+function! Pl#Match#Add(pat, expr) " {{{
2
+	return [a:pat, a:expr]
3
+endfunction " }}}
4
+function! Pl#Match#Any(...) " {{{
5
+	let matches = []
6
+
7
+	for match_name in a:000
8
+		if empty(match_name)
9
+			" Skip empty match parameters
10
+			continue
11
+		endif
12
+
13
+		if has_key(g:Powerline#Matches#matches, match_name)
14
+			call add(matches, g:Powerline#Matches#matches[match_name])
15
+		endif
16
+
17
+		unlet! match_name
18
+	endfor
19
+
20
+	return ['match', 'any', matches]
21
+endfunction " }}}
22
+function! Pl#Match#Validate(theme, window) " {{{
23
+	let match = a:theme.matches[1]
24
+
25
+	if match == 'none'
26
+		return 0
27
+	elseif match == 'any'
28
+		let matches = a:theme.matches[2]
29
+
30
+		if ! len(matches)
31
+			" Empty match array matches everything
32
+			return 1
33
+		endif
34
+
35
+		for [eval, re] in matches
36
+			if match(eval(eval), '\v\C'. re) != -1
37
+				return 1
38
+			endif
39
+		endfor
40
+
41
+		return 0
42
+	endif
43
+endfunction " }}}
... ...
@@ -0,0 +1,40 @@
1
+let s:segment_mods = []
2
+
3
+function! Pl#Mod#AddSegmentMod(action, properties) " {{{
4
+	call add(s:segment_mods, [a:action, a:properties])
5
+endfunction " }}}
6
+function! Pl#Mod#ApplySegmentMods(theme) " {{{
7
+	let theme = deepcopy(a:theme)
8
+
9
+	for mod in s:segment_mods
10
+		let [action, properties] = mod
11
+
12
+		" We have to loop through the segments instead of using index() because some
13
+		" segments are lists!
14
+		let target_seg_idx = -1
15
+
16
+		for i in range(0, len(theme) - 1)
17
+			unlet! segment
18
+			let segment = theme[i]
19
+
20
+			if type(segment) == type(properties.target_segment) && segment == properties.target_segment
21
+				let target_seg_idx = i
22
+				break
23
+			endif
24
+		endfor
25
+
26
+		if action == 'insert_segment'
27
+			" Insert segment
28
+			if target_seg_idx != -1
29
+				call insert(theme, properties.new_segment, (properties.where == 'before' ? target_seg_idx : target_seg_idx + 1))
30
+			endif
31
+		elseif action == 'remove_segment'
32
+			" Remove segment
33
+			if target_seg_idx != -1
34
+				call remove(theme, target_seg_idx)
35
+			endif
36
+		endif
37
+	endfor
38
+
39
+	return theme
40
+endfunction " }}}
... ...
@@ -0,0 +1,371 @@
1
+let g:Pl#Parser#Symbols = {
2
+	\ 'compatible': {
3
+		\   'dividers': [ '', [0x2502], '', [0x2502] ]
4
+		\ , 'symbols' : {
5
+			\   'BRANCH': 'BR:'
6
+			\ , 'RO'    : 'RO'
7
+			\ , 'FT'    : 'FT'
8
+			\ , 'LINE'  : 'LN'
9
+		\ }
10
+	\ },
11
+	\ 'unicode': {
12
+		\   'dividers': [ [0x25b6], [0x276f], [0x25c0], [0x276e]  ]
13
+		\ , 'symbols' : {
14
+			\   'BRANCH': [0x26a1]
15
+			\ , 'RO'    : [0x2613]
16
+			\ , 'FT'    : [0x2691]
17
+			\ , 'LINE'  : [0x204b]
18
+		\ },
19
+	\ },
20
+	\ 'fancy': {
21
+		\   'dividers': [ [0x2b80], [0x2b81], [0x2b82], [0x2b83] ]
22
+		\ , 'symbols' : {
23
+			\   'BRANCH': [0x2b60]
24
+			\ , 'RO'    : [0x2b64]
25
+			\ , 'FT'    : [0x2b62, 0x2b63]
26
+			\ , 'LINE'  : [0x2b61]
27
+		\ }
28
+	\ }
29
+\ }
30
+
31
+" Handle symbol overrides
32
+for [s:key, s:value] in items(g:Powerline_symbols_override)
33
+	let g:Pl#Parser#Symbols[g:Powerline_symbols].symbols[s:key] = s:value
34
+
35
+	unlet! s:key s:value
36
+endfor
37
+
38
+" Handle divider overrides
39
+if len(g:Powerline_dividers_override) == 4
40
+	let g:Pl#Parser#Symbols[g:Powerline_symbols].dividers = g:Powerline_dividers_override
41
+endif
42
+
43
+let s:LEFT_SIDE = 0
44
+let s:RIGHT_SIDE = 2
45
+
46
+let s:PADDING = 1
47
+
48
+let s:EMPTY_SEGMENT = { 'type': 'empty' }
49
+
50
+let s:HARD_DIVIDER = 0
51
+let s:SOFT_DIVIDER = 1
52
+
53
+function! Pl#Parser#GetStatusline(segments) " {{{
54
+	let statusline = {
55
+		\   'n': ''
56
+		\ , 'N': ''
57
+		\ , 'v': ''
58
+		\ , 'i': ''
59
+		\ , 'r': ''
60
+		\ , 's': ''
61
+		\ }
62
+
63
+	" Run through the different modes and create the statuslines
64
+	for mode in keys(statusline)
65
+		" Create an empty statusline list
66
+		let stl = []
67
+
68
+		call extend(stl, s:ParseSegments(mode, s:LEFT_SIDE, a:segments))
69
+
70
+		let statusline[mode] .= join(stl, '')
71
+	endfor
72
+
73
+	return statusline
74
+endfunction " }}}
75
+function! Pl#Parser#ParseChars(arg) " {{{
76
+	" Handles symbol arrays which can be either an array of hex values,
77
+	" or a string. Will convert the hex array to a string, or return the
78
+	" string as-is.
79
+	let arg = a:arg
80
+
81
+	if type(arg) == type([])
82
+		" Hex array
83
+		call map(arg, 'nr2char(v:val)')
84
+
85
+		return join(arg, '')
86
+	endif
87
+
88
+	" Anything else, just return it as it is
89
+	return arg
90
+endfunction " }}}
91
+function! s:ParseSegments(mode, side, segments, ...) " {{{
92
+	let mode     = a:mode
93
+	let side     = a:side
94
+	let segments = a:segments
95
+
96
+	let level      = exists('a:1') ? a:1 : 0
97
+	let base_color = exists('a:2') ? a:2 : {}
98
+
99
+	let ret = []
100
+
101
+	for i in range(0, len(segments) - 1)
102
+		unlet! seg_prev seg_curr seg_next
103
+
104
+		" Prepare some resources (fetch previous, current and next segment)
105
+		let seg_curr = deepcopy(get(segments, i))
106
+
107
+		" Find previous segment
108
+		let seg_prev = s:EMPTY_SEGMENT
109
+
110
+		" If we're currently at i = 0 we have to start on 0 or else we will start on the last segment (list[-1])
111
+		let range_start = (i == 0 ? i : i - 1)
112
+		for j in range(range_start, 0, -1)
113
+			let seg = deepcopy(get(segments, j))
114
+			if get(seg, 'name') ==# 'TRUNCATE'
115
+				" Skip truncate segments
116
+				continue
117
+			endif
118
+
119
+			" Look ahead for another segment that's visible in this mode
120
+			if index(get(seg, 'modes'), mode) != -1
121
+				" Use this segment
122
+				let seg_prev = seg
123
+
124
+				break
125
+			endif
126
+		endfor
127
+
128
+		"" Find next segment
129
+		let seg_next = s:EMPTY_SEGMENT
130
+
131
+		" If we're currently at i = len(segments) - 1 we have to start on i or else we will get an error because the index doesn't exist
132
+		let range_start = (i == len(segments) - 1 ? i : i + 1)
133
+		for j in range(range_start, len(segments) - 1, 1)
134
+			let seg = deepcopy(get(segments, j))
135
+			if get(seg, 'name') ==# 'TRUNCATE'
136
+				" Skip truncate segments
137
+				continue
138
+			endif
139
+
140
+			" Look ahead for another segment that's visible in this mode
141
+			if index(get(seg, 'modes'), mode) != -1
142
+				" Use this segment
143
+				let seg_next = seg
144
+
145
+				break
146
+			endif
147
+		endfor
148
+
149
+		if index(get(seg_curr, 'modes', []), mode) == -1
150
+			" The segment is invisible in this mode, skip it
151
+			" FIXME When two segments after each other are hidden, a gap appears where the segments would be, this is probably due to segment padding
152
+			continue
153
+		endif
154
+
155
+		" Handle the different segment types
156
+		if seg_curr.type == 'segment'
157
+			if seg_curr.name ==# 'TRUNCATE'
158
+				" Truncate statusline
159
+				call add(ret, '%<')
160
+			elseif seg_curr.name ==# 'SPLIT'
161
+				" Split statusline
162
+
163
+				" Switch sides
164
+				let side = s:RIGHT_SIDE
165
+
166
+				" Handle highlighting
167
+				let mode_colors = get(seg_curr.colors, mode, seg_curr.colors['n'])
168
+				let hl_group = s:HlCreate(mode_colors)
169
+
170
+				" Add segment text
171
+				call add(ret, '%#'. hl_group .'#%=')
172
+			else
173
+				" Add segment text
174
+				let text = seg_curr.text
175
+
176
+				" Decide on whether to use the group's colors or the segment's colors
177
+				let colors = get(seg_curr, 'colors', base_color)
178
+
179
+				" Fallback to normal (current) highlighting if we don't have mode-specific highlighting
180
+				let mode_colors = get(colors, mode, get(colors, 'n', {}))
181
+
182
+				if empty(mode_colors)
183
+					echom 'Segment doesn''t have any colors! NS: "'. seg_curr.ns .'" SEG: "'. seg_curr.name .'"'
184
+
185
+					continue
186
+				endif
187
+
188
+				" Check if we're in a group (level > 0)
189
+				if level > 0
190
+					" If we're in a group we don't have dividers between
191
+					" segments, so we should only pad one side, but only pad
192
+					" if the segment doesn't have Pl#Segment#NoPadding() set
193
+					let padding_right = (seg_curr.padding && side == s:LEFT_SIDE  ? repeat(' ', s:PADDING) : '')
194
+					let padding_left  = (seg_curr.padding && side == s:RIGHT_SIDE ? repeat(' ', s:PADDING) : '')
195
+
196
+					" Check if we lack a bg/fg color for this segment
197
+					" If we do, use the bg/fg color from base_color
198
+					let base_color_mode = ! has_key(base_color, mode) ? base_color['n'] : base_color[mode]
199
+
200
+					for col in ['ctermbg', 'ctermfg', 'guibg', 'guifg']
201
+						if empty(mode_colors[col])
202
+							let mode_colors[col] = base_color_mode[col]
203
+						endif
204
+					endfor
205
+				else
206
+					"" If we're outside a group we have dividers and must pad both sides
207
+					let padding_left  = repeat(' ', s:PADDING)
208
+					let padding_right = repeat(' ', s:PADDING)
209
+				endif
210
+
211
+				" Get main hl group for segment
212
+				let hl_group = s:HlCreate(mode_colors)
213
+
214
+				" Prepare segment text
215
+				let text = '%(%#'. hl_group .'#'. padding_left . text . padding_right . '%)'
216
+
217
+				if level == 0
218
+					" Add divider to single segments
219
+					let text = s:AddDivider(text, side, mode, colors, seg_prev, seg_curr, seg_next)
220
+				endif
221
+
222
+				call add(ret, text)
223
+			endif
224
+		elseif seg_curr.type == 'segment_group'
225
+			" Recursively parse segment group
226
+			let func_params = [mode, side, seg_curr.segments, level + 1]
227
+
228
+			if has_key(seg_curr, 'colors')
229
+				" Pass the base colors on to the child segments
230
+				call add(func_params, seg_curr.colors)
231
+			endif
232
+
233
+			" Get segment group string
234
+			let text = join(call('s:ParseSegments', func_params), '')
235
+
236
+			" Pad on the opposite side of the divider
237
+			let padding_right = (side == s:RIGHT_SIDE ? repeat(' ', s:PADDING) : '')
238
+			let padding_left  = (side == s:LEFT_SIDE  ? repeat(' ', s:PADDING) : '')
239
+
240
+			let text = s:AddDivider(padding_left . text . padding_right, side, mode, seg_curr.colors, seg_prev, seg_curr, seg_next)
241
+
242
+			call add(ret, text)
243
+		endif
244
+	endfor
245
+
246
+	return ret
247
+endfunction " }}}
248
+function! s:HlCreate(hl) " {{{
249
+	" Create a short and unique highlighting group name
250
+	" It uses the hex values of all the color properties and an attribute flag at the end
251
+	" NONE colors are translated to NN for cterm and NNNNNN for gui colors
252
+	let hi_group = printf('Pl%s%s%s%s%s'
253
+		\ , (a:hl['ctermfg'] == 'NONE' ? 'NN'     : printf('%02x', a:hl['ctermfg']))
254
+		\ , (a:hl['guifg']   == 'NONE' ? 'NNNNNN' : printf('%06x', a:hl['guifg']  ))
255
+		\ , (a:hl['ctermbg'] == 'NONE' ? 'NN'     : printf('%02x', a:hl['ctermbg']))
256
+		\ , (a:hl['guibg']   == 'NONE' ? 'NNNNNN' : printf('%06x', a:hl['guibg']  ))
257
+		\ , substitute(a:hl['attr'], '\v([a-zA-Z])[a-zA-Z]*,?', '\1', 'g')
258
+		\ )
259
+
260
+	if ! s:HlExists(hi_group)
261
+		let ctermbg = a:hl['ctermbg'] == 'NONE' ? 'NONE' : printf('%d', a:hl['ctermbg'])
262
+		if (has('win32') || has('win64')) && !has('gui_running') && ctermbg != 'NONE' && ctermbg > 128
263
+			let ctermbg -= 128
264
+		endif
265
+		let hi_cmd = printf('hi %s ctermfg=%s ctermbg=%s cterm=%s guifg=%s guibg=%s gui=%s'
266
+			\ , hi_group
267
+			\ , a:hl['ctermfg'] == 'NONE' ? 'NONE' : printf('%d', a:hl['ctermfg'])
268
+			\ , ctermbg
269
+			\ , a:hl['attr']
270
+			\ , (a:hl['guifg'] == 'NONE' ? 'NONE' : printf('#%06x', a:hl['guifg']))
271
+			\ , (a:hl['guibg'] == 'NONE' ? 'NONE' : printf('#%06x', a:hl['guibg']))
272
+			\ , a:hl['attr']
273
+			\ )
274
+
275
+		exec hi_cmd
276
+
277
+		" Add command to Pl#HL list for caching
278
+		call add(g:Pl#HL, hi_cmd)
279
+	endif
280
+
281
+	" Return only the highlighting group name
282
+	return hi_group
283
+endfunction " }}}
284
+function! s:HlExists(hl) " {{{
285
+	if ! hlexists(a:hl)
286
+		return 0
287
+	endif
288
+
289
+	redir => hlstatus
290
+	silent exec 'hi' a:hl
291
+	redir END
292
+
293
+	return (hlstatus !~ 'cleared')
294
+endfunction " }}}
295
+function! s:AddDivider(text, side, mode, colors, prev, curr, next) " {{{
296
+	let seg_prev = a:prev
297
+	let seg_curr = a:curr
298
+	let seg_next = a:next
299
+
300
+	" Set default color/type for the divider
301
+	let div_colors = get(a:colors, a:mode, a:colors['n'])
302
+	let div_type = s:SOFT_DIVIDER
303
+
304
+	" Define segment to compare
305
+	let cmp_seg = a:side == s:LEFT_SIDE ? seg_next : seg_prev
306
+
307
+	let cmp_all_colors = get(cmp_seg, 'colors', {})
308
+	let cmp_colors = get(cmp_all_colors, a:mode, get(cmp_all_colors, 'n', {}))
309
+
310
+	if ! empty(cmp_colors)
311
+		" Compare the highlighting groups
312
+		"
313
+		" If the background color for cterm is equal, use soft divider with the current segment's highlighting
314
+		" If not, use hard divider with a new highlighting group
315
+		"
316
+		" Note that if the previous/next segment is the split, a hard divider is always used
317
+		if get(div_colors, 'ctermbg') != get(cmp_colors, 'ctermbg') || get(seg_next, 'name') ==# 'SPLIT' || get(seg_prev, 'name') ==# 'SPLIT'
318
+			let div_type = s:HARD_DIVIDER
319
+
320
+			" Create new highlighting group
321
+			if div_colors['attr'] =~ 'reverse' && cmp_colors['attr'] =~ 'reverse'
322
+				" Use FG = CURRENT FG, BG = CMP FG
323
+				let div_colors['ctermbg'] = get(cmp_colors, 'ctermfg')
324
+				let div_colors['guibg']   = get(cmp_colors, 'guifg')
325
+
326
+				let div_colors['attr']    = div_colors['attr'] =~ 'bold' ? 'bold' : 'NONE'
327
+			elseif div_colors['attr'] =~ 'reverse'
328
+				" Use FG = CURRENT FG, BG = CMP BG
329
+				let div_colors['ctermbg'] = get(cmp_colors, 'ctermbg')
330
+				let div_colors['guibg']   = get(cmp_colors, 'guibg')
331
+
332
+				let div_colors['attr']    = div_colors['attr'] =~ 'bold' ? 'bold' : 'NONE'
333
+			elseif cmp_colors['attr'] =~ 'reverse'
334
+				" Use FG = CMP FG, BG = CURRENT BG : reversed
335
+				let div_colors['ctermfg'] = get(cmp_colors, 'ctermfg')
336
+				let div_colors['guifg']   = get(cmp_colors, 'guifg')
337
+
338
+				let div_colors['attr']    = 'reverse'
339
+
340
+			else
341
+				" Use FG = CURRENT BG, BG = CMP BG
342
+				let div_colors['ctermfg'] = get(div_colors, 'ctermbg')
343
+				let div_colors['guifg']   = get(div_colors, 'guibg')
344
+
345
+				let div_colors['ctermbg'] = get(cmp_colors, 'ctermbg')
346
+				let div_colors['guibg']   = get(cmp_colors, 'guibg')
347
+
348
+				let div_colors['attr']    = 'NONE'
349
+			endif
350
+		endif
351
+	endif
352
+
353
+	" Prepare divider
354
+	let divider_raw = deepcopy(g:Pl#Parser#Symbols[g:Powerline_symbols].dividers[a:side + div_type])
355
+	let divider = Pl#Parser#ParseChars(divider_raw)
356
+
357
+	" Don't add dividers for segments adjacent to split (unless it's a hard divider)
358
+	if ((get(seg_next, 'name') ==# 'SPLIT' || get(seg_prev, 'name') ==# 'SPLIT') && div_type != s:HARD_DIVIDER)
359
+		return ''
360
+	endif
361
+
362
+	if a:side == s:LEFT_SIDE
363
+		" Left side
364
+		" Divider to the right
365
+		return printf('%%(%s%%#%s#%s%%)', a:text, s:HlCreate(div_colors), divider)
366
+	else
367
+		" Right side
368
+		" Divider to the left
369
+		return printf('%%(%%#%s#%s%s%%)', s:HlCreate(div_colors), divider, a:text)
370
+	endif
371
+endfunction " }}}
... ...
@@ -0,0 +1,188 @@
1
+let s:default_modes = ['n', 'N', 'v', 'i', 'r', 's']
2
+
3
+function! s:CheckConditions(params) " {{{
4
+	" Check conditions for a segment/group
5
+	" Integer parameters are always conditions
6
+	for param in a:params
7
+		if type(param) == type(0) && param == 0
8
+			" Break here if it's an integer parameter and it's false (0)
9
+			return 0
10
+		endif
11
+		unlet! param
12
+	endfor
13
+
14
+	return 1
15
+endfunction " }}}
16
+function! Pl#Segment#Create(name, ...) " {{{
17
+	" Check condition parameters
18
+	if ! s:CheckConditions(a:000)
19
+		return {}
20
+	endif
21
+
22
+	let name = a:name
23
+	let modes = s:default_modes
24
+	let padding = 1
25
+	let segments = []
26
+
27
+	for param in a:000
28
+		" Lookup modes for this segment/group
29
+		if type(param) == type([]) && param[0] == 'modes'
30
+			let modes = param[1]
31
+		elseif type(param) == type([]) && param[0] == 'nopadding'
32
+			let padding = 0
33
+		elseif type(a:1) == type([]) && a:1[0] == 'segment'
34
+			call add(segments, param[1])
35
+		endif
36
+
37
+		unlet! param
38
+	endfor
39
+
40
+	if type(a:1) == type([]) && a:1[0] == 'segment'
41
+		" This is a segment group
42
+		return ['segment_group', {
43
+			\   'type': 'segment_group'
44
+			\ , 'name': name
45
+			\ , 'segments': segments
46
+			\ , 'modes': modes
47
+			\ , 'padding': padding
48
+			\ }]
49
+	else
50
+		" This is a single segment
51
+		let text = a:1
52
+
53
+		" Search/replace symbols
54
+		for [key, symbol] in items(g:Pl#Parser#Symbols[g:Powerline_symbols].symbols)
55
+			let text = substitute(
56
+				\ text,
57
+				\ '\v\$('. key .')',
58
+				\ '\=Pl#Parser#ParseChars(g:Pl#Parser#Symbols[g:Powerline_symbols].symbols[submatch(1)])',
59
+				\ 'g')
60
+
61
+			unlet! key symbol
62
+		endfor
63
+
64
+		return ['segment', {
65
+			\   'type': 'segment'
66
+			\ , 'name': name
67
+			\ , 'text': text
68
+			\ , 'modes': modes
69
+			\ , 'padding': padding
70
+			\ }]
71
+	endif
72
+
73
+endfunction " }}}
74
+function! Pl#Segment#Init(params) " {{{
75
+	" Check condition parameters
76
+	if ! s:CheckConditions(a:params)
77
+		return {}
78
+	endif
79
+
80
+	let segments = {}
81
+	let ns = ''
82
+
83
+	for param in a:params
84
+		if type(param) == type('')
85
+			" String parameters is the namespace
86
+			let ns = param
87
+		elseif type(param) == type([])
88
+			" The data dict is in param[1]
89
+			" By default we don't have a namespace for the segment
90
+			let segment = param[1]
91
+
92
+			if ! empty(ns)
93
+				" Update segment so that it includes the namespace
94
+				" Add the namespace to the segment dict key
95
+				let segment.ns = ns
96
+				let segment.name = join([segment.ns, segment.name], ':')
97
+			endif
98
+
99
+			let key = segment.name
100
+
101
+			let segments[key] = segment
102
+		endif
103
+
104
+		unlet! param
105
+	endfor
106
+
107
+	return segments
108
+endfunction " }}}
109
+function! Pl#Segment#Modes(modes) " {{{
110
+	" Handle modes for both segments and groups
111
+	let modes = split(a:modes, '\zs')
112
+
113
+	if modes[0] == '!'
114
+		" Filter modes (e.g. "!nr" will ignore the segment in normal and replace modes)
115
+		let modes = filter(deepcopy(s:default_modes), 'v:val !~# "['. join(modes[1:]) .']"')
116
+	endif
117
+
118
+	return ['modes', modes]
119
+endfunction " }}}
120
+function! Pl#Segment#NoPadding() " {{{
121
+	return ['nopadding']
122
+endfunction " }}}
123
+function! Pl#Segment#Split(...) " {{{
124
+	return a:0 ? a:1 .':SPLIT' : 'SPLIT'
125
+endfunction " }}}
126
+function! Pl#Segment#Truncate() " {{{
127
+	return 'TRUNCATE'
128
+endfunction " }}}
129
+function! Pl#Segment#Get(name) " {{{
130
+	" Return a segment data dict
131
+	let args = []
132
+
133
+	" Check for printf segments (lists)
134
+	if type(a:name) == type([])
135
+		" We're dealing with a segment with printf arguments
136
+		let seg_orig_name = a:name[0]
137
+		let args = a:name[1:]
138
+	else
139
+		let seg_orig_name = a:name
140
+	endif
141
+
142
+	" Fetch namespace and variants for storing in the segment dict
143
+	let seg_ns = ''
144
+	let seg_variants = []
145
+
146
+	" Retrieve color scheme variants
147
+	let seg_name_split = split(seg_orig_name, '\v\.')
148
+	if len(seg_name_split) > 1
149
+		let seg_variants = seg_name_split[1:]
150
+	endif
151
+
152
+	" Retrieve segment name and namespace
153
+	" Use the first piece of the split string, we can't have variants in the final segment name
154
+	let seg_name_split = split(seg_name_split[0], '\v:')
155
+	let seg_name = seg_name_split[0]
156
+
157
+	if len(seg_name_split) > 1
158
+		let seg_ns = seg_name_split[0]
159
+		let seg_name = seg_name_split[-1]
160
+	endif
161
+
162
+	try
163
+		" If we have a namespace, try to use the namespaced segment first (i.e. search for the segment in the namespaced file first)
164
+		let return_segment = deepcopy(g:Powerline#Segments#{seg_ns}#segments[seg_ns .':'. seg_name])
165
+	catch
166
+		try
167
+			" We didn't find a namespaced segment, fall back to common segments
168
+			let return_segment = deepcopy(g:Powerline#Segments#segments[seg_name])
169
+		catch
170
+			" Didn't find the segment among the common segments either, just skip it
171
+			return {}
172
+		endtry
173
+	endtry
174
+
175
+	if len(args) && has_key(return_segment, 'text')
176
+		" Handle segment printf arguments
177
+		" printf doesn't accept lists as its second argument, so we have to work around that
178
+		let return_segment.text = call('printf', [ return_segment.text ] + args)
179
+	endif
180
+
181
+	" Assign namespace, name and variants
182
+	let return_segment.ns = seg_ns
183
+	let return_segment.name = seg_name
184
+	let return_segment.orig_name = seg_orig_name
185
+	let return_segment.variants = seg_variants
186
+
187
+	return return_segment
188
+endfunction " }}}
... ...
@@ -0,0 +1,100 @@
1
+function! Pl#Theme#Create(...) " {{{
2
+	let buffer_segments = []
3
+
4
+	for buffer_segment in a:000
5
+		" Remove empty segments (e.g. 'Pl#Theme#Function's)
6
+		if empty(buffer_segment)
7
+			continue
8
+		endif
9
+
10
+		call add(buffer_segments, buffer_segment)
11
+	endfor
12
+
13
+	let buffer_segments = Pl#Colorscheme#Apply(g:Powerline_colorscheme, buffer_segments)
14
+
15
+	return buffer_segments
16
+endfunction " }}}
17
+function! Pl#Theme#Callback(name, expr) " {{{
18
+	return ['callback', a:name, a:expr]
19
+endfunction " }}}
20
+function! Pl#Theme#Buffer(ns, ...) " {{{
21
+	let segments = []
22
+	let ns = ! empty(a:ns) ? a:ns .':' : ''
23
+
24
+	" Match namespace parameter by default
25
+	let matches = Pl#Match#Any(a:ns)
26
+	let callback = []
27
+
28
+	let args = a:000
29
+	let args = Pl#Mod#ApplySegmentMods(args)
30
+
31
+	" Fetch segment data dicts
32
+	for item in args
33
+		if type(item) == type([])
34
+			if item[0] == 'match'
35
+				" Match item, overrides default namespace match
36
+				let matches = item
37
+
38
+				unlet! item
39
+				continue
40
+			elseif item[0] == 'callback'
41
+				" Store the item as a callback expression
42
+				let matches = ['match', 'none']
43
+				let callback = [a:ns, item[1], item[2]]
44
+
45
+				unlet! item
46
+				continue
47
+			endif
48
+
49
+			" printf segment, append ns to first item in list
50
+			let item[0] = ns . item[0]
51
+		else
52
+			let item = ns . item
53
+		endif
54
+
55
+		let segment = Pl#Segment#Get(item)
56
+
57
+		if ! empty(segment)
58
+			" Skip empty (possible disabled) segments
59
+			call add(segments, segment)
60
+		endif
61
+
62
+		unlet! item
63
+	endfor
64
+
65
+	return {
66
+		\   'matches': matches
67
+		\ , 'callback': callback
68
+		\ , 'segments': segments
69
+		\ }
70
+endfunction " }}}
71
+function! Pl#Theme#InsertSegment(new_segment, where, target_segment) " {{{
72
+	" It's very important to NOT refer to the theme dict until everything's loaded!
73
+	"
74
+	" Because these functions are called from the vimrc, we need to put the
75
+	" actions in a list which will be parsed later.
76
+	"
77
+	" These functions don't accept a name parameter, because they work on the
78
+	" currently selected theme (will change any selected theme)
79
+	call Pl#Mod#AddSegmentMod('insert_segment', {
80
+		\ 'new_segment': a:new_segment,
81
+		\ 'where': a:where,
82
+		\ 'target_segment': a:target_segment
83
+		\ })
84
+endfunction " }}}
85
+function! Pl#Theme#RemoveSegment(target_segment) " {{{
86
+	" It's very important to NOT refer to the theme dict until everything's loaded!
87
+	"
88
+	" Because these functions are called from the vimrc, we need to put the
89
+	" actions in a list which will be parsed later.
90
+	"
91
+	" These functions don't accept a name parameter, because they work on the
92
+	" currently selected theme (will change any selected theme)
93
+	call Pl#Mod#AddSegmentMod('remove_segment', {
94
+		\ 'target_segment': a:target_segment
95
+		\ })
96
+endfunction " }}}
97
+function! Pl#Theme#ReplaceSegment(old_segment, new_segment) " {{{
98
+	call Pl#Theme#InsertSegment(a:new_segment, 'after', a:old_segment)
99
+	call Pl#Theme#RemoveSegment(a:old_segment)
100
+endfunction " }}}
... ...
@@ -0,0 +1,166 @@
1
+call Pl#Hi#Allocate({
2
+	\ 'black'          : 16,
3
+	\ 'white'          : 231,
4
+	\
5
+	\ 'darkestgreen'   : 22,
6
+	\ 'darkgreen'      : 28,
7
+	\ 'mediumgreen'    : 70,
8
+	\ 'brightgreen'    : 148,
9
+	\
10
+	\ 'darkestcyan'    : 23,
11
+	\ 'mediumcyan'     : 117,
12
+	\
13
+	\ 'darkestblue'    : 24,
14
+	\ 'darkblue'       : 31,
15
+	\
16
+	\ 'darkestred'     : 52,
17
+	\ 'darkred'        : 88,
18
+	\ 'mediumred'      : 124,
19
+	\ 'brightred'      : 160,
20
+	\ 'brightestred'   : 196,
21
+	\
22
+	\ 'darkestpurple'  : 55,
23
+	\ 'mediumpurple'   : 98,
24
+	\ 'brightpurple'   : 189,
25
+	\
26
+	\ 'brightorange'   : 208,
27
+	\ 'brightestorange': 214,
28
+	\
29
+	\ 'gray0'          : 233,
30
+	\ 'gray1'          : 235,
31
+	\ 'gray2'          : 236,
32
+	\ 'gray3'          : 239,
33
+	\ 'gray4'          : 240,
34
+	\ 'gray5'          : 241,
35
+	\ 'gray6'          : 244,
36
+	\ 'gray7'          : 245,
37
+	\ 'gray8'          : 247,
38
+	\ 'gray9'          : 250,
39
+	\ 'gray10'         : 252,
40
+	\ })
41
+
42
+let g:Powerline#Colorschemes#default#colorscheme = Pl#Colorscheme#Init([
43
+	\ Pl#Hi#Segments(['SPLIT'], {
44
+		\ 'n': ['white', 'gray2'],
45
+		\ 'N': ['white', 'gray0'],
46
+		\ 'i': ['white', 'darkestblue'],
47
+		\ }),
48
+	\
49
+	\ Pl#Hi#Segments(['mode_indicator'], {
50
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
51
+		\ 'i': ['darkestcyan', 'white', ['bold']],
52
+		\ 'v': ['darkred', 'brightorange', ['bold']],
53
+		\ 'r': ['white', 'brightred', ['bold']],
54
+		\ 's': ['white', 'gray5', ['bold']],
55
+		\ }),
56
+	\
57
+	\ Pl#Hi#Segments(['branch', 'scrollpercent', 'raw', 'filesize'], {
58
+		\ 'n': ['gray9', 'gray4'],
59
+		\ 'N': ['gray4', 'gray1'],
60
+		\ 'i': ['mediumcyan', 'darkblue'],
61
+		\ }),
62
+	\
63
+	\ Pl#Hi#Segments(['fileinfo', 'filename'], {
64
+		\ 'n': ['white', 'gray4', ['bold']],
65
+		\ 'N': ['gray7', 'gray0', ['bold']],
66
+		\ 'i': ['white', 'darkblue', ['bold']],
67
+		\ }),
68
+	\
69
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
70
+		\ 'n': ['gray10'],
71
+		\ 'N': ['gray5'],
72
+		\ 'i': ['mediumcyan'],
73
+		\ }),
74
+	\
75
+	\ Pl#Hi#Segments(['static_str'], {
76
+		\ 'n': ['white', 'gray4'],
77
+		\ 'N': ['gray7', 'gray1'],
78
+		\ 'i': ['white', 'darkblue'],
79
+		\ }),
80
+	\
81
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
82
+		\ 'n': ['brightestred', ['bold']],
83
+		\ 'N': ['darkred'],
84
+		\ 'i': ['brightestred', ['bold']],
85
+		\ }),
86
+	\
87
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
88
+		\ 'n': ['gray8', 'gray2'],
89
+		\ 'i': ['mediumcyan', 'darkestblue'],
90
+		\ }),
91
+	\
92
+	\ Pl#Hi#Segments(['lineinfo'], {
93
+		\ 'n': ['gray2', 'gray10', ['bold']],
94
+		\ 'N': ['gray7', 'gray1', ['bold']],
95
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
96
+		\ }),
97
+	\
98
+	\ Pl#Hi#Segments(['errors'], {
99
+		\ 'n': ['brightestorange', 'gray2', ['bold']],
100
+		\ 'i': ['brightestorange', 'darkestblue', ['bold']],
101
+		\ }),
102
+	\
103
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
104
+		\ 'n': ['gray6'],
105
+		\ 'N': ['gray5'],
106
+		\ 'i': ['darkestcyan'],
107
+		\ }),
108
+	\
109
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
110
+		\ 'n': ['white', 'brightred', ['bold']],
111
+		\ }),
112
+	\
113
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
114
+		\ 'n': ['white', 'mediumred', ['bold']],
115
+		\ 'N': ['brightred', 'darkestred', ['bold']],
116
+		\ }),
117
+	\
118
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
119
+		\ 'n': ['white', 'darkred'],
120
+		\ 'N': ['brightred', 'darkestred'],
121
+		\ }),
122
+	\
123
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
124
+		\ 'n': ['white', 'darkred'],
125
+		\ 'N': ['white', 'darkestred'],
126
+		\ }),
127
+	\
128
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
129
+		\ 'n': ['white', 'mediumgreen', ['bold']],
130
+		\ 'N': ['mediumgreen', 'darkestgreen', ['bold']],
131
+		\ }),
132
+	\
133
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
134
+		\ 'n': ['brightgreen', 'darkgreen'],
135
+		\ 'N': ['mediumgreen', 'darkestgreen'],
136
+		\ }),
137
+	\
138
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
139
+		\ 'n': ['white', 'darkgreen'],
140
+		\ 'N': ['white', 'darkestgreen'],
141
+		\ }),
142
+	\
143
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
144
+		\ 'n': ['brightpurple', 'darkestpurple'],
145
+		\ }),
146
+	\
147
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
148
+		\ 'n': ['white', 'mediumpurple'],
149
+		\ }),
150
+	\
151
+	\ Pl#Hi#Segments(['ctrlp:item'], {
152
+		\ 'n': ['darkestpurple', 'white', ['bold']],
153
+		\ }),
154
+	\
155
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
156
+		\ 'n': ['brightestred', 'darkestpurple', ['bold']],
157
+		\ }),
158
+	\
159
+	\ Pl#Hi#Segments(['ctrlp:count'], {
160
+		\ 'n': ['darkestpurple', 'white'],
161
+		\ }),
162
+	\
163
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
164
+		\ 'n': ['white', 'darkestpurple'],
165
+		\ }),
166
+	\ ])
... ...
@@ -0,0 +1,154 @@
1
+
2
+" Solarized color scheme for Powerline
3
+" N = no focus
4
+" 16 hex colors as defined on http://ethanschoonover.com/solarized
5
+call Pl#Hi#Allocate({
6
+  \ 'base03'  : [8,   0x002b36],
7
+  \ 'base02'  : [0,   0x073642],
8
+  \ 'base01'  : [10,  0x586e75],
9
+  \ 'base00'  : [11,  0x657b83],
10
+  \ 'base0'   : [12,  0x839496],
11
+  \ 'base1'   : [14,  0x93a1a1],
12
+  \ 'base2'   : [7,   0xeee8d5],
13
+  \ 'base3'   : [15,  0xfdf6e3],
14
+  \ 'yellow'  : [3,   0xb58900],
15
+  \ 'orange'  : [9,   0xcb4b16],
16
+  \ 'red'     : [1,   0xdc322f],
17
+  \ 'magenta' : [5,   0xd33682],
18
+  \ 'violet'  : [13,  0x6c71c4],
19
+  \ 'blue'    : [4,   0x268bd2],
20
+  \ 'cyan'    : [6,   0x2aa198],
21
+  \ 'green'   : [2,   0x859900],
22
+	\ })
23
+
24
+let g:Powerline#Colorschemes#solarized#colorscheme = Pl#Colorscheme#Init([
25
+	\ Pl#Hi#Segments(['SPLIT'], {
26
+		\ 'n': ['base3',  'base2'],
27
+		\ 'N': ['base3',  'base2'],
28
+		\ 'i': ['base3',  'base2'],
29
+		\ }),
30
+	\
31
+	\ Pl#Hi#Segments(['mode_indicator'], {
32
+		\ 'n': ['base2',  'blue',     ['bold']],
33
+		\ 'i': ['base3',  'orange',   ['bold']],
34
+		\ 'v': ['base3',  'magenta',  ['bold']],
35
+		\ 'r': ['base3',  'violet',   ['bold']],
36
+		\ 's': ['base3',  'yellow',   ['bold']],
37
+		\ }),
38
+	\
39
+	\ Pl#Hi#Segments(['branch'], {
40
+		\ 'n': ['base2',   'base02'],
41
+		\ 'N': ['base02',  'base1'],
42
+		\ 'i': ['base2',   'base00'],
43
+		\ }),
44
+	\
45
+  \ Pl#Hi#Segments(['scrollpercent', 'raw', 'filesize'], {
46
+		\ 'n': ['base2',   'base0'],
47
+		\ 'N': ['base00',  'base2'],
48
+		\ 'i': ['base2',   'base1'],
49
+		\ }),
50
+	\
51
+	\ Pl#Hi#Segments(['fileinfo', 'filename'], {
52
+		\ 'n': ['base2',   'base01',   ['bold']],
53
+		\ 'N': ['base01',  'base2' ],
54
+		\ 'i': ['base3',   'base1',    ['bold']],
55
+		\ }),
56
+	\
57
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
58
+		\ 'n': ['base1'],
59
+		\ 'N': ['base1'],
60
+		\ 'i': ['base01'],
61
+		\ }),
62
+	\
63
+	\ Pl#Hi#Segments(['static_str'], {
64
+		\ 'n': ['base3',   'green'],
65
+		\ 'N': ['base02',  'base01'],
66
+		\ 'i': ['base3',   'blue'],
67
+		\ }),
68
+	\
69
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
70
+		\ 'n': ['base3'],
71
+		\ 'N': ['base00'],
72
+		\ 'i': ['base3'],
73
+		\ }),
74
+	\
75
+	\ Pl#Hi#Segments(['currenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
76
+		\ 'n': ['base00', 'base2'],
77
+		\ 'i': ['base0', 'base2'],
78
+		\ }),
79
+	\
80
+	\ Pl#Hi#Segments(['lineinfo'], {
81
+		\ 'n': ['base2',   'base01',  ['bold']],
82
+		\ 'N': ['base02',  'base0'],
83
+		\ 'i': ['base2',   'base00',  ['bold']],
84
+		\ }),
85
+	\
86
+	\ Pl#Hi#Segments(['errors'], {
87
+		\ 'n': ['red',  'base2',  ['bold']],
88
+		\ 'i': ['red',  'base2',  ['bold']],
89
+		\ }),
90
+	\
91
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
92
+		\ 'n': ['base3'],
93
+		\ 'N': ['base02'],
94
+		\ 'i': ['base3'],
95
+		\ }),
96
+	\
97
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
98
+		\ 'n': ['base3', 'red', ['bold']],
99
+		\ }),
100
+	\
101
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
102
+		\ 'n': ['base3',   'red',     ['bold']],
103
+		\ 'N': ['base02',  'base01',  ['bold']],
104
+		\ }),
105
+	\
106
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
107
+		\ 'n': ['base3',  'base00'],
108
+		\ 'N': ['base0',  'base02'],
109
+		\ }),
110
+	\
111
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
112
+		\ 'n': ['base3',  'base02'],
113
+		\ 'N': ['base0',  'base03'],
114
+		\ }),
115
+	\
116
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
117
+		\ 'n': ['base2',   'green',   ['bold']],
118
+		\ 'N': ['base02',  'base1'],
119
+		\ }),
120
+	\
121
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
122
+		\ 'n': ['base3',   'base01'],
123
+		\ 'N': ['base02',  'base01'],
124
+		\ }),
125
+	\
126
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
127
+		\ 'n': ['base2',  'base2'],
128
+		\ 'N': ['base2',  'base2'],
129
+		\ }),
130
+	\
131
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
132
+		\ 'n': ['base03', 'base01'],
133
+		\ }),
134
+	\
135
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
136
+		\ 'n': ['base3', 'base00'],
137
+		\ }),
138
+	\
139
+	\ Pl#Hi#Segments(['ctrlp:item'], {
140
+		\ 'n': ['base3', 'violet', ['bold']],
141
+		\ }),
142
+	\
143
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
144
+		\ 'n': ['base1', 'base01', ['bold']],
145
+		\ }),
146
+	\
147
+	\ Pl#Hi#Segments(['ctrlp:count'], {
148
+		\ 'n': ['base3', 'violet'],
149
+		\ }),
150
+	\
151
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
152
+		\ 'n': ['base3', 'base03'],
153
+		\ }),
154
+	\ ])
... ...
@@ -0,0 +1,195 @@
1
+" Authors:
2
+"   @stephenmckinney
3
+"
4
+" This colorscheme is based on Solarized-dark colors, setting the specific
5
+" values for the Solarized palette, using the terminal's 16 ansi
6
+" color values. It combines Solarized with Powerline native colors.
7
+call Pl#Hi#Allocate({
8
+	\ 'black'          : 16,
9
+	\ 'white'          : 231,
10
+	\
11
+	\ 'darkestgreen'   : 22,
12
+	\ 'darkgreen'      : 28,
13
+	\ 'mediumgreen'    : 70,
14
+	\ 'brightgreen'    : 148,
15
+	\
16
+	\ 'darkestcyan'    : 23,
17
+	\ 'mediumcyan'     : 117,
18
+	\
19
+	\ 'darkestblue'    : 24,
20
+	\ 'darkblue'       : 31,
21
+	\
22
+	\ 'darkestred'     : 52,
23
+	\ 'darkred'        : 88,
24
+	\ 'mediumred'      : 124,
25
+	\ 'brightred'      : 160,
26
+	\ 'brightestred'   : 196,
27
+	\
28
+	\ 'darkestpurple'  : 55,
29
+	\ 'mediumpurple'   : 98,
30
+	\ 'brightpurple'   : 189,
31
+	\
32
+	\ 'brightorange'   : 208,
33
+	\ 'brightestorange': 214,
34
+	\
35
+	\ 'gray0'          : 233,
36
+	\ 'gray1'          : 235,
37
+	\ 'gray2'          : 236,
38
+	\ 'gray3'          : 239,
39
+	\ 'gray4'          : 240,
40
+	\ 'gray5'          : 241,
41
+	\ 'gray6'          : 244,
42
+	\ 'gray7'          : 245,
43
+	\ 'gray8'          : 247,
44
+	\ 'gray9'          : 250,
45
+	\ 'gray10'         : 252,
46
+	\
47
+	\ 'base03'         : [8, 0x002b36],
48
+	\ 'base02'         : [0, 0x073642],
49
+	\ 'base01'         : [10, 0x586e75],
50
+	\ 'base00'         : [11, 0x657b83],
51
+	\ 'base0'          : [12, 0x839496],
52
+	\ 'base1'          : [14, 0x93a1a1],
53
+	\ 'base2'          : [7, 0xeee8d5],
54
+	\ 'base3'          : [15, 0xfdf6e3],
55
+	\ 'yellow'         : [3, 0xb58900],
56
+	\ 'orange'         : [9, 0xcb4b16],
57
+	\ 'red'            : [1, 0xdc322f],
58
+	\ 'magenta'        : [5, 0xd33682],
59
+	\ 'violet'         : [13, 0x6c71c4],
60
+	\ 'blue'           : [4, 0x268bd2],
61
+	\ 'cyan'           : [6, 0x2aa198],
62
+	\ 'green'          : [2, 0x859900],
63
+	\ })
64
+
65
+let g:Powerline#Colorschemes#solarized16#colorscheme= Pl#Colorscheme#Init([
66
+	\ Pl#Hi#Segments(['SPLIT'], {
67
+		\ 'n': ['white', 'base02'],
68
+		\ 'N': ['white', 'base02'],
69
+		\ }),
70
+	\
71
+	\ Pl#Hi#Segments(['mode_indicator'], {
72
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
73
+		\ 'i': ['darkestcyan', 'white', ['bold']],
74
+		\ 'v': ['red', 'brightorange', ['bold']],
75
+		\ 'r': ['white', 'violet', ['bold']],
76
+		\ 's': ['white', 'gray5', ['bold']],
77
+		\ }),
78
+	\
79
+	\ Pl#Hi#Segments(['branch', 'raw', 'filesize'], {
80
+		\ 'n': ['base03', 'blue'],
81
+		\ 'N': ['base00', 'base03'],
82
+		\ }),
83
+	\
84
+	\ Pl#Hi#Segments(['fileinfo', 'filename', 'filepath'], {
85
+		\ 'n': ['base3', 'darkestblue', ['bold']],
86
+		\ 'N': ['base0', 'base02', ['bold']],
87
+		\ }),
88
+	\
89
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
90
+		\ 'n': ['base2'],
91
+		\ 'N': ['base00'],
92
+		\ }),
93
+	\
94
+	\ Pl#Hi#Segments(['static_str'], {
95
+		\ 'n': ['base3', 'violet'],
96
+		\ 'N': ['base1', 'base02'],
97
+		\ 'i': ['white', 'base02'],
98
+		\ }),
99
+	\
100
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
101
+		\ 'n': ['base03', ['bold']],
102
+		\ 'N': ['gray5'],
103
+		\ 'i': ['base03', ['bold']],
104
+		\ }),
105
+	\
106
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
107
+		\ 'n': ['base1', 'base02'],
108
+		\ 'N': ['base00', 'base03'],
109
+		\ }),
110
+	\
111
+	\ Pl#Hi#Segments(['scrollpercent'], {
112
+		\ 'n': ['base1', 'base02', ['bold']],
113
+		\ 'N': ['base00', 'base03'],
114
+		\ }),
115
+	\
116
+	\ Pl#Hi#Segments(['lineinfo'], {
117
+		\ 'n': ['gray2', 'gray10', ['bold']],
118
+		\ 'N': ['gray7', 'gray1', ['bold']],
119
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
120
+		\ }),
121
+	\
122
+	\ Pl#Hi#Segments(['errors'], {
123
+		\ 'n': ['orange', 'base02', ['bold']],
124
+		\ 'N': ['gray5', 'base03', ['bold']],
125
+		\ }),
126
+	\
127
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
128
+		\ 'n': ['gray6'],
129
+		\ 'N': ['gray5'],
130
+		\ 'i': ['darkestcyan'],
131
+		\ }),
132
+	\
133
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
134
+		\ 'n': ['base3', 'red', ['bold']],
135
+		\ }),
136
+	\
137
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
138
+		\ 'n': ['base3', 'darkblue', ['bold']],
139
+		\ 'N': ['base1', 'base03', ['bold']],
140
+		\ }),
141
+	\
142
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
143
+		\ 'n': ['white', 'base02'],
144
+		\ 'N': ['gray5', 'base02'],
145
+		\ }),
146
+	\
147
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
148
+		\ 'n': ['white', 'base02'],
149
+		\ 'N': ['white', 'base02'],
150
+		\ }),
151
+	\
152
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
153
+		\ 'n': ['base3', 'darkestblue', ['bold']],
154
+		\ 'N': ['base01', 'base02', ['bold']],
155
+		\ }),
156
+	\
157
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
158
+		\ 'n': ['base3', 'blue'],
159
+		\ 'N': ['gray5', 'base02'],
160
+		\ }),
161
+	\
162
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
163
+		\ 'n': ['gray3', 'base02'],
164
+		\ 'N': ['gray3', 'base02'],
165
+		\ }),
166
+	\
167
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
168
+		\ 'n': ['green', 'base02'],
169
+		\ }),
170
+	\
171
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next'], {
172
+		\ 'n': ['green', 'base02'],
173
+		\ }),
174
+	\
175
+	\ Pl#Hi#Segments(['ctrlp:item', 'ctrlp:pwd'], {
176
+		\ 'n': ['base2', 'darkestblue', ['bold']],
177
+		\ }),
178
+	\
179
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
180
+		\ 'n': ['green', 'base02'],
181
+		\ }),
182
+	\
183
+	\ Pl#Hi#Segments(['ctrlp:count'], {
184
+		\ 'n': ['base0', 'base02'],
185
+		\ }),
186
+	\
187
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
188
+		\ 'n': ['white', 'base02'],
189
+		\ }),
190
+  \
191
+  \ Pl#Hi#Segments(['status'], {
192
+		\ 'n': ['green', 'base02'],
193
+		\ 'N': ['gray5', 'base02'],
194
+    \ }),
195
+\ ])
... ...
@@ -0,0 +1,195 @@
1
+" Authors:
2
+"   @skwp
3
+"
4
+" This colorscheme is based on Solarized-dark colors, combined
5
+" with Powerline native colors
6
+call Pl#Hi#Allocate({
7
+	\ 'black'          : 16,
8
+	\ 'white'          : 231,
9
+	\
10
+	\ 'darkestgreen'   : 22,
11
+	\ 'darkgreen'      : 28,
12
+	\ 'mediumgreen'    : 70,
13
+	\ 'brightgreen'    : 148,
14
+	\
15
+	\ 'darkestcyan'    : 23,
16
+	\ 'mediumcyan'     : 117,
17
+	\
18
+	\ 'darkestblue'    : 24,
19
+	\ 'darkblue'       : 31,
20
+	\
21
+	\ 'darkestred'     : 52,
22
+	\ 'darkred'        : 88,
23
+	\ 'mediumred'      : 124,
24
+	\ 'brightred'      : 160,
25
+	\ 'brightestred'   : 196,
26
+	\
27
+	\ 'darkestpurple'  : 55,
28
+	\ 'mediumpurple'   : 98,
29
+	\ 'brightpurple'   : 189,
30
+	\
31
+	\ 'brightorange'   : 208,
32
+	\ 'brightestorange': 214,
33
+	\
34
+	\ 'gray0'          : 233,
35
+	\ 'gray1'          : 235,
36
+	\ 'gray2'          : 236,
37
+	\ 'gray3'          : 239,
38
+	\ 'gray4'          : 240,
39
+	\ 'gray5'          : 241,
40
+	\ 'gray6'          : 244,
41
+	\ 'gray7'          : 245,
42
+	\ 'gray8'          : 247,
43
+	\ 'gray9'          : 250,
44
+	\ 'gray10'         : 252,
45
+	\
46
+	\ 'base03'         : [234, 0x002b36],
47
+	\ 'base02'         : [235, 0x073642],
48
+	\ 'base01'         : [240, 0x586e75],
49
+	\ 'base00'         : [241, 0x657b83],
50
+	\ 'base0'          : [244, 0x839496],
51
+	\ 'base1'          : [245, 0x93a1a1],
52
+	\ 'base2'          : [254, 0xeee8d5],
53
+	\ 'base3'          : [230, 0xfdf6e3],
54
+	\ 'yellow'         : [136, 0xb58900],
55
+	\ 'orange'         : [166, 0xcb4b16],
56
+	\ 'red'            : [160, 0xdc322f],
57
+	\ 'magenta'        : [125, 0xd33682],
58
+	\ 'violet'         : [61, 0x6c71c4],
59
+	\ 'blue'           : [33, 0x268bd2],
60
+	\ 'cyan'           : [37, 0x2aa198],
61
+	\ 'green'          : [64, 0x859900],
62
+	\ })
63
+
64
+let g:Powerline#Colorschemes#solarized256#colorscheme = Pl#Colorscheme#Init([
65
+	\ Pl#Hi#Segments(['SPLIT'], {
66
+		\ 'n': ['white', 'base02'],
67
+		\ 'N': ['white', 'base02'],
68
+		\ }),
69
+	\
70
+	\ Pl#Hi#Segments(['mode_indicator'], {
71
+		\ 'n': ['darkestgreen', 'brightgreen', ['bold']],
72
+		\ 'i': ['darkestcyan', 'white', ['bold']],
73
+		\ 'v': ['red', 'brightorange', ['bold']],
74
+		\ 'r': ['white', 'violet', ['bold']],
75
+		\ 's': ['white', 'gray5', ['bold']],
76
+		\ }),
77
+	\
78
+	\ Pl#Hi#Segments(['branch', 'raw', 'filesize'], {
79
+		\ 'n': ['base03', 'blue'],
80
+		\ 'N': ['gray5', 'base03'],
81
+		\ }),
82
+	\
83
+	\ Pl#Hi#Segments(['scrollpercent'], {
84
+		\ 'n': ['gray7', 'gray2'],
85
+		\ 'N': ['base2', 'base02'],
86
+		\ }),
87
+	\
88
+	\ Pl#Hi#Segments(['fileinfo', 'filename', 'filepath'], {
89
+		\ 'n': ['base2', 'darkestblue', ['bold']],
90
+		\ 'N': ['base1', 'base02', ['bold']],
91
+		\ }),
92
+	\
93
+	\ Pl#Hi#Segments(['fileinfo.filepath'], {
94
+		\ 'n': ['gray10'],
95
+		\ 'N': ['gray5'],
96
+		\ 'i': ['mediumcyan'],
97
+		\ }),
98
+	\
99
+	\ Pl#Hi#Segments(['static_str'], {
100
+		\ 'n': ['base3', 'violet'],
101
+		\ 'N': ['base1', 'base02'],
102
+		\ 'i': ['white', 'base02'],
103
+		\ }),
104
+	\
105
+	\ Pl#Hi#Segments(['fileinfo.flags'], {
106
+		\ 'n': ['base03', ['bold']],
107
+		\ 'N': ['gray5'],
108
+		\ 'i': ['base03', ['bold']],
109
+		\ }),
110
+	\
111
+	\ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
112
+		\ 'n': ['gray5', 'gray2'],
113
+		\ 'i': ['mediumcyan', 'base02'],
114
+		\ }),
115
+	\
116
+	\ Pl#Hi#Segments(['lineinfo'], {
117
+		\ 'n': ['gray2', 'gray10', ['bold']],
118
+		\ 'N': ['gray7', 'gray1', ['bold']],
119
+		\ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
120
+		\ }),
121
+	\
122
+	\ Pl#Hi#Segments(['errors'], {
123
+		\ 'n': ['orange', 'base02', ['bold']],
124
+		\ 'N': ['gray5', 'base03', ['bold']],
125
+		\ }),
126
+	\
127
+	\ Pl#Hi#Segments(['lineinfo.line.tot'], {
128
+		\ 'n': ['gray6'],
129
+		\ 'N': ['gray5'],
130
+		\ 'i': ['darkestcyan'],
131
+		\ }),
132
+	\
133
+	\ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
134
+		\ 'n': ['base3', 'red', ['bold']],
135
+		\ }),
136
+	\
137
+	\ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
138
+		\ 'n': ['base3', 'darkblue', ['bold']],
139
+		\ 'N': ['base1', 'base03', ['bold']],
140
+		\ }),
141
+	\
142
+	\ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
143
+		\ 'n': ['white', 'base02'],
144
+		\ 'N': ['gray5', 'base02'],
145
+		\ }),
146
+	\
147
+	\ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
148
+		\ 'n': ['white', 'base02'],
149
+		\ 'N': ['white', 'base02'],
150
+		\ }),
151
+	\
152
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
153
+		\ 'n': ['gray10', 'darkestblue', ['bold']],
154
+		\ 'N': ['gray3', 'base02', ['bold']],
155
+		\ }),
156
+	\
157
+	\ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
158
+		\ 'n': ['base3', 'blue'],
159
+		\ 'N': ['gray5', 'base02'],
160
+		\ }),
161
+	\
162
+	\ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
163
+		\ 'n': ['gray3', 'base02'],
164
+		\ 'N': ['gray3', 'base02'],
165
+		\ }),
166
+	\
167
+	\ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
168
+		\ 'n': ['green', 'base03'],
169
+		\ }),
170
+	\
171
+	\ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
172
+		\ 'n': ['green', 'base02'],
173
+		\ }),
174
+	\
175
+	\ Pl#Hi#Segments(['ctrlp:item'], {
176
+		\ 'n': ['base2', 'darkestblue', ['bold']],
177
+		\ }),
178
+	\
179
+	\ Pl#Hi#Segments(['ctrlp:marked'], {
180
+		\ 'n': ['brightgreen', 'base03', ['bold']],
181
+		\ }),
182
+	\
183
+	\ Pl#Hi#Segments(['ctrlp:count'], {
184
+		\ 'n': ['base0', 'base03'],
185
+		\ }),
186
+	\
187
+	\ Pl#Hi#Segments(['ctrlp:SPLIT'], {
188
+		\ 'n': ['white', 'base03'],
189
+		\ }),
190
+  \
191
+  \ Pl#Hi#Segments(['status'], {
192
+		\ 'n': ['green', 'base02'],
193
+		\ 'N': ['gray5', 'base02'],
194
+    \ }),
195
+\ ])
... ...
@@ -0,0 +1,141 @@
1
+" Recalculate the trailing whitespace warning when idle, and after saving
2
+autocmd CursorHold,BufWritePost,InsertLeave * unlet! b:statusline_trailing_space_warning
3
+
4
+function! Powerline#Functions#GetFilepath() " {{{
5
+	" Recalculate the filepath when cwd changes.
6
+	let cwd = getcwd()
7
+	if exists("b:Powerline_cwd") && cwd != b:Powerline_cwd
8
+		unlet! b:Powerline_filepath
9
+	endif
10
+	let b:Powerline_cwd = cwd
11
+
12
+	if exists('b:Powerline_filepath')
13
+		return b:Powerline_filepath
14
+	endif
15
+
16
+	let dirsep = has('win32') && ! &shellslash ? '\' : '/'
17
+	let filepath = expand('%:p')
18
+
19
+	if empty(filepath)
20
+		return ''
21
+	endif
22
+
23
+	let ret = ''
24
+
25
+	if g:Powerline_stl_path_style == 'short'
26
+		" Display a short path where the first directory is displayed with its
27
+		" full name, and the subsequent directories are shortened to their
28
+		" first letter, i.e. "/home/user/foo/foo/bar/baz.vim" becomes
29
+		" "~/foo/f/b/baz.vim"
30
+		"
31
+		" This displays the shortest possible path, relative to ~ or the
32
+		" current directory.
33
+		let mod = (exists('+acd') && &acd) ? ':~:h' : ':~:.:h'
34
+		let fpath = split(fnamemodify(filepath, mod), dirsep)
35
+		let fpath_shortparts = map(fpath[1:], 'v:val[0]')
36
+		let ret = join(extend([fpath[0]], fpath_shortparts), dirsep) . dirsep
37
+	elseif g:Powerline_stl_path_style == 'relative'
38
+		" Display a relative path, similar to the %f statusline item
39
+		let ret = fnamemodify(filepath, ':~:.:h') . dirsep
40
+	elseif g:Powerline_stl_path_style == 'full'
41
+		" Display the full path, similar to the %F statusline item
42
+		let ret = fnamemodify(filepath, ':h') . dirsep
43
+	endif
44
+
45
+	if ret == ('.' . dirsep)
46
+		let ret = ''
47
+	endif
48
+
49
+	let b:Powerline_filepath = ret
50
+	return ret
51
+endfunction " }}}
52
+function! Powerline#Functions#GetShortPath(threshold) " {{{
53
+	let fullpath = split(expand('%:~'), '[/\\]')
54
+
55
+	if len(fullpath) > a:threshold
56
+		let fullpath = [fullpath[0], '…'] +  fullpath[-a:threshold + 1 :]
57
+	endif
58
+
59
+	return join(fullpath, '/')
60
+endfunction " }}}
61
+function! Powerline#Functions#GetMode() " {{{
62
+	let mode = mode()
63
+
64
+	if mode ==# 'v'
65
+		let mode = get(g:, "Powerline_mode_v", "VISUAL")
66
+	elseif mode ==# 'V'
67
+		let mode = get(g:, "Powerline_mode_V", "Vâ‹…LINE")
68
+	elseif mode ==# ''
69
+		let mode = get(g:, "Powerline_mode_cv", "Vâ‹…BLOCK")
70
+	elseif mode ==# 's'
71
+		let mode = get(g:, "Powerline_mode_s", "SELECT")
72
+	elseif mode ==# 'S'
73
+		let mode = get(g:, "Powerline_mode_S", "Sâ‹…LINE")
74
+	elseif mode ==# ''
75
+		let mode = get(g:, "Powerline_mode_cs", "Sâ‹…BLOCK")
76
+	elseif mode =~# '\vi'
77
+		let mode = get(g:, "Powerline_mode_i", "INSERT")
78
+	elseif mode =~# '\v(R|Rv)'
79
+		let mode = get(g:, "Powerline_mode_R", "REPLACE")
80
+	else
81
+		" Fallback to normal mode
82
+		let mode = get(g:, "Powerline_mode_n", "NORMAL")
83
+	endif
84
+
85
+	return mode
86
+endfunction " }}}
87
+function! Powerline#Functions#GetFilesize() " {{{
88
+	let bytes = getfsize(expand("%:p"))
89
+
90
+	if bytes <= 0
91
+		return ''
92
+	endif
93
+
94
+	if bytes < 1024
95
+		return bytes . 'B'
96
+	else
97
+		return (bytes / 1024) . 'kB'
98
+	endif
99
+endfunction "}}}
100
+function! Powerline#Functions#GetCharCode() " {{{
101
+	" Get the output of :ascii
102
+	redir => ascii
103
+	silent! ascii
104
+	redir END
105
+
106
+	if match(ascii, 'NUL') != -1
107
+		return 'NUL'
108
+	endif
109
+
110
+	" Zero pad hex values
111
+	let nrformat = '0x%02x'
112
+
113
+	let encoding = (&fenc == '' ? &enc : &fenc)
114
+
115
+	if encoding == 'utf-8'
116
+		" Zero pad with 4 zeroes in unicode files
117
+		let nrformat = '0x%04x'
118
+	endif
119
+
120
+	" Get the character and the numeric value from the return value of :ascii
121
+	" This matches the two first pieces of the return value, e.g.
122
+	" "<F>  70" => char: 'F', nr: '70'
123
+	let [str, char, nr; rest] = matchlist(ascii, '\v\<(.{-1,})\>\s*([0-9]+)')
124
+
125
+	" Format the numeric value
126
+	let nr = printf(nrformat, nr)
127
+
128
+	return "'". char ."' ". nr
129
+endfunction "}}}
130
+function! Powerline#Functions#GetWSMarker() " {{{
131
+	" Return '...' if trailing white space is detected
132
+	" Return '' otherwise
133
+	if ! exists("b:statusline_trailing_space_warning")
134
+		if search('\s$', 'nw') != 0
135
+			let b:statusline_trailing_space_warning = ' … '
136
+		else
137
+			let b:statusline_trailing_space_warning = ''
138
+		endif
139
+	endif
140
+	return b:statusline_trailing_space_warning
141
+endfunction " }}}
... ...
@@ -0,0 +1,12 @@
1
+function! Powerline#Functions#ft_man#GetName() " {{{
2
+	let matches = matchlist(getline(1), '\v^([a-zA-Z_\.\-]+)\((\d+)\)')
3
+
4
+	if ! len(matches)
5
+		return 'n/a'
6
+	endif
7
+
8
+	let file = tolower(matches[1])
9
+	let num = matches[2]
10
+
11
+	return file
12
+endfunction " }}}
... ...
@@ -0,0 +1,7 @@
1
+function! Powerline#Functions#fugitive#GetBranch(symbol) " {{{
2
+	let ret = fugitive#statusline()
3
+
4
+	let ret = substitute(ret, '\c\v\[?GIT\(([a-z0-9\-_\./:]+)\)\]?', a:symbol .' \1', 'g')
5
+
6
+	return ret
7
+endfunction " }}}
... ...
@@ -0,0 +1,17 @@
1
+function! Powerline#Functions#hgrev#Status(symbol) " {{{
2
+	if ! exists('*HGRev')
3
+		" HGRev hasn't been loaded yet
4
+		return ''
5
+	endif
6
+	if !exists("b:statusline_hg_status")
7
+		silent execute "RefreshMercurialRev"
8
+	endif
9
+	let b:statusline_hg_status=HGRev()
10
+	if b:statusline_hg_status != '-'
11
+		let ret = "\u26A1". '' . substitute(b:statusline_hg_status, '^[^ ]*', '\1', 'g')
12
+		let ret=substitute(ret,' M$','+','g')
13
+	else
14
+		let ret=''
15
+		endif
16
+	return ret
17
+endfunction " }}}
... ...
@@ -0,0 +1,16 @@
1
+function! Powerline#Functions#syntastic#GetErrors(line_symbol) " {{{
2
+	if ! exists('g:syntastic_stl_format')
3
+		" Syntastic hasn't been loaded yet
4
+		return ''
5
+	endif
6
+
7
+	" Temporarily change syntastic output format
8
+	let old_stl_format = g:syntastic_stl_format
9
+	let g:syntastic_stl_format = '%E{ ERRORS (%e) '. a:line_symbol .' %fe }%W{ WARNINGS (%w) '. a:line_symbol .' %fw }'
10
+
11
+	let ret = SyntasticStatuslineFlag()
12
+
13
+	let g:syntastic_stl_format = old_stl_format
14
+
15
+	return ret
16
+endfunction " }}}
... ...
@@ -0,0 +1,13 @@
1
+let g:Powerline#Matches#matches = {
2
+	\ 'command_t'       : Pl#Match#Add('bufname(winbufnr(a:window))', '^GoToFile$'),
3
+	\ 'bt_help'         : Pl#Match#Add('getwinvar(a:window, "&bt")' , '^help$'),
4
+	\ 'ft_man'          : Pl#Match#Add('getwinvar(a:window, "&ft")' , '^man$'),
5
+	\ 'ft_qf'           : Pl#Match#Add('getwinvar(a:window, "&ft")' , '^qf$'),
6
+	\ 'ft_vimpager'     : Pl#Match#Add('getwinvar(a:window, "&ft")' , 'vimpager'),
7
+	\ 'gundo_preview'   : Pl#Match#Add('bufname(winbufnr(a:window))', '^__Gundo_Preview__$'),
8
+	\ 'gundo_tree'      : Pl#Match#Add('bufname(winbufnr(a:window))', '^__Gundo__$'),
9
+	\ 'lustyexplorer'   : Pl#Match#Add('bufname(winbufnr(a:window))', '\[LustyExplorer\-Buffers\]'),
10
+	\ 'minibufexplorer' : Pl#Match#Add('bufname(winbufnr(a:window))', '^\-MiniBufExplorer\-$'),
11
+	\ 'tagbar'          : Pl#Match#Add('getwinvar(a:window, "&ft")' , '^tagbar$'),
12
+	\ 'nerdtree'        : Pl#Match#Add('getwinvar(a:window, "&ft")' , '^nerdtree$'),
13
+\ }
... ...
@@ -0,0 +1,30 @@
1
+let g:Powerline#Segments#segments = Pl#Segment#Init([
2
+	\ Pl#Segment#Create('SPLIT'   , '__split__'),
3
+	\ Pl#Segment#Create('TRUNCATE', '__truncate__'),
4
+	\
5
+	\ Pl#Segment#Create('paste_indicator' , '%{&paste ? "PASTE" : ""}', Pl#Segment#Modes('!N')),
6
+	\ Pl#Segment#Create('mode_indicator'  , '%{Powerline#Functions#GetMode()}', Pl#Segment#Modes('!N')),
7
+	\ Pl#Segment#Create('fileinfo',
8
+		\ Pl#Segment#Create('flags.ro'    , '%{&readonly ? "$RO" : ""}'),
9
+		\ Pl#Segment#Create('filepath'    , '%{Powerline#Functions#GetFilepath()}', Pl#Segment#NoPadding()),
10
+		\ Pl#Segment#Create('filename'    , '%t'),
11
+		\ Pl#Segment#Create('flags.mod'   , '%M'),
12
+		\ Pl#Segment#Create('flags.type'  , '%H%W'),
13
+	\ ),
14
+	\ Pl#Segment#Create('filename'        , '%t'),
15
+	\ Pl#Segment#Create('filesize'        , '%{Powerline#Functions#GetFilesize()}', Pl#Segment#Modes('!N')),
16
+	\ Pl#Segment#Create('pwd'             , '%{substitute(getcwd(), expand("$HOME"), "~", "g")}'),
17
+	\ Pl#Segment#Create('static_str'      , '%%{"%s"}'),
18
+	\ Pl#Segment#Create('raw'             , '%s'),
19
+	\ Pl#Segment#Create('fileformat'      , '%{&fileformat}', Pl#Segment#Modes('!N')),
20
+	\ Pl#Segment#Create('fileencoding'    , '%{(&fenc == "" ? &enc : &fenc)}', Pl#Segment#Modes('!N')),
21
+	\ Pl#Segment#Create('filetype'        , '%{strlen(&ft) ? &ft : "no ft"}', Pl#Segment#Modes('!N')),
22
+	\ Pl#Segment#Create('scrollpercent'   , '%3p%%'),
23
+	\ Pl#Segment#Create('lineinfo',
24
+		\ Pl#Segment#Create('line.cur'    , '$LINE %3l'),
25
+		\ Pl#Segment#Create('line.tot'    , ':%-2v', Pl#Segment#NoPadding()),
26
+	\ ),
27
+	\ Pl#Segment#Create('charcode'        , '%{Powerline#Functions#GetCharCode()}', Pl#Segment#Modes('!N')),
28
+	\ Pl#Segment#Create('currhigroup'     , '%{synIDattr(synID(line("."), col("."), 1), "name")}', Pl#Segment#Modes('!N')),
29
+	\ Pl#Segment#Create('ws_marker'       , '%{Powerline#Functions#GetWSMarker()}', Pl#Segment#Modes('!N')),
30
+\ ])
... ...
@@ -0,0 +1,20 @@
1
+if !exists("g:Powerline#Segments#ctrlp#segments#focus ")
2
+	let g:Powerline#Segments#ctrlp#segments#focus = '%{"%0"}'
3
+endif
4
+if !exists("g:Powerline#Segments#ctrlp#segments#prev ")
5
+	let g:Powerline#Segments#ctrlp#segments#prev = '%-3{"%3"}'
6
+endif
7
+if !exists("g:Powerline#Segments#ctrlp#segments#next ")
8
+	let g:Powerline#Segments#ctrlp#segments#next = '%-3{"%5"}'
9
+endif
10
+
11
+let g:Powerline#Segments#ctrlp#segments = Pl#Segment#Init(['ctrlp'
12
+	\ , Pl#Segment#Create('focus', g:Powerline#Segments#ctrlp#segments#focus)
13
+	\ , Pl#Segment#Create('byfname', '%{"%1"}')
14
+	\ , Pl#Segment#Create('prev', g:Powerline#Segments#ctrlp#segments#prev)
15
+	\ , Pl#Segment#Create('item', '%-9{"%4"}')
16
+	\ , Pl#Segment#Create('next', g:Powerline#Segments#ctrlp#segments#next)
17
+	\ , Pl#Segment#Create('marked', '%{"%6" == " <+>" ? "" : strpart("%6", 2, len("%6") - 3)}')
18
+	\
19
+	\ , Pl#Segment#Create('count', '%-6{"%0"}')
20
+\ ])
... ...
@@ -0,0 +1,3 @@
1
+let g:Powerline#Segments#ft_man#segments = Pl#Segment#Init(['ft_man',
2
+	\ Pl#Segment#Create('filename', '%{Powerline#Functions#ft_man#GetName()}')
3
+\ ])
... ...
@@ -0,0 +1,5 @@
1
+let g:Powerline#Segments#fugitive#segments = Pl#Segment#Init(['fugitive',
2
+	\ (exists('g:loaded_fugitive') && g:loaded_fugitive == 1),
3
+	\
4
+	\ Pl#Segment#Create('branch', '%{Powerline#Functions#fugitive#GetBranch("$BRANCH")}')
5
+\ ])
... ...
@@ -0,0 +1,4 @@
1
+let g:Powerline#Segments#hgrev#segments = Pl#Segment#Init(['hgrev',
2
+	\ (exists('hgrev_loaded')),
3
+	\ Pl#Segment#Create('branch', '%{Powerline#Functions#hgrev#Status("$BRANCH")}')
4
+  \ ])
... ...
@@ -0,0 +1,6 @@
1
+let g:Powerline#Segments#rvm#segments = Pl#Segment#Init(['rvm',
2
+	\ (exists('g:loaded_rvm') && g:loaded_rvm == 1),
3
+	\
4
+	\ Pl#Segment#Create('string', '%{rvm#string()}'),
5
+	\ Pl#Segment#Create('statusline', '%{rvm#statusline()}')
6
+\ ])
... ...
@@ -0,0 +1,5 @@
1
+let g:Powerline#Segments#syntastic#segments = Pl#Segment#Init(['syntastic',
2
+	\ (exists('g:loaded_syntastic_plugin') && g:loaded_syntastic_plugin == 1),
3
+	\
4
+	\ Pl#Segment#Create('errors', '%{Powerline#Functions#syntastic#GetErrors("$LINE")}', Pl#Segment#Modes('!N'))
5
+\ ])
... ...
@@ -0,0 +1,6 @@
1
+let g:Powerline#Segments#tagbar#segments = Pl#Segment#Init(['tagbar',
2
+	\ (exists(':Tagbar') > 0),
3
+	\
4
+	\ Pl#Segment#Create('currenttag', '%{tagbar#currenttag("%s", "")}', Pl#Segment#Modes('!N')),
5
+	\ Pl#Segment#Create('fullcurrenttag', '%{tagbar#currenttag("%s", "", "f")}', Pl#Segment#Modes('!N'))
6
+\ ])
... ...
@@ -0,0 +1,5 @@
1
+let g:Powerline#Segments#virtualenv#segments = Pl#Segment#Init(['virtualenv',
2
+	\ has('python') && (exists('g:virtualenv_loaded') && g:virtualenv_loaded == 1),
3
+	\
4
+	\ Pl#Segment#Create('statusline', '%{virtualenv#statusline()}')
5
+\ ])
... ...
@@ -0,0 +1,116 @@
1
+let g:Powerline#Themes#default#theme = Pl#Theme#Create(
2
+	\ Pl#Theme#Buffer(''
3
+		\ , 'paste_indicator'
4
+		\ , 'mode_indicator'
5
+		\ , 'fugitive:branch'
6
+		\ , 'hgrev:branch'
7
+		\ , 'fileinfo'
8
+		\ , 'syntastic:errors'
9
+		\ , Pl#Segment#Truncate()
10
+		\ , 'tagbar:currenttag'
11
+		\ , Pl#Segment#Split()
12
+		\ , 'rvm:string'
13
+		\ , 'virtualenv:statusline'
14
+		\ , 'fileformat'
15
+		\ , 'fileencoding'
16
+		\ , 'filetype'
17
+		\ , 'scrollpercent'
18
+		\ , 'lineinfo'
19
+	\ ),
20
+	\
21
+	\ Pl#Theme#Buffer('command_t'
22
+		\ , ['static_str.name', 'Command-T']
23
+		\ , Pl#Segment#Truncate()
24
+		\ , Pl#Segment#Split()
25
+		\ , ['raw.line', '%10(Match #%l%)']
26
+	\ ),
27
+	\
28
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_tree')
29
+		\ , ['static_str.name', 'Gundo']
30
+		\ , ['static_str.buffer', 'Undo tree']
31
+		\ , Pl#Segment#Truncate()
32
+		\ , Pl#Segment#Split()
33
+	\ ),
34
+	\
35
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_preview')
36
+		\ , ['static_str.name', 'Gundo']
37
+		\ , ['static_str.buffer', 'Diff preview']
38
+		\ , Pl#Segment#Truncate()
39
+		\ , Pl#Segment#Split()
40
+	\ ),
41
+	\
42
+	\ Pl#Theme#Buffer('bt_help'
43
+		\ , ['static_str.name', 'Help']
44
+		\ , 'filename'
45
+		\ , Pl#Segment#Truncate()
46
+		\ , Pl#Segment#Split()
47
+		\ , 'scrollpercent'
48
+	\ ),
49
+	\
50
+	\ Pl#Theme#Buffer('ft_vimpager'
51
+		\ , ['static_str.name', 'Pager']
52
+		\ , 'filename'
53
+		\ , Pl#Segment#Truncate()
54
+		\ , Pl#Segment#Split()
55
+		\ , 'scrollpercent'
56
+	\ ),
57
+	\
58
+	\ Pl#Theme#Buffer('lustyexplorer'
59
+		\ , ['static_str.name', 'LustyExplorer']
60
+		\ , ['static_str.buffer', 'Buffer list']
61
+		\ , Pl#Segment#Truncate()
62
+		\ , Pl#Segment#Split()
63
+	\ ),
64
+	\
65
+	\ Pl#Theme#Buffer('ft_man'
66
+		\ , ['static_str.name', 'Man page']
67
+		\ , 'filename'
68
+		\ , Pl#Segment#Truncate()
69
+		\ , Pl#Segment#Split()
70
+		\ , 'scrollpercent'
71
+	\ ),
72
+	\
73
+	\ Pl#Theme#Buffer('minibufexplorer'
74
+		\ , ['static_str.name', 'MiniBufExplorer']
75
+		\ , Pl#Segment#Truncate()
76
+		\ , Pl#Segment#Split()
77
+	\ ),
78
+	\
79
+	\ Pl#Theme#Buffer('ft_qf'
80
+		\ , ['static_str.name', 'Quickfix']
81
+		\ , Pl#Segment#Truncate()
82
+		\ , Pl#Segment#Split()
83
+	\ ),
84
+	\
85
+	\ Pl#Theme#Buffer('tagbar'
86
+		\ , ['static_str.name', 'Tagbar']
87
+		\ , ['static_str.buffer', 'Tree']
88
+		\ , Pl#Segment#Truncate()
89
+		\ , Pl#Segment#Split()
90
+	\ ),
91
+	\
92
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_main', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.main = "%s"')
93
+		\ , 'ctrlp:prev'
94
+		\ , 'ctrlp:item'
95
+		\ , 'ctrlp:next'
96
+		\ , 'ctrlp:marked'
97
+		\ , Pl#Segment#Truncate()
98
+		\ , Pl#Segment#Split()
99
+		\ , 'ctrlp:focus'
100
+		\ , 'ctrlp:byfname'
101
+		\ , 'pwd'
102
+	\ ),
103
+	\
104
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_prog', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.prog = "%s"')
105
+		\ , 'ctrlp:count'
106
+		\ , Pl#Segment#Truncate()
107
+		\ , Pl#Segment#Split()
108
+		\ , 'pwd'
109
+	\ ),
110
+	\
111
+	\ Pl#Theme#Buffer('nerdtree'
112
+		\ , ['raw.name', '%{Powerline#Functions#GetShortPath(4)}']
113
+		\ , Pl#Segment#Truncate()
114
+		\ , Pl#Segment#Split()
115
+	\ )
116
+\ )
... ...
@@ -0,0 +1,114 @@
1
+" Authors:
2
+"   @stephenmckinney
3
+"
4
+let g:Powerline#Themes#solarized16#theme = Pl#Theme#Create(
5
+	\ Pl#Theme#Buffer(''
6
+		\ , 'fugitive:branch'
7
+		\ , 'fileinfo'
8
+		\ , 'flags.mod'
9
+		\ , 'syntastic:errors'
10
+		\ , Pl#Segment#Truncate()
11
+		\ , Pl#Segment#Split()
12
+		\ , 'sass:status'
13
+		\ , 'rvm:string'
14
+		\ , 'filetype'
15
+		\ , 'scrollpercent'
16
+		\ , 'paste_indicator'
17
+	\ ),
18
+	\
19
+	\ Pl#Theme#Buffer('command_t'
20
+		\ , ['static_str.name', 'Command-T']
21
+		\ , Pl#Segment#Truncate()
22
+		\ , Pl#Segment#Split()
23
+		\ , ['raw.line', '%10(Match #%l%)']
24
+	\ ),
25
+	\
26
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_tree')
27
+		\ , ['static_str.name', 'Gundo']
28
+		\ , ['static_str.buffer', 'Undo tree']
29
+		\ , Pl#Segment#Truncate()
30
+		\ , Pl#Segment#Split()
31
+	\ ),
32
+	\
33
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_preview')
34
+		\ , ['static_str.name', 'Gundo']
35
+		\ , ['static_str.buffer', 'Diff preview']
36
+		\ , Pl#Segment#Truncate()
37
+		\ , Pl#Segment#Split()
38
+	\ ),
39
+	\
40
+	\ Pl#Theme#Buffer('bt_help'
41
+		\ , ['static_str.name', 'Help']
42
+		\ , 'filename'
43
+		\ , Pl#Segment#Truncate()
44
+		\ , Pl#Segment#Split()
45
+		\ , 'scrollpercent'
46
+	\ ),
47
+	\
48
+	\ Pl#Theme#Buffer('ft_vimpager'
49
+		\ , ['static_str.name', 'Pager']
50
+		\ , 'filename'
51
+		\ , Pl#Segment#Truncate()
52
+		\ , Pl#Segment#Split()
53
+		\ , 'scrollpercent'
54
+	\ ),
55
+	\
56
+	\ Pl#Theme#Buffer('lustyexplorer'
57
+		\ , ['static_str.name', 'LustyExplorer']
58
+		\ , ['static_str.buffer', 'Buffer list']
59
+		\ , Pl#Segment#Truncate()
60
+		\ , Pl#Segment#Split()
61
+	\ ),
62
+	\
63
+	\ Pl#Theme#Buffer('ft_man'
64
+		\ , ['static_str.name', 'Man page']
65
+		\ , 'filename'
66
+		\ , Pl#Segment#Truncate()
67
+		\ , Pl#Segment#Split()
68
+		\ , 'scrollpercent'
69
+	\ ),
70
+	\
71
+	\ Pl#Theme#Buffer('minibufexplorer'
72
+		\ , ['static_str.name', 'MiniBufExplorer']
73
+		\ , Pl#Segment#Truncate()
74
+		\ , Pl#Segment#Split()
75
+	\ ),
76
+	\
77
+	\ Pl#Theme#Buffer('ft_qf'
78
+		\ , ['static_str.name', 'Quickfix']
79
+		\ , Pl#Segment#Truncate()
80
+		\ , Pl#Segment#Split()
81
+	\ ),
82
+	\
83
+	\ Pl#Theme#Buffer('tagbar'
84
+		\ , ['static_str.name', 'Tagbar']
85
+		\ , ['static_str.buffer', 'Tree']
86
+		\ , Pl#Segment#Truncate()
87
+		\ , Pl#Segment#Split()
88
+	\ ),
89
+	\
90
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_main', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.main = "%s"')
91
+		\ , 'ctrlp:prev'
92
+		\ , 'ctrlp:item'
93
+		\ , 'ctrlp:next'
94
+		\ , 'ctrlp:marked'
95
+		\ , Pl#Segment#Truncate()
96
+		\ , Pl#Segment#Split()
97
+		\ , 'ctrlp:focus'
98
+		\ , 'ctrlp:byfname'
99
+		\ , 'pwd'
100
+	\ ),
101
+	\
102
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_prog', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.prog = "%s"')
103
+		\ , 'ctrlp:count'
104
+		\ , Pl#Segment#Truncate()
105
+		\ , Pl#Segment#Split()
106
+		\ , 'pwd'
107
+	\ ),
108
+	\
109
+	\ Pl#Theme#Buffer('nerdtree'
110
+		\ , ['raw.name', '%{Powerline#Functions#GetShortPath(4)}']
111
+		\ , Pl#Segment#Truncate()
112
+		\ , Pl#Segment#Split()
113
+	\ )
114
+\ )
... ...
@@ -0,0 +1,119 @@
1
+" Authors:
2
+"   @skwp
3
+"
4
+" Disabled:
5
+" Add the following line into the first theme group to see the highlight
6
+" group
7
+" \ , 'currhigroup'
8
+"
9
+" Line info taken out - I know which line number I'm on from the gutter
10
+"\ , 'lineinfo'
11
+let g:Powerline#Themes#solarized256#theme = Pl#Theme#Create(
12
+	\ Pl#Theme#Buffer(''
13
+		\ , 'fugitive:branch'
14
+		\ , 'fileinfo'
15
+		\ , 'flags.mod'
16
+		\ , 'syntastic:errors'
17
+		\ , Pl#Segment#Truncate()
18
+		\ , Pl#Segment#Split()
19
+		\ , 'sass:status'
20
+		\ , 'rvm:string'
21
+		\ , 'paste_indicator'
22
+	\ ),
23
+	\
24
+	\ Pl#Theme#Buffer('command_t'
25
+		\ , ['static_str.name', 'Command-T']
26
+		\ , Pl#Segment#Truncate()
27
+		\ , Pl#Segment#Split()
28
+		\ , ['raw.line', '%10(Match #%l%)']
29
+	\ ),
30
+	\
31
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_tree')
32
+		\ , ['static_str.name', 'Gundo']
33
+		\ , ['static_str.buffer', 'Undo tree']
34
+		\ , Pl#Segment#Truncate()
35
+		\ , Pl#Segment#Split()
36
+	\ ),
37
+	\
38
+	\ Pl#Theme#Buffer('gundo', Pl#Match#Any('gundo_preview')
39
+		\ , ['static_str.name', 'Gundo']
40
+		\ , ['static_str.buffer', 'Diff preview']
41
+		\ , Pl#Segment#Truncate()
42
+		\ , Pl#Segment#Split()
43
+	\ ),
44
+	\
45
+	\ Pl#Theme#Buffer('bt_help'
46
+		\ , ['static_str.name', 'Help']
47
+		\ , 'filename'
48
+		\ , Pl#Segment#Truncate()
49
+		\ , Pl#Segment#Split()
50
+		\ , 'scrollpercent'
51
+	\ ),
52
+	\
53
+	\ Pl#Theme#Buffer('ft_vimpager'
54
+		\ , ['static_str.name', 'Pager']
55
+		\ , 'filename'
56
+		\ , Pl#Segment#Truncate()
57
+		\ , Pl#Segment#Split()
58
+		\ , 'scrollpercent'
59
+	\ ),
60
+	\
61
+	\ Pl#Theme#Buffer('lustyexplorer'
62
+		\ , ['static_str.name', 'LustyExplorer']
63
+		\ , ['static_str.buffer', 'Buffer list']
64
+		\ , Pl#Segment#Truncate()
65
+		\ , Pl#Segment#Split()
66
+	\ ),
67
+	\
68
+	\ Pl#Theme#Buffer('ft_man'
69
+		\ , ['static_str.name', 'Man page']
70
+		\ , 'filename'
71
+		\ , Pl#Segment#Truncate()
72
+		\ , Pl#Segment#Split()
73
+		\ , 'scrollpercent'
74
+	\ ),
75
+	\
76
+	\ Pl#Theme#Buffer('minibufexplorer'
77
+		\ , ['static_str.name', 'MiniBufExplorer']
78
+		\ , Pl#Segment#Truncate()
79
+		\ , Pl#Segment#Split()
80
+	\ ),
81
+	\
82
+	\ Pl#Theme#Buffer('ft_qf'
83
+		\ , ['static_str.name', 'Quickfix']
84
+		\ , Pl#Segment#Truncate()
85
+		\ , Pl#Segment#Split()
86
+	\ ),
87
+	\
88
+	\ Pl#Theme#Buffer('tagbar'
89
+		\ , ['static_str.name', 'Tagbar']
90
+		\ , ['static_str.buffer', 'Tree']
91
+		\ , Pl#Segment#Truncate()
92
+		\ , Pl#Segment#Split()
93
+	\ ),
94
+	\
95
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_main', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.main = "%s"')
96
+		\ , 'ctrlp:prev'
97
+		\ , 'ctrlp:item'
98
+		\ , 'ctrlp:next'
99
+		\ , 'ctrlp:marked'
100
+		\ , Pl#Segment#Truncate()
101
+		\ , Pl#Segment#Split()
102
+		\ , 'ctrlp:focus'
103
+		\ , 'ctrlp:byfname'
104
+		\ , 'pwd'
105
+	\ ),
106
+	\
107
+	\ Pl#Theme#Buffer('ctrlp', Pl#Theme#Callback('ctrlp_prog', 'if ! exists("g:ctrlp_status_func") | let g:ctrlp_status_func = {} | endif | let g:ctrlp_status_func.prog = "%s"')
108
+		\ , 'ctrlp:count'
109
+		\ , Pl#Segment#Truncate()
110
+		\ , Pl#Segment#Split()
111
+		\ , 'pwd'
112
+	\ ),
113
+	\
114
+	\ Pl#Theme#Buffer('nerdtree'
115
+		\ , ['raw.name', '%{Powerline#Functions#GetShortPath(4)}']
116
+		\ , Pl#Segment#Truncate()
117
+		\ , Pl#Segment#Split()
118
+	\ )
119
+\ )
... ...
@@ -0,0 +1,439 @@
1
+*Powerline.txt*	For Vim version 7.3.	Last change: 2011 Nov 23
2
+
3
+                                            ______
4
+         _________                          \    /__
5
+         \_____   \______  _  _____________ /   /'__' ___   ____
6
+          |    ___/  _ \ \/ \/ / __ \_  ___\   / |  |/   \_/ __ \
7
+          |   |  |  (_) \  _  /  ___/|  |  /  /__|  |  |  \  ___/
8
+          '___'   \____/ \/ \/ \___  |__' /___  /'__'__|  /\___ \
9
+                                   \/        / /        \/     \/
10
+                                            | /
11
+                                            |/
12
+                                            '
13
+
14
+==============================================================================
15
+CONTENTS                                                  *Powerline-contents*
16
+
17
+    1. Introduction ....................... |Powerline-introduction|
18
+    2. Usage .............................. |Powerline-usage|
19
+    3. Requirements ....................... |Powerline-requirements|
20
+       3.1 Recommended settings ........... |Powerline-recommended-settings|
21
+    4. Configuration ...................... |Powerline-configuration|
22
+       4.1 Powerline_cache_file ........... |Powerline_cache_file|
23
+           4.1.1 Clearing the cache ....... |:PowerlineClearCache|
24
+           4.1.2 Powerline_cache_dir ...... |Powerline_cache_dir|
25
+       4.2 Powerline_cache_enabled ........ |Powerline_cache_enabled|
26
+       4.3 Powerline_symbols .............. |Powerline_symbols|
27
+           4.3.1 Compatible symbols ....... |Powerline-symbols-compatible|
28
+           4.3.2 Fancy symbols ............ |Powerline-symbols-fancy|
29
+           4.3.3 Overriding symbols ....... |Powerline_symbols_override|
30
+           4.3.4 Overriding dividers ...... |Powerline_dividers_override|
31
+       4.4 Powerline_theme ................ |Powerline_theme|
32
+       4.5 Powerline_colorscheme .......... |Powerline_colorscheme|
33
+       4.6 Powerline_stl_path_style ....... |Powerline_stl_path_style|
34
+    5. Fonts .............................. |Powerline-fonts|
35
+    6. Customization ...................... |Powerline-customization|
36
+       6.1 Basic customization ............ |Powerline-basic-customization|
37
+       6.2 Advanced customization ......... |Powerline-advanced-customization|
38
+           6.2.1 Colorschemes ............. |Powerline-cust-colorschemes|
39
+           6.2.2 Functions ................ |Powerline-cust-functions|
40
+           6.2.3 Segments ................. |Powerline-cust-segments|
41
+           6.2.4 Themes ................... |Powerline-cust-themes|
42
+    7. License ............................ |Powerline-license|
43
+    8. Known issues ....................... |Powerline-known-issues|
44
+    9. Contributing ....................... |Powerline-contributing|
45
+
46
+==============================================================================
47
+1. Introduction                           *Powerline* *Powerline-introduction*
48
+
49
+Powerline is a utility plugin which allows you to create better-looking, more 
50
+functional Vim statuslines.
51
+
52
+==============================================================================
53
+2. Usage                                                     *Powerline-usage*
54
+
55
+Powerline is automatically enabled when it's installed, either by unzipping 
56
+the provided archive or by adding it as a Pathogen/Vundle bundle.
57
+
58
+Powerline replaces the standard Vim 'statusline' with a custom statusline made 
59
+up of Powerline segments.
60
+
61
+Powerline ignores any 'statusline' customizations you have defined in your 
62
+|vimrc|. If you remove Powerline, your 'statusline' customizations are 
63
+restored.
64
+
65
+==============================================================================
66
+3. Requirements                                       *Powerline-requirements*
67
+
68
+Powerline has been developed and tested in Vim 7.3, but it should run without 
69
+any problems in Vim 7.2. The default configuration requires a Unix-like system 
70
+to work properly.
71
+
72
+The plugin only works with Vim running in an 88/256-color terminal or Gvim.
73
+
74
+Vi-compatible mode must be disabled.
75
+
76
+------------------------------------------------------------------------------
77
+3.1 Recommended settings                      *Powerline-recommended-settings*
78
+
79
+The following configuration options should be set in your |vimrc|: >
80
+
81
+    set nocompatible   " Disable vi-compatibility
82
+    set laststatus=2   " Always show the statusline
83
+    set encoding=utf-8 " Necessary to show Unicode glyphs
84
+
85
+Note: If you're using an 88/256-color terminal but still don't see the colored 
86
+statusline, you may have to set the following option as well: >
87
+
88
+    set t_Co=256 " Explicitly tell Vim that the terminal supports 256 colors
89
+
90
+==============================================================================
91
+4. Configuration                                     *Powerline-configuration*
92
+
93
+Powerline will work fine without any user configuration, but default behavior 
94
+can be overridden by setting configuration variables globally in your |vimrc| 
95
+file.
96
+
97
+------------------------------------------------------------------------------
98
+4.1 Powerline_cache_file                                *Powerline_cache_file*
99
+
100
+By default Powerline caches all the statuslines and colors in a cache file in 
101
+the plugin's directory (or the Vim directory, depending on the installation 
102
+method used).
103
+
104
+It's recommended that you enable the cache, as this dramatically improves Vim 
105
+startup time after the cache file has been generated (the plugin usually loads 
106
+within ~100ms without the cache and ~1ms with the cache).
107
+
108
+Note: The default cache filename includes the current theme, colorscheme and 
109
+symbol settings in order to tie the cache file to your current configuration, 
110
+so the cache file will be regenerated when you change any settings. This may 
111
+leave several old cache files in your Vim folder, and these may safely be 
112
+deleted.
113
+
114
+Defaults: "|Powerline_cache_dir|/Powerline_<theme>_<colorscheme>_<symbols>.cache"
115
+
116
+------------------------------------------------------------------------------
117
+4.1.1 Powerline_cache_dir                                *Powerline_cache_dir*
118
+
119
+This is the directory used for |Powerline_cache_file|.
120
+
121
+Default: Plugin directory: >
122
+
123
+    let g:Powerline_cache_dir = simplify(expand('<sfile>:p:h') .'/..')
124
+<
125
+------------------------------------------------------------------------------
126
+4.1.2 Clearing the cache                                *:PowerlineClearCache*
127
+
128
+Powerline provides a command to easily clear the cache after changing your 
129
+settings or updating your theme. Simply run the following command to clear 
130
+your cache, and restart Vim afterwards: >
131
+
132
+    :PowerlineClearCache
133
+<
134
+------------------------------------------------------------------------------
135
+4.2 Powerline_cache_enabled                          *Powerline_cache_enabled*
136
+
137
+It's possible to disable statusline caching by setting this option to 0. This 
138
+is mostly useful when developing statuslines.
139
+
140
+Example: >
141
+
142
+    let g:Powerline_cache_enabled = 0
143
+<
144
+
145
+Default: 1
146
+
147
+------------------------------------------------------------------------------
148
+4.3 Powerline_symbols                                      *Powerline_symbols*
149
+
150
+This option defines which set of symbols and dividers you want to use. There 
151
+are currently three available options: "compatible", "unicode" and "fancy".
152
+
153
+    TYPE           DESCRIPTION ~
154
+    compatible     Doesn't use any special characters.
155
+    unicode        Simulates icons and arrows using similar Unicode glyphs.
156
+    fancy          Custom icons and arrows. Requires a patched font.
157
+
158
+Example: >
159
+
160
+    let g:Powerline_symbols = 'fancy'
161
+<
162
+
163
+Default: "compatible"
164
+
165
+Symbols can be inserted into statuslines by using the following variables 
166
+(just insert the variables as text in your segments):
167
+
168
+    VARIABLE       DESCRIPTION ~
169
+    $BRANCH        Inserts a branch symbol
170
+    $RO            Inserts a read-only symbol
171
+    $FT            Inserts a filetype symbol
172
+    $LINE          Inserts a line number symbol
173
+
174
+------------------------------------------------------------------------------
175
+4.3.1 Compatible symbols                        *Powerline-symbols-compatible*
176
+
177
+These symbols will work in any configuration, and do not require a special 
178
+font to work. This option will replace the fancy icons with plain text, and 
179
+the pointy dividers with straight lines.
180
+
181
+------------------------------------------------------------------------------
182
+4.3.2 Fancy symbols                                  *Powerline-symbols-fancy*
183
+
184
+These symbols require a custom font to work. A font patcher is provided for 
185
+adding the required symbols to any outline font and some bitmap fonts, see 
186
+|Powerline-fonts| and the provided README file for usage details.
187
+
188
+------------------------------------------------------------------------------
189
+4.3.3 Overriding symbols                          *Powerline_symbols_override*
190
+
191
+You can override symbols by adding your symbols to the 
192
+g:Powerline_symbols_override dictionary. Example: If you want the branch 
193
+symbol to be "∓" (hex code 0x2213) and the line symbol to be "L" you can add 
194
+the following to your |vimrc|: >
195
+
196
+    let g:Powerline_symbols_override = {
197
+        \ 'BRANCH': [0x2213],
198
+        \ 'LINE': 'L',
199
+        \ }
200
+<
201
+------------------------------------------------------------------------------
202
+4.3.4 Overriding dividers                        *Powerline_dividers_override*
203
+
204
+If you for some reason want to override the dividers then you can set 
205
+g:Powerline_dividers_override to a list with exactly four elements:
206
+
207
+    1: Hard right-pointing arrow
208
+    2: Soft right-pointing arrow
209
+    3: Hard left-pointing arrow
210
+    4: Soft left-pointing arrow
211
+
212
+Example: >
213
+
214
+    let g:Powerline_dividers_override = ['>>', '>', '<<', '<']
215
+<
216
+
217
+------------------------------------------------------------------------------
218
+4.3.5 Overriding mode names                                   *Powerline_mode*
219
+
220
+You can change the names used for modes at the far left by setting some
221
+variables in your |vimrc|. For example you can change "N" to "NORMAL" with: >
222
+
223
+    let g:Powerline_mode_n = 'NORMAL'
224
+<
225
+The variables are all named beginning with 'g:Powerline_mode_', as follows:
226
+
227
+mode                name    default       note ~
228
+Normal              n       ' N '         (surrounded by spaces)
229
+Insert              i       INSERT
230
+Replace             R       REPLACE       |Replace-mode|
231
+Visual              v       VISUAL        |Visual-mode|
232
+Visual linewise     V       Vâ‹…LINE
233
+Visual blockwise    cv      Vâ‹…BLOCK
234
+Select              s       SELECT        |Select-mode|
235
+Select linewise     S       Sâ‹…LINE
236
+Select blockwise    cs      Sâ‹…BLOCK
237
+
238
+-----------------------------------------------------------------------------
239
+4.4 Powerline_theme                                          *Powerline_theme*
240
+
241
+This option defines the theme Powerline uses. The available themes are located 
242
+in autoload/Powerline/Themes/. A theme is a pre-defined set of Powerline 
243
+segments which make up the statusline.
244
+
245
+Example: >
246
+
247
+    let g:Powerline_theme = 'solarized256'
248
+<
249
+
250
+Default: "default"
251
+
252
+------------------------------------------------------------------------------
253
+4.5 Powerline_colorscheme                              *Powerline_colorscheme*
254
+
255
+This option defines the colorscheme Powerline uses. The available colorschemes 
256
+are located in autoload/Powerline/Colorschemes/.
257
+
258
+Example: >
259
+
260
+    let g:Powerline_colorscheme = 'solarized256'
261
+<
262
+
263
+Default: "default"
264
+
265
+------------------------------------------------------------------------------
266
+4.6 Powerline_stl_path_style                        *Powerline_stl_path_style*
267
+
268
+There are currently four ways to display the current path and file name. The 
269
+default is to only display the file name like the %t statusline item. By 
270
+setting this configuration value you can choose from the following ways 
271
+display the current path and file name:
272
+
273
+    VALUE      DESCRIPTION ~
274
+    filename   Display only the file name using the %t statusline item.
275
+    short      Display a short path. The home directory is substituted with
276
+               "~", the first directory is displayed with its full name, and
277
+               subsequent directories are shortened to their first letter.
278
+               I.e. "/home/user/foo/bar/baz.vim" becomes "~/f/b/baz.vim" and
279
+               "long/relative/path/foo/bar/baz.vim becomes
280
+               "long/r/p/f/b/baz.vim".
281
+    relative   Display a relative path, similar to the %f statusline item.
282
+    full       Display the full path, similar to the %F statusline item.
283
+
284
+Example: >
285
+
286
+    let g:Powerline_stl_path_style = 'full'
287
+<
288
+
289
+Default: "relative"
290
+
291
+==============================================================================
292
+5. Fonts                                                     *Powerline-fonts*
293
+
294
+TODO
295
+
296
+==============================================================================
297
+6. Customization                                     *Powerline-customization*
298
+
299
+There are currently two ways of customizing Powerline: Basic customization 
300
+using a couple of functions to insert and remove existing segments from the 
301
+statusline, and advanced customization using your own autoload files. The 
302
+customization features of Powerline allow you to create your own statuslines 
303
+without ever touching the original source code.
304
+
305
+------------------------------------------------------------------------------
306
+6.1 Basic customization                        *Powerline-basic-customization*
307
+
308
+Powerline provides the following functions to alter the default statusline 
309
+look. These functions should be called from your |vimrc| file or another file 
310
+which is sourced at Vim startup.
311
+
312
+Note: These functions are currently applied to all statuslines, so if you 
313
+insert a segment after a segment which is present in many statuslines (e.g.  
314
+the "filename" segment), all the statuslines will have the inserted segment.  
315
+This behavior may be changed in a future version of Powerline.
316
+
317
+Note: Remember to clear your cache with |:PowerlineClearCache| after changing 
318
+your statusline!
319
+
320
+Example: >
321
+
322
+    " Insert the charcode segment after the filetype segment
323
+    call Pl#Theme#InsertSegment('charcode', 'after', 'filetype')
324
+
325
+    " Replace the scrollpercent segment with the charcode segment
326
+    call Pl#Theme#ReplaceSegment('scrollpercent', 'fileinfo')
327
+<
328
+                                                      *Pl#Theme#InsertSegment*
329
+Pl#Theme#InsertSegment({newsegment}, {location}, {targetsegment})
330
+
331
+This function inserts {newsegment} before or after {targetsegment}. The 
332
+{location} parameter specifies the location of the new segment, valid values 
333
+are "before" and "after". You can see all the available segments in 
334
+autoload/Powerline/Segments.vim and the files specified in 
335
+|Powerline-cust-segments|.
336
+
337
+Pl#Theme#RemoveSegment({targetsegment})               *Pl#Theme#RemoveSegment*
338
+
339
+This function removes the {targetsegment} segment entirely.
340
+
341
+Pl#Theme#ReplaceSegment({oldsegment}, {newsegment})  *Pl#Theme#ReplaceSegment*
342
+
343
+This function replaces {oldsegment} with {newsegment}.
344
+
345
+------------------------------------------------------------------------------
346
+6.2 Advanced customization                  *Powerline-advanced-customization*
347
+
348
+Because Powerline utilizes Vim's autoload functionality, you can easily create 
349
+your own segments, themes, functions and colorschemes without touching the 
350
+original source code. This is a bit more complex than using the utility 
351
+functions, but it allows you to do a lot more with your statusline.
352
+
353
+Your custom autoload files should be stored in your |runtimepath| (usually in 
354
+"~/.vim/autoload/Powerline/*").
355
+
356
+Note: Remember to clear your cache with |:PowerlineClearCache| after changing 
357
+your statusline!
358
+
359
+6.2.1 Colorschemes                               *Powerline-cust-colorschemes*
360
+------------------------------------------------------------------------------
361
+
362
+Colorschemes should be stored as separate files in 
363
+{runtimepath}/autoload/Powerline/Colorschemes/.
364
+
365
+SYNTAX ~
366
+
367
+TODO
368
+
369
+EXAMPLE ~
370
+
371
+TODO
372
+
373
+6.2.2 Functions                                     *Powerline-cust-functions*
374
+------------------------------------------------------------------------------
375
+
376
+Functions should be stored as separate files in 
377
+{runtimepath}/autoload/Powerline/Functions/.
378
+
379
+SYNTAX ~
380
+
381
+TODO
382
+
383
+EXAMPLE ~
384
+
385
+TODO
386
+
387
+6.2.3 Segments                                       *Powerline-cust-segments*
388
+------------------------------------------------------------------------------
389
+
390
+Segments should be stored as separate files in 
391
+{runtimepath}/autoload/Powerline/Segments/.
392
+
393
+SYNTAX ~
394
+
395
+TODO
396
+
397
+EXAMPLE ~
398
+
399
+TODO
400
+
401
+6.2.4 Themes                                           *Powerline-cust-themes*
402
+------------------------------------------------------------------------------
403
+
404
+Themes should be stored as separate files in 
405
+{runtimepath}/autoload/Powerline/Themes/.
406
+
407
+SYNTAX ~
408
+
409
+TODO
410
+
411
+EXAMPLE ~
412
+
413
+TODO
414
+
415
+==============================================================================
416
+7. License                                                 *Powerline-license*
417
+
418
+Creative Commons Attribution-ShareAlike 3.0 Unported
419
+
420
+http://creativecommons.org/licenses/by-sa/3.0/
421
+
422
+==============================================================================
423
+8. Known issues                                       *Powerline-known-issues*
424
+
425
+See the issue tracker at
426
+https://github.com/Lokaltog/vim-powerline/issues
427
+
428
+==============================================================================
429
+9. Contributing                                       *Powerline-contributing*
430
+
431
+If you experience any bugs or have feature requests, please open an issue on
432
+GitHub. Fork the source repository on GitHub and send a pull request if you
433
+have any code improvements.
434
+
435
+Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
436
+Source repository: https://github.com/Lokaltog/vim-powerline
437
+
438
+==============================================================================
439
+vim:tw=78:sw=4:ts=8:ft=help:norl:
... ...
@@ -0,0 +1,319 @@
1
+SplineFontDB: 3.0
2
+FontName: PowerlineSymbols
3
+FullName: PowerlineSymbols
4
+FamilyName: PowerlineSymbols
5
+Weight: Medium
6
+Copyright: 
7
+UComments: "2011-11-21: Created." 
8
+Version: 001.000
9
+ItalicAngle: 0
10
+UnderlinePosition: -98.6328
11
+UnderlineWidth: 48.8281
12
+Ascent: 800
13
+Descent: 200
14
+LayerCount: 2
15
+Layer: 0 0 "Back"  1
16
+Layer: 1 0 "Fore"  0
17
+XUID: [1021 211 26716215 11021609]
18
+FSType: 0
19
+OS2Version: 0
20
+OS2_WeightWidthSlopeOnly: 0
21
+OS2_UseTypoMetrics: 1
22
+CreationTime: 1321867751
23
+ModificationTime: 1326665029
24
+OS2TypoAscent: 0
25
+OS2TypoAOffset: 1
26
+OS2TypoDescent: 0
27
+OS2TypoDOffset: 1
28
+OS2TypoLinegap: 90
29
+OS2WinAscent: 0
30
+OS2WinAOffset: 1
31
+OS2WinDescent: 0
32
+OS2WinDOffset: 1
33
+HheadAscent: 0
34
+HheadAOffset: 1
35
+HheadDescent: 0
36
+HheadDOffset: 1
37
+OS2Vendor: 'PfEd'
38
+MarkAttachClasses: 1
39
+DEI: 91125
40
+Encoding: UnicodeFull
41
+Compacted: 1
42
+UnicodeInterp: none
43
+NameList: Adobe Glyph List
44
+DisplaySize: -24
45
+AntiAlias: 1
46
+FitToEm: 1
47
+WinInfo: 0 31 18
48
+BeginPrivate: 0
49
+EndPrivate
50
+BeginChars: 1114112 9
51
+
52
+StartChar: uni2B80
53
+Encoding: 11136 11136 0
54
+Width: 621
55
+Flags: HMW
56
+LayerCount: 2
57
+Fore
58
+SplineSet
59
+0 1000 m 1
60
+ 621 379 l 1
61
+ 0 -243 l 1
62
+ 0 1000 l 1
63
+EndSplineSet
64
+EndChar
65
+
66
+StartChar: uni2B81
67
+Encoding: 11137 11137 1
68
+Width: 621
69
+Flags: HMW
70
+LayerCount: 2
71
+Fore
72
+SplineSet
73
+10 991 m 0
74
+ 16 997 23 1000 32 1000 c 0
75
+ 41 1000 48 996 54 990 c 2
76
+ 613 400 l 2
77
+ 619 394 621 386 621 378 c 0
78
+ 621 370 618 362 613 357 c 2
79
+ 54 -233 l 2
80
+ 48 -239 41 -242 32 -242 c 0
81
+ 23 -242 16 -240 10 -234 c 0
82
+ 4 -228 0 -221 0 -212 c 0
83
+ 0 -203 3 -196 8 -190 c 2
84
+ 547 379 l 1
85
+ 8 948 l 2
86
+ 3 954 0 961 0 970 c 0
87
+ 0 979 4 985 10 991 c 0
88
+EndSplineSet
89
+EndChar
90
+
91
+StartChar: uni2B82
92
+Encoding: 11138 11138 2
93
+Width: 621
94
+Flags: HMW
95
+LayerCount: 2
96
+Fore
97
+SplineSet
98
+621 1000 m 5
99
+ 621 -243 l 5
100
+ 0 379 l 5
101
+ 621 1000 l 5
102
+EndSplineSet
103
+EndChar
104
+
105
+StartChar: uni2B83
106
+Encoding: 11139 11139 3
107
+Width: 621
108
+Flags: HMW
109
+LayerCount: 2
110
+Fore
111
+SplineSet
112
+612 991 m 0
113
+ 618 985 621 979 621 970 c 0
114
+ 621 961 619 954 613 948 c 2
115
+ 74 379 l 1
116
+ 613 -190 l 2
117
+ 619 -196 621 -203 621 -212 c 0
118
+ 621 -221 618 -228 612 -234 c 0
119
+ 606 -240 598 -242 589 -242 c 0
120
+ 580 -242 574 -239 568 -233 c 2
121
+ 8 357 l 2
122
+ 3 362 0 370 0 378 c 0
123
+ 0 386 3 394 8 400 c 2
124
+ 568 990 l 2
125
+ 574 996 580 1000 589 1000 c 0
126
+ 598 1000 606 997 612 991 c 0
127
+EndSplineSet
128
+EndChar
129
+
130
+StartChar: uni2B61
131
+Encoding: 11105 11105 4
132
+Width: 555
133
+VWidth: 0
134
+Flags: HMW
135
+LayerCount: 2
136
+Fore
137
+SplineSet
138
+0 800 m 5
139
+ 92 800 l 5
140
+ 92 513 l 5
141
+ 253 513 l 5
142
+ 253 444 l 5
143
+ 0 444 l 5
144
+ 0 800 l 5
145
+236 312 m 5
146
+ 339 312 l 5
147
+ 468 67 l 5
148
+ 468 312 l 5
149
+ 555 312 l 5
150
+ 555 -44 l 5
151
+ 453 -44 l 5
152
+ 323 200 l 5
153
+ 323 -44 l 5
154
+ 236 -44 l 5
155
+ 236 312 l 5
156
+EndSplineSet
157
+EndChar
158
+
159
+StartChar: uni2B60
160
+Encoding: 11104 11104 5
161
+Width: 676
162
+Flags: HMW
163
+LayerCount: 2
164
+Fore
165
+SplineSet
166
+0 197 m 1
167
+ 94 207 419 279 419 384 c 2
168
+ 419 537 l 1
169
+ 278 501 l 1
170
+ 478 794 l 1
171
+ 677 501 l 1
172
+ 536 537 l 1
173
+ 536 384 l 2
174
+ 536 196 208 126 208 21 c 2
175
+ 208 -244 l 1
176
+ 0 -244 l 1
177
+ 0 197 l 1
178
+0 288 m 1
179
+ 0 405 0 944 0 944 c 1
180
+ 208 944 l 1
181
+ 208 944 208 451 208 334 c 1
182
+ 185 311 12 288 0 288 c 1
183
+EndSplineSet
184
+EndChar
185
+
186
+StartChar: uni2B62
187
+Encoding: 11106 11106 6
188
+Width: 428
189
+VWidth: 0
190
+Flags: HMW
191
+LayerCount: 2
192
+Fore
193
+SplineSet
194
+88 677 m 2
195
+ 429 677 l 1
196
+ 429 589 l 1
197
+ 88 589 l 1
198
+ 88 162 l 1
199
+ 198 162 l 1
200
+ 198 343 l 1
201
+ 374 343 l 1
202
+ 374 427 l 1
203
+ 198 427 l 1
204
+ 198 506 l 1
205
+ 429 506 l 1
206
+ 429 274 l 1
207
+ 416 263 391 255 374 255 c 2
208
+ 286 255 l 1
209
+ 286 162 l 2
210
+ 286 114 246 74 198 74 c 2
211
+ 88 74 l 2
212
+ 40 74 0 114 0 162 c 2
213
+ 0 589 l 2
214
+ 0 637 40 677 88 677 c 2
215
+EndSplineSet
216
+EndChar
217
+
218
+StartChar: uni2B63
219
+Encoding: 11107 11107 7
220
+Width: 428
221
+VWidth: 0
222
+Flags: HMW
223
+LayerCount: 2
224
+Fore
225
+SplineSet
226
+0 677 m 5
227
+ 341 677 l 6
228
+ 389 677 429 637 429 589 c 6
229
+ 429 506 l 6
230
+ 429 458 389 418 341 418 c 6
231
+ 287 418 l 5
232
+ 287 162 l 6
233
+ 287 114 247 74 199 74 c 6
234
+ 89 74 l 6
235
+ 41 74 1 114 1 162 c 6
236
+ 1 274 l 6
237
+ 0 274 l 6
238
+ 0 506 l 5
239
+ 89 506 l 5
240
+ 89 162 l 5
241
+ 199 162 l 5
242
+ 199 506 l 5
243
+ 341 506 l 5
244
+ 341 589 l 5
245
+ 0 589 l 5
246
+ 0 677 l 5
247
+EndSplineSet
248
+EndChar
249
+
250
+StartChar: uni2B64
251
+Encoding: 11108 11108 8
252
+Width: 546
253
+VWidth: 0
254
+Flags: HMW
255
+LayerCount: 2
256
+Fore
257
+SplineSet
258
+273 733 m 4
259
+ 429 733 430 538 430 538 c 5
260
+ 430 420 l 5
261
+ 547 420 l 5
262
+ 547 303 l 5
263
+ 547 303 546 -9 273 -9 c 4
264
+ 0 -9 0 303 0 303 c 5
265
+ 0 420 l 5
266
+ 117 420 l 5
267
+ 117 538 l 5
268
+ 117 538 117 733 273 733 c 4
269
+273 655 m 4
270
+ 195 655 195 576 195 420 c 5
271
+ 352 420 l 5
272
+ 352 576 351 655 273 655 c 4
273
+273 342 m 4
274
+ 195 342 195 147 273 147 c 4
275
+ 351 147 351 342 273 342 c 4
276
+EndSplineSet
277
+EndChar
278
+EndChars
279
+BitmapFont: 10 10 8 2 1 
280
+BDFChar: 0 11136 6 0 4 -2 7
281
+JAC+4q"X@:^jlCb
282
+BDFChar: 1 11137 6 0 4 -2 7
283
+J3Y4g#RCta5_&h7
284
+BDFChar: 2 11138 6 1 5 -2 7
285
+#T,OGq"T(n(^L*A
286
+BDFChar: 3 11139 6 1 5 -2 7
287
+#S8+DJ:Km-&-r79
288
+BDFChar: 4 11105 6 1 4 -1 7
289
+J:N1>!0GR3O8o7\
290
+BDFChar: 5 11104 7 0 5 -2 7
291
+^rY<PaN2`d^q]pM
292
+BDFChar: 6 11106 4 1 5 -1 6
293
+G^u0KJ=)F+
294
+BDFChar: 7 11107 4 0 5 -1 6
295
+p]QtGOH>Q3
296
+BDFChar: 8 11108 5 0 5 0 6
297
+0M"b4bku\c
298
+EndBitmapFont
299
+BitmapFont: 12 10 10 2 1 
300
+BDFChar: 0 11136 7 0 6 -2 11
301
+!!%Pbi:-O>r:od>^jlCb
302
+BDFChar: 1 11137 7 0 6 -3 11
303
+!!%O7+:ne]":,P]5_&h7
304
+BDFChar: 2 11138 7 0 6 -2 11
305
+!!!-1*'AWHr-UUH$j6P1
306
+BDFChar: 3 11139 7 0 6 -2 11
307
+!!!--&0O5gJ3Y4g#Qt,-
308
+BDFChar: 4 11105 7 0 5 0 8
309
+J:N1>!$jBP,QIfE
310
+BDFChar: 5 11104 8 0 8 -3 11
311
+z^];.Ma8juqa8j9]a8jQehuLOm^];.Mz
312
+BDFChar: 6 11106 5 1 6 0 8
313
+!-j$]R"1Qc?iU0,
314
+BDFChar: 7 11107 5 0 5 0 7
315
+p]QtGOH>Q3
316
+BDFChar: 8 11108 7 0 5 0 8
317
+0M"`*r63C_GQ7^D
318
+EndBitmapFont
319
+EndSplineFont
... ...
@@ -0,0 +1,164 @@
1
+======================
2
+Powerline font patcher
3
+======================
4
+
5
+:Author: Kim Silkebækken (kim.silkebaekken+vim@gmail.com)
6
+
7
+Description
8
+-----------
9
+
10
+This font patcher creates dividers and symbols for use with Powerline. The 
11
+script requires Python 2 and FontForge compiled with Python bindings.
12
+
13
+Patched fonts are renamed by default (" for Powerline" is added to the font 
14
+name) so they don't conflict with existing fonts. Use the ``--no-rename`` 
15
+option to disable font renaming.
16
+
17
+Glyph table
18
+-----------
19
+
20
+All the glyphs are stored in the ``U+2B60``-``U+2BFF`` range ("Misc symbols 
21
+and arrows").
22
+
23
++------------+-------------------+
24
+| Code point | Description       |
25
++============+===================+
26
+| ``U+2B60`` | Branch symbol     |
27
++------------+-------------------+
28
+| ``U+2B61`` | LN (line) symbol  |
29
++------------+-------------------+
30
+| ``U+2B62`` | FT symbol, part 1 |
31
++------------+-------------------+
32
+| ``U+2B63`` | FT symbol, part 2 |
33
++------------+-------------------+
34
+| ``U+2B64`` | Padlock (closed)  |
35
++------------+-------------------+
36
+| ``U+2B80`` | Hard right arrow  |
37
++------------+-------------------+
38
+| ``U+2B81`` | Soft right arrow  |
39
++------------+-------------------+
40
+| ``U+2B82`` | Hard left arrow   |
41
++------------+-------------------+
42
+| ``U+2B83`` | Soft left arrow   |
43
++------------+-------------------+
44
+
45
+===================
46
+Font patching guide
47
+===================
48
+
49
+There's a `GitHub wiki page`_ dedicated to community-contributed patched 
50
+fonts. You may download one of the fonts on that page if you don't want to 
51
+patch the fonts yourself.
52
+
53
+If you do patch a font that's not included in the wiki (and you have 
54
+permission to distribute it), please include it on the wiki page.
55
+
56
+**Note:** The fonts in the wiki may be outdated, and may have different 
57
+glyphs than the ones provided in the latest version of Powerline. It's 
58
+recommended that you always patch your fonts yourself if you have the 
59
+required software.
60
+
61
+.. _`GitHub wiki page`: https://github.com/Lokaltog/vim-powerline/wiki/Patched-fonts
62
+
63
+Linux
64
+-----
65
+
66
+1. Install fontforge with Python bindings. For Ubuntu users the required 
67
+   package is ``python-fontforge``, for Arch Linux users the required 
68
+   package is ``fontforge``. It should be something similar for other 
69
+   distros.
70
+
71
+2. Run the font patcher::
72
+
73
+       $ /path/to/fontpatcher MyFontFile.ttf
74
+
75
+3. Copy the font file into ``~/.fonts`` (or another X font directory)::
76
+
77
+       $ cp MyFontFile-Powerline.otf ~/.fonts
78
+
79
+   **Note:** If the font is a pure bitmap font (e.g. a PCF font) it will be 
80
+   stored in the BDF format. This is usually not a problem, and you may 
81
+   convert the font back to the PCF format using ``bdftopcf`` if you want 
82
+   to. All other fonts will be stored in the OTF format regardless of the 
83
+   original format.
84
+
85
+4. Update your font cache::
86
+
87
+       $ sudo fc-cache -vf
88
+
89
+   **Note:** If you use vim in rxvt-unicode in the client/daemon mode, you 
90
+   may need to close all running terminals as well for the font to be 
91
+   updated.
92
+
93
+5. **For gvim users:** Update the GUI font in your ``vimrc`` file::
94
+
95
+       set guifont=MyFont\ for\ Powerline
96
+
97
+   **For terminal users:** Update your terminal configuration to use the 
98
+   patched font.
99
+
100
+6. Update your ``vimrc`` configuration to use the new symbols::
101
+
102
+       let g:Powerline_symbols = 'fancy'
103
+
104
+7. Make sure that the cache file is deleted::
105
+
106
+       $ rm /tmp/Powerline.cache
107
+
108
+8. Start vim and enjoy your new statusline!
109
+
110
+OS X
111
+----
112
+
113
+1. Check if you have a FontForge version with Python support by running 
114
+   ``fontforge -version``. You should see something like this::
115
+
116
+       $ fontforge -version
117
+       Copyright (c) 2000-2011 by George Williams.
118
+       Executable based on sources from 13:48 GMT 22-Feb-2011-D.
119
+       Library based on sources from 13:48 GMT 22-Feb-2011.
120
+       fontforge 20110222
121
+       libfontforge 20110222
122
+
123
+   Make sure that the executable version number doesn't have ``NoPython`` in 
124
+   it. If everything looks OK, skip ahead to step 4.
125
+
126
+2. If you have FontForge but with ``NoPython`` in the version number, please 
127
+   try to update to a later version::
128
+
129
+       $ brew uninstall fontforge
130
+       $ brew update
131
+       $ brew install --use-gcc fontforge
132
+
133
+   **Note:** You may have to use ``--use-clang`` instead of ``--use-gcc`` 
134
+   when compiling FontForge.
135
+
136
+3. If you don't have FontForge, install it with Homebrew::
137
+
138
+       $ brew update
139
+       $ brew install --use-gcc fontforge
140
+
141
+4. Patch your fonts by passing the ``fontpatcher`` script as a parameter to 
142
+   FontForge::
143
+
144
+       $ fontforge -script /path/to/fontpatcher MyFontFile.ttf
145
+
146
+5. Install the font by double-clicking the font file in Finder and click 
147
+   "Install this font" from the preview window.
148
+
149
+6. **For gvim users:** Update the GUI font in your ``vimrc`` file::
150
+
151
+       set guifont=MyFont\ for\ Powerline
152
+
153
+   **For terminal users:** Update your terminal configuration to use the 
154
+   patched font.
155
+
156
+7. Update your ``vimrc`` configuration to use the new symbols::
157
+
158
+       let g:Powerline_symbols = 'fancy'
159
+
160
+8. Make sure that the cache file is deleted::
161
+
162
+       $ rm /tmp/Powerline.cache
163
+
164
+9. Start vim and enjoy your new statusline!
... ...
@@ -0,0 +1,240 @@
1
+#!/usr/bin/env python
2
+
3
+"""Font patcher for Powerline.
4
+
5
+Creates dividers and symbols for use with Powerline. Requires FontForge with Python bindings.
6
+
7
+Stores glyphs in the 2b60-2bff Unicode range ("Misc symbols and arrows").
8
+
9
+[2b60] Branch symbol
10
+[2b61] LN (line) symbol
11
+[2b62] FT symbol 1
12
+[2b63] FT symbol 2
13
+[2b64] Padlock (closed) symbol
14
+[2b80] Hard right arrow
15
+[2b81] Soft right arrow
16
+[2b82] Hard left arrow
17
+[2b83] Soft left arrow
18
+"""
19
+
20
+from __future__ import division
21
+
22
+import argparse
23
+import os
24
+import sys
25
+import re
26
+
27
+try:
28
+	import fontforge
29
+	import psMat
30
+except ImportError:
31
+	sys.stderr.write('The required FontForge modules could not be loaded.\n\n')
32
+
33
+	if sys.version_info.major > 2:
34
+		sys.stderr.write('FontForge only supports Python 2. Please run this script with the Python 2 executable - e.g. "python2 {0}"\n'.format(sys.argv[0]))
35
+	else:
36
+		sys.stderr.write('You need FontForge with Python bindings for this script to work.\n')
37
+
38
+	sys.exit(1)
39
+
40
+# Handle command-line arguments
41
+parser = argparse.ArgumentParser(description='Font patcher for Powerline. Creates dividers and symbols in FontForge-compatible font files. Requires FontForge with Python bindings. Stores glyphs in the U+2B80-U+2BFF range ("Miscellaneous symbols and arrows"). Stores the patched font as a new, renamed font file by default.')
42
+
43
+parser.add_argument('fonts', help='font file to patch', metavar='font', nargs='+')
44
+parser.add_argument('--no-rename', help='don\'t add " for Powerline" to the font name', default=True, action='store_false', dest='rename')
45
+parser.add_argument('--symbol-font', help='font file with symbols', metavar='font', dest='symbol_font', default='{0}/PowerlineSymbols.sfd'.format(sys.path[0]))
46
+parser.add_argument('--fix-mono', help='fixes some mono-fonts which have glyphs of 0 widths', default=False, action='store_true', dest='fixmono')
47
+parser.add_argument('--fix-win', help='modifies font names such that Windows correctly recognizes font families', default=False, action='store_true', dest='fixwin')
48
+
49
+args = parser.parse_args()
50
+
51
+SYM_ATTR = {
52
+	# Right/left-aligned glyphs will have their advance width reduced in order to overlap the next glyph slightly
53
+	0x2b60: { 'align': 'c', 'stretch': 'y' , 'overlap': False },
54
+	0x2b61: { 'align': 'c', 'stretch': ''  , 'overlap': False },
55
+	0x2b62: { 'align': 'r', 'stretch': ''  , 'overlap': False },
56
+	0x2b63: { 'align': 'l', 'stretch': ''  , 'overlap': False },
57
+	0x2b64: { 'align': 'c', 'stretch': ''  , 'overlap': False },
58
+	0x2b80: { 'align': 'l', 'stretch': 'xy', 'overlap': True  },
59
+	0x2b81: { 'align': 'l', 'stretch': 'xy', 'overlap': True  },
60
+	0x2b82: { 'align': 'r', 'stretch': 'xy', 'overlap': True  },
61
+	0x2b83: { 'align': 'r', 'stretch': 'xy', 'overlap': True  },
62
+}
63
+
64
+# Open symbol font
65
+try:
66
+	symbols = fontforge.open(args.symbol_font)
67
+except EnvironmentError:
68
+	sys.exit(1)
69
+
70
+# Patch provided fonts
71
+for font_path in args.fonts:
72
+	try:
73
+		font = fontforge.open(font_path)
74
+	except EnvironmentError:
75
+		sys.exit(1)
76
+
77
+	# Rename font
78
+	if args.rename:
79
+		font.familyname += ' for Powerline'
80
+		font.fullname += ' for Powerline'
81
+		font.fontname += 'ForPowerline'
82
+		font.appendSFNTName('English (US)', 'Preferred Family', font.familyname)
83
+		font.appendSFNTName('English (US)', 'Compatible Full', font.fullname)
84
+	if args.fixwin:
85
+		font.fontname = re.sub(r'\W', '', font.familyname)
86
+
87
+	# Force the em size to be equal
88
+	symbols.em = font.em
89
+
90
+	# Initial font dimensions
91
+	font_dim = {
92
+		'xmin'  :    0,
93
+		'ymin'  :    -font.descent,
94
+		'xmax'  :    0,
95
+		'ymax'  :    font.ascent,
96
+
97
+		'width' :    0,
98
+		'height':    0,
99
+	}
100
+
101
+	# Find the biggest char width and height
102
+	#
103
+	# 0x00-0x17f is the Latin Extended-A range
104
+	# 0x2500-0x2600 is the box drawing range
105
+	for glyph in range(0x00, 0x17f) + range(0x2500, 0x2600):
106
+		try:
107
+			(xmin, ymin, xmax, ymax) = font[glyph].boundingBox()
108
+		except TypeError:
109
+			continue
110
+
111
+		if font_dim['width'] == 0:
112
+			font_dim['width'] = font[glyph].width
113
+
114
+		if ymin < font_dim['ymin']: font_dim['ymin'] = ymin
115
+		if ymax > font_dim['ymax']: font_dim['ymax'] = ymax
116
+		if xmax > font_dim['xmax']: font_dim['xmax'] = xmax
117
+
118
+	# Calculate font height
119
+	font_dim['height'] = abs(font_dim['ymin']) + font_dim['ymax']
120
+
121
+	# Update the font encoding to ensure that the Unicode glyphs are available
122
+	font.encoding = 'ISO10646'
123
+
124
+	# Fetch this property before adding outlines
125
+	onlybitmaps = font.onlybitmaps
126
+
127
+	def get_dim(glyph):
128
+		bbox = glyph.boundingBox()
129
+
130
+		return  {
131
+			'xmin'  : bbox[0],
132
+			'ymin'  : bbox[1],
133
+			'xmax'  : bbox[2],
134
+			'ymax'  : bbox[3],
135
+
136
+			'width' : bbox[2] + (-bbox[0]),
137
+			'height': bbox[3] + (-bbox[1]),
138
+		}
139
+
140
+	# Create glyphs from symbol font
141
+	for sym_glyph in symbols.glyphs():
142
+		sym_attr = SYM_ATTR[sym_glyph.unicode]
143
+
144
+		# Prepare symbol glyph dimensions
145
+		sym_dim = get_dim(sym_glyph)
146
+
147
+		# Select and copy symbol from its encoding point
148
+		symbols.selection.select(sym_glyph.encoding)
149
+		symbols.copy()
150
+
151
+		# Select and paste symbol to its unicode code point
152
+		font.selection.select(sym_glyph.unicode)
153
+		font.paste()
154
+
155
+		# Now that we have copy/pasted the glyph, it's time to scale and move it
156
+
157
+		# Handle glyph stretching
158
+		if 'x' in sym_attr['stretch']:
159
+			# Stretch the glyph horizontally
160
+			scale_ratio = font_dim['width'] / sym_dim['width']
161
+
162
+			font.transform(psMat.scale(scale_ratio, 1))
163
+		if 'y' in sym_attr['stretch']:
164
+			# Stretch the glyph vertically
165
+			scale_ratio = font_dim['height'] / sym_dim['height']
166
+
167
+			font.transform(psMat.scale(1, scale_ratio))
168
+
169
+		# Use the dimensions from the pasted and stretched glyph
170
+		sym_dim = get_dim(font[sym_glyph.unicode])
171
+
172
+		# Center-align the glyph vertically
173
+		font_ycenter = font_dim['height'] / 2
174
+		sym_ycenter  = sym_dim['height'] / 2
175
+
176
+		# First move it to the ymax (top)
177
+		font.transform(psMat.translate(0, font_dim['ymax'] - sym_dim['ymax']))
178
+
179
+		# Then move it the y center difference
180
+		font.transform(psMat.translate(0, sym_ycenter - font_ycenter))
181
+
182
+		# Ensure that the glyph doesn't extend outside the font's bounding box
183
+		if sym_dim['width'] > font_dim['width']:
184
+			# The glyph is too wide, scale it down to fit
185
+			scale_matrix = psMat.scale(font_dim['width'] / sym_dim['width'], 1)
186
+
187
+			font.transform(scale_matrix)
188
+
189
+			# Use the dimensions from the stretched glyph
190
+			sym_dim = get_dim(font[sym_glyph.unicode])
191
+
192
+		# Handle glyph alignment
193
+		if sym_attr['align'] == 'c':
194
+			# Center align
195
+			align_matrix = psMat.translate(font_dim['width'] / 2 - sym_dim['width'] / 2 , 0)
196
+		elif sym_attr['align'] == 'r':
197
+			# Right align
198
+			align_matrix = psMat.translate(font_dim['width'] - sym_dim['width'], 0)
199
+		else:
200
+			# No alignment (left alignment)
201
+			align_matrix = psMat.translate(0, 0)
202
+
203
+		font.transform(align_matrix)
204
+
205
+		if sym_attr['overlap'] is True:
206
+			overlap_width = font.em / 48
207
+
208
+			# Stretch the glyph slightly horizontally if it should overlap
209
+			font.transform(psMat.scale((sym_dim['width'] + overlap_width) / sym_dim['width'], 1))
210
+
211
+			if sym_attr['align'] == 'l':
212
+				# The glyph should be left-aligned, so it must be moved overlap_width to the left
213
+				# This only applies to left-aligned glyphs because the glyph is scaled to the right
214
+				font.transform(psMat.translate(-overlap_width, 0))
215
+
216
+		# Ensure the font is considered monospaced on Windows
217
+		font[sym_glyph.unicode].width = font_dim['width']
218
+
219
+	if font.bitmapSizes and not onlybitmaps:
220
+		# If this is an outline font with bitmaps, regenerate bitmaps for the changed glyphs
221
+		font.selection.changed()
222
+
223
+		for size in font.bitmapSizes:
224
+			font.regenBitmaps((size, ))
225
+
226
+	output_name, extension = os.path.split(font_path)[1].rsplit('.', 1)
227
+	if extension.lower() not in ['ttf', 'otf']:
228
+		# Default to OpenType if input is not TrueType/OpenType
229
+		extension = 'otf'
230
+	if args.fixmono:
231
+		for glyph in font.glyphs():
232
+			if glyph.width == 0: glyph.width = font_dim['width']
233
+
234
+	if onlybitmaps:
235
+		# Generate BDF font
236
+		font.generate('{0}-Powerline.bdf'.format(output_name, bitmap_type='bdf'))
237
+	else:
238
+		# Generate OTF/TTF font
239
+		font.generate('{0}-Powerline.{1}'.format(output_name, extension))
240
+
... ...
@@ -0,0 +1,78 @@
1
+" Powerline - The ultimate statusline utility
2
+"
3
+" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
4
+" Source repository: https://github.com/Lokaltog/vim-powerline
5
+
6
+" Script initialization {{{
7
+	if exists('g:Powerline_loaded') || &compatible || version < 702
8
+		finish
9
+	endif
10
+
11
+	let g:Powerline_loaded = 1
12
+" }}}
13
+" Commands {{{
14
+	command! PowerlineClearCache call Pl#ClearCache()
15
+	command! PowerlineReloadColorscheme call Pl#ReloadColorscheme()
16
+" }}}
17
+" Set default options {{{
18
+	for [s:key, s:value] in items({
19
+		\   'theme'            : 'default'
20
+		\ , 'colorscheme'      : 'default'
21
+		\ , 'symbols'          : 'compatible'
22
+		\ , 'symbols_override' : {}
23
+		\ , 'dividers_override': []
24
+		\ , 'stl_path_style'   : 'relative'
25
+		\ , 'cache_enabled'    : 1
26
+		\ })
27
+
28
+		if ! exists('g:Powerline_' . s:key)
29
+			exec printf('let g:Powerline_%s = %s', s:key, string(s:value))
30
+		endif
31
+
32
+		unlet! s:key s:value
33
+	endfor
34
+
35
+	if ! exists('g:Powerline_cache_dir')
36
+		let g:Powerline_cache_dir = simplify(expand('<sfile>:p:h') .'/..')
37
+	endif
38
+
39
+	if ! exists('g:Powerline_cache_file')
40
+		exec 'let g:Powerline_cache_file = '. string(printf('%s/Powerline_%s_%s_%s.cache'
41
+			\ , g:Powerline_cache_dir
42
+			\ , g:Powerline_theme
43
+			\ , g:Powerline_colorscheme
44
+			\ , g:Powerline_symbols
45
+			\ ))
46
+	endif
47
+" }}}
48
+" Autocommands {{{
49
+	function! s:Startup()
50
+		augroup PowerlineMain
51
+			autocmd!
52
+
53
+			" Reload statuslines when changing color scheme
54
+			autocmd ColorScheme *
55
+				\ call Pl#Load()
56
+
57
+			autocmd BufEnter,WinEnter,FileType,BufUnload,CmdWinEnter *
58
+				\ call Pl#UpdateStatusline(1)
59
+
60
+			autocmd BufLeave,WinLeave,CmdWinLeave *
61
+				\ call Pl#UpdateStatusline(0)
62
+
63
+			autocmd BufWritePost */autoload/Powerline/Colorschemes/*.vim
64
+				\ :PowerlineReloadColorscheme
65
+		augroup END
66
+
67
+		let curwindow = winnr()
68
+		for window in range(1, winnr('$'))
69
+			call Pl#UpdateStatusline(window == curwindow, window)
70
+		endfor
71
+	endfunction
72
+
73
+	augroup PowerlineStartup
74
+		autocmd!
75
+
76
+		autocmd VimEnter * call s:Startup()
77
+	augroup END
78
+" }}}
... ...
@@ -0,0 +1,108 @@
1
+" Vim color file
2
+" Maintainer:	Hans Fugal <hans@fugal.net>
3
+" Last Change:	$Date: 2004/06/13 19:30:30 $
4
+" Last Change:	$Date: 2004/06/13 19:30:30 $
5
+" URL:		http://hans.fugal.net/vim/colors/desert.vim
6
+" Version:	$Id: desert.vim,v 1.1 2004/06/13 19:30:30 vimboss Exp $
7
+
8
+" cool help screens
9
+" :he group-name
10
+" :he highlight-groups
11
+" :he cterm-colors
12
+
13
+set background=dark
14
+if version > 580
15
+    " no guarantees for version 5.8 and below, but this makes it stop
16
+    " complaining
17
+    hi clear
18
+    if exists("syntax_on")
19
+	syntax reset
20
+    endif
21
+endif
22
+let g:colors_name="desert"
23
+
24
+hi Normal	guifg=White guibg=grey20
25
+
26
+" highlight groups
27
+hi Cursor	guibg=khaki guifg=slategrey
28
+"hi CursorIM
29
+"hi Directory
30
+"hi DiffAdd
31
+"hi DiffChange
32
+"hi DiffDelete
33
+"hi DiffText
34
+"hi ErrorMsg
35
+hi VertSplit	guibg=#c2bfa5 guifg=grey50 gui=none
36
+hi Folded	guibg=grey30 guifg=gold
37
+hi FoldColumn	guibg=grey30 guifg=tan
38
+hi IncSearch	guifg=slategrey guibg=khaki
39
+"hi LineNr
40
+hi ModeMsg	guifg=goldenrod
41
+hi MoreMsg	guifg=SeaGreen
42
+hi NonText	guifg=LightBlue guibg=grey30
43
+hi Question	guifg=springgreen
44
+hi Search	guibg=peru guifg=wheat
45
+hi SpecialKey	guifg=yellowgreen
46
+hi StatusLine	guibg=#c2bfa5 guifg=black gui=none
47
+hi StatusLineNC	guibg=#c2bfa5 guifg=grey50 gui=none
48
+hi Title	guifg=indianred
49
+hi Visual	gui=none guifg=khaki guibg=olivedrab
50
+"hi VisualNOS
51
+hi WarningMsg	guifg=salmon
52
+"hi WildMenu
53
+"hi Menu
54
+"hi Scrollbar
55
+"hi Tooltip
56
+
57
+" syntax highlighting groups
58
+hi Comment	guifg=SkyBlue
59
+hi Constant	guifg=#ffa0a0
60
+hi Identifier	guifg=palegreen
61
+hi Statement	guifg=khaki
62
+hi PreProc	guifg=indianred
63
+hi Type		guifg=darkkhaki
64
+hi Special	guifg=navajowhite
65
+"hi Underlined
66
+hi Ignore	guifg=grey40
67
+"hi Error
68
+hi Todo		guifg=orangered guibg=yellow2
69
+
70
+" color terminal definitions
71
+hi SpecialKey	ctermfg=darkgreen
72
+hi NonText	cterm=bold ctermfg=darkblue
73
+hi Directory	ctermfg=darkcyan
74
+hi ErrorMsg	cterm=bold ctermfg=7 ctermbg=1
75
+hi IncSearch	cterm=NONE ctermfg=yellow ctermbg=green
76
+hi Search	cterm=NONE ctermfg=grey ctermbg=blue
77
+hi MoreMsg	ctermfg=darkgreen
78
+hi ModeMsg	cterm=NONE ctermfg=brown
79
+hi LineNr	ctermfg=3
80
+hi Question	ctermfg=green
81
+hi StatusLine	cterm=bold,reverse
82
+hi StatusLineNC cterm=reverse
83
+hi VertSplit	cterm=reverse
84
+hi Title	ctermfg=5
85
+hi Visual	cterm=reverse
86
+hi VisualNOS	cterm=bold,underline
87
+hi WarningMsg	ctermfg=1
88
+hi WildMenu	ctermfg=0 ctermbg=3
89
+hi Folded	ctermfg=darkgrey ctermbg=NONE
90
+hi FoldColumn	ctermfg=darkgrey ctermbg=NONE
91
+hi DiffAdd      term=reverse ctermbg=28 ctermfg=254
92
+hi DiffChange   term=reverse ctermbg=darkcyan ctermfg=black
93
+hi DiffText     term=reverse ctermbg=cyan ctermfg=black
94
+hi DiffDelete   term=reverse ctermbg=52 ctermfg=black
95
+hi Comment	ctermfg=darkcyan
96
+hi Constant	ctermfg=brown
97
+hi Special	ctermfg=5
98
+hi Identifier	ctermfg=6
99
+hi Statement	ctermfg=3
100
+hi PreProc	ctermfg=5
101
+hi Type		ctermfg=2
102
+hi Underlined	cterm=underline ctermfg=5
103
+hi Ignore	cterm=bold ctermfg=7
104
+hi Ignore	ctermfg=darkgrey
105
+hi Error	cterm=bold ctermfg=7 ctermbg=1
106
+
107
+
108
+"vim: sw=4
... ...
@@ -0,0 +1,599 @@
1
+" Vim color file --- psc (peak sea color) "Lite version"
2
+" Maintainer:	Pan, Shi Zhu <Go to the following URL for my email>
3
+" URL:		http://vim.sourceforge.net/scripts/script.php?script_id=760
4
+" Last Change:	19 May 2011
5
+" Version:	3.5
6
+"
7
+"	Comments and e-mails are welcomed, thanks.
8
+"
9
+"	The peaksea color is simply a colorscheme with the default settings of
10
+"	the original ps_color. Lite version means there's no custom settings
11
+"	and fancy features such as integration with reloaded.vim 
12
+"
13
+"	The full version of ps_color.vim will be maintained until Vim 8.
14
+"	By then there will be only the lite version: peaksea.vim
15
+"
16
+" Note: Please set the background option in your .vimrc and/or .gvimrc
17
+"
18
+"	It is much better *not* to set 'background' option inside
19
+"	a colorscheme file.  because ":set background" improperly
20
+"	may cause colorscheme be sourced twice
21
+"
22
+" Color Scheme Overview: 
23
+"	:ru syntax/hitest.vim
24
+"
25
+" Relevant Help: 
26
+"	:h highlight-groups
27
+"	:h psc-cterm-color-table
28
+"
29
+" Colors Order:
30
+"	#rrggbb
31
+"
32
+
33
+hi clear
34
+
35
+if exists("syntax_on")
36
+  syntax reset
37
+endif
38
+
39
+let g:colors_name = expand("<sfile>:t:r")
40
+
41
+" I don't want to abuse folding, but here folding is used to avoid confusion. 
42
+if &background=='light' 
43
+  " for background=light {{{2
44
+  " LIGHT COLOR DEFINE START
45
+
46
+  hi Normal		guifg=#000000	guibg=#e0e0e0	gui=NONE
47
+  hi Search		guifg=NONE	guibg=#f8f8f8	gui=NONE
48
+  hi Visual		guifg=NONE	guibg=#a6caf0	gui=NONE
49
+  hi Cursor		guifg=#f0f0f0	guibg=#008000	gui=NONE
50
+  hi CursorIM		guifg=#f0f0f0	guibg=#800080   gui=NONE
51
+  hi Special		guifg=#907000	guibg=NONE	gui=NONE
52
+  hi Comment		guifg=#606000	guibg=NONE	gui=NONE
53
+  hi Number		guifg=#907000	guibg=NONE	gui=NONE
54
+  hi Constant		guifg=#007068	guibg=NONE	gui=NONE
55
+  hi StatusLine		guifg=fg	guibg=#a6caf0	gui=NONE
56
+  hi LineNr		guifg=#686868	guibg=NONE	gui=NONE
57
+  hi Question		guifg=fg	guibg=#d0d090	gui=NONE
58
+  hi PreProc		guifg=#009030	guibg=NONE	gui=NONE
59
+  hi Statement		guifg=#2060a8	guibg=NONE	gui=NONE
60
+  hi Type		guifg=#0850a0	guibg=NONE	gui=NONE
61
+  hi Todo		guifg=#800000	guibg=#e0e090	gui=NONE
62
+  " NOTE THIS IS IN THE WARM SECTION
63
+  hi Error		guifg=#c03000	guibg=NONE	gui=NONE
64
+  hi Identifier		guifg=#a030a0	guibg=NONE	gui=NONE
65
+  hi ModeMsg		guifg=fg	guibg=#b0b0e0	gui=NONE
66
+  hi VisualNOS		guifg=fg	guibg=#b0b0e0	gui=NONE
67
+  hi SpecialKey		guifg=#1050a0	guibg=NONE	gui=NONE
68
+  hi NonText		guifg=#002090	guibg=#d0d0d0	gui=NONE
69
+  hi Directory		guifg=#a030a0	guibg=NONE	gui=NONE
70
+  hi ErrorMsg		guifg=fg	guibg=#f0b090	gui=NONE
71
+  hi MoreMsg		guifg=#489000	guibg=NONE	gui=NONE
72
+  hi Title		guifg=#a030a0	guibg=NONE	gui=NONE
73
+  hi WarningMsg		guifg=#b02000	guibg=NONE	gui=NONE
74
+  hi WildMenu		guifg=fg	guibg=#d0d090	gui=NONE
75
+  hi Folded		guifg=NONE	guibg=#b0e0b0	gui=NONE
76
+  hi FoldColumn		guifg=fg	guibg=#90e090	gui=NONE
77
+  hi DiffAdd		guifg=NONE	guibg=#b0b0e0	gui=NONE
78
+  hi DiffChange		guifg=NONE	guibg=#e0b0e0	gui=NONE
79
+  hi DiffDelete		guifg=#002090	guibg=#d0d0d0	gui=NONE
80
+  hi DiffText		guifg=NONE	guibg=#c0e080	gui=NONE
81
+  hi SignColumn		guifg=fg	guibg=#90e090	gui=NONE
82
+
83
+  hi IncSearch		guifg=#f0f0f0	guibg=#806060	gui=NONE
84
+  hi StatusLineNC	guifg=fg	guibg=#c0c0c0	gui=NONE
85
+  hi VertSplit		guifg=fg	guibg=#c0c0c0	gui=NONE
86
+  hi Underlined		guifg=#6a5acd	guibg=NONE	gui=underline
87
+  hi Ignore		guifg=bg	guibg=NONE
88
+  " NOTE THIS IS IN THE WARM SECTION
89
+  if v:version >= 700
90
+    if has('spell')
91
+      hi SpellBad	guifg=NONE	guibg=NONE	guisp=#c03000
92
+      hi SpellCap	guifg=NONE	guibg=NONE	guisp=#2060a8
93
+      hi SpellRare	guifg=NONE	guibg=NONE	guisp=#a030a0
94
+      hi SpellLocal	guifg=NONE	guibg=NONE	guisp=#007068
95
+    endif
96
+    hi Pmenu		guifg=fg	guibg=#e0b0e0
97
+    hi PmenuSel		guifg=#f0f0f0	guibg=#806060	gui=NONE
98
+    hi PmenuSbar	guifg=fg	guibg=#c0c0c0	gui=NONE
99
+    hi PmenuThumb	guifg=fg	guibg=#c0e080	gui=NONE
100
+    hi TabLine		guifg=fg	guibg=#c0c0c0	gui=NONE
101
+    hi TabLineFill	guifg=fg	guibg=#c0c0c0	gui=NONE
102
+    hi TabLineSel	guifg=fg	guibg=NONE	gui=NONE
103
+    hi CursorColumn	guifg=NONE	guibg=#f0b090
104
+    hi CursorLine	guifg=NONE	guibg=NONE	gui=underline
105
+    hi MatchParen	guifg=NONE	guibg=#c0e080
106
+  endif
107
+
108
+  " LIGHT COLOR DEFINE END
109
+
110
+  " Vim 7 added stuffs
111
+  if v:version >= 700
112
+    hi Ignore		gui=NONE
113
+
114
+    " the gui=undercurl guisp could only support in Vim 7
115
+    if has('spell')
116
+      hi SpellBad	gui=undercurl
117
+      hi SpellCap	gui=undercurl
118
+      hi SpellRare	gui=undercurl
119
+      hi SpellLocal	gui=undercurl
120
+    endif
121
+    hi TabLine		gui=underline
122
+    hi TabLineFill	gui=underline
123
+    hi CursorLine	gui=underline
124
+  endif
125
+
126
+  " For reversed stuffs, clear the reversed prop and set the bold prop again
127
+  hi IncSearch		gui=bold
128
+  hi StatusLine		gui=bold
129
+  hi StatusLineNC	gui=bold
130
+  hi VertSplit		gui=bold
131
+  hi Visual		gui=bold
132
+
133
+  " Enable the bold property
134
+  hi Question		gui=bold
135
+  hi DiffText		gui=bold
136
+  hi Statement		gui=bold
137
+  hi Type		gui=bold
138
+  hi MoreMsg		gui=bold
139
+  hi ModeMsg		gui=bold
140
+  hi NonText		gui=bold
141
+  hi Title		gui=bold
142
+  hi DiffDelete		gui=bold
143
+  hi TabLineSel		gui=bold
144
+
145
+  " gui define for background=light end here
146
+
147
+  " generally, a dumb terminal is dark, we assume the light terminal has 256
148
+  " color support.
149
+  if &t_Co==8 || &t_Co==16
150
+    set t_Co=256
151
+  endif
152
+  if &t_Co==256
153
+    " 256color light terminal support here
154
+
155
+    hi Normal		ctermfg=16	ctermbg=254	cterm=NONE
156
+    " Comment/Uncomment the following line to disable/enable transparency
157
+    "hi Normal		ctermfg=16	ctermbg=NONE	cterm=NONE
158
+    hi Search		ctermfg=NONE	ctermbg=231	cterm=NONE
159
+    hi Visual		ctermfg=NONE	ctermbg=153	cterm=NONE
160
+    hi Cursor		ctermfg=255	ctermbg=28	cterm=NONE
161
+    hi CursorIM		ctermfg=255	ctermbg=90 cterm=NONE
162
+    hi Special		ctermfg=94	ctermbg=NONE	cterm=NONE
163
+    hi Comment		ctermfg=58	ctermbg=NONE	cterm=NONE
164
+    hi Number		ctermfg=94	ctermbg=NONE	cterm=NONE
165
+    hi Constant		ctermfg=23	ctermbg=NONE	cterm=NONE
166
+    hi StatusLine	ctermfg=fg	ctermbg=153	cterm=NONE
167
+    hi LineNr		ctermfg=242	ctermbg=NONE	cterm=NONE
168
+    hi Question		ctermfg=fg	ctermbg=186	cterm=NONE
169
+    hi PreProc		ctermfg=29	ctermbg=NONE	cterm=NONE
170
+    hi Statement	ctermfg=25	ctermbg=NONE	cterm=NONE
171
+    hi Type		ctermfg=25	ctermbg=NONE	cterm=NONE
172
+    hi Todo		ctermfg=88	ctermbg=186	cterm=NONE
173
+    " NOTE THIS IS IN THE WARM SECTION
174
+    hi Error		ctermfg=130	ctermbg=NONE	cterm=NONE
175
+    hi Identifier	ctermfg=133	ctermbg=NONE	cterm=NONE
176
+    hi ModeMsg		ctermfg=fg	ctermbg=146	cterm=NONE
177
+    hi VisualNOS	ctermfg=fg	ctermbg=146	cterm=NONE
178
+    hi SpecialKey	ctermfg=25	ctermbg=NONE	cterm=NONE
179
+    hi NonText		ctermfg=18	ctermbg=252	cterm=NONE
180
+    " Comment/Uncomment the following line to disable/enable transparency
181
+    "hi NonText		ctermfg=18	ctermbg=NONE	cterm=NONE
182
+    hi Directory	ctermfg=133	ctermbg=NONE	cterm=NONE
183
+    hi ErrorMsg		ctermfg=fg	ctermbg=216	cterm=NONE
184
+    hi MoreMsg		ctermfg=64	ctermbg=NONE	cterm=NONE
185
+    hi Title		ctermfg=133	ctermbg=NONE	cterm=NONE
186
+    hi WarningMsg	ctermfg=124	ctermbg=NONE	cterm=NONE
187
+    hi WildMenu		ctermfg=fg	ctermbg=186	cterm=NONE
188
+    hi Folded		ctermfg=NONE	ctermbg=151	cterm=NONE
189
+    hi FoldColumn	ctermfg=fg	ctermbg=114	cterm=NONE
190
+    hi DiffAdd		ctermfg=NONE	ctermbg=146	cterm=NONE
191
+    hi DiffChange	ctermfg=NONE	ctermbg=182	cterm=NONE
192
+    hi DiffDelete	ctermfg=18	ctermbg=252	cterm=NONE
193
+    hi DiffText		ctermfg=NONE	ctermbg=150	cterm=NONE
194
+    hi SignColumn	ctermfg=fg	ctermbg=114	cterm=NONE
195
+
196
+    hi IncSearch	ctermfg=255	ctermbg=95	cterm=NONE
197
+    hi StatusLineNC	ctermfg=fg	ctermbg=250	cterm=NONE
198
+    hi VertSplit	ctermfg=fg	ctermbg=250	cterm=NONE
199
+    hi Underlined	ctermfg=62	ctermbg=NONE	cterm=underline
200
+    hi Ignore		ctermfg=bg	ctermbg=NONE
201
+    " NOTE THIS IS IN THE WARM SECTION
202
+    if v:version >= 700
203
+      if has('spell')
204
+        if 0
205
+          " ctermsp is not supported in Vim7, we ignore it.
206
+          hi SpellBad	cterm=undercurl	ctermbg=NONE	ctermfg=130
207
+          hi SpellCap	cterm=undercurl	ctermbg=NONE	ctermfg=25
208
+          hi SpellRare	cterm=undercurl	ctermbg=NONE	ctermfg=133
209
+          hi SpellLocal	cterm=undercurl	ctermbg=NONE	ctermfg=23
210
+        else
211
+          hi SpellBad	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
212
+          hi SpellCap	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
213
+          hi SpellRare	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
214
+          hi SpellLocal	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
215
+        endif
216
+      endif
217
+      hi Pmenu		ctermfg=fg	ctermbg=182
218
+      hi PmenuSel	ctermfg=255	ctermbg=95	cterm=NONE
219
+      hi PmenuSbar	ctermfg=fg	ctermbg=250	cterm=NONE
220
+      hi PmenuThumb	ctermfg=fg	ctermbg=150	cterm=NONE
221
+      hi TabLine	ctermfg=fg	ctermbg=250	cterm=NONE
222
+      hi TabLineFill	ctermfg=fg	ctermbg=250	cterm=NONE
223
+      hi TabLineSel	ctermfg=fg	ctermbg=NONE	cterm=NONE
224
+      hi CursorColumn	ctermfg=NONE	ctermbg=216
225
+      hi CursorLine	ctermfg=NONE	ctermbg=NONE	cterm=underline
226
+      hi MatchParen	ctermfg=NONE	ctermbg=150
227
+    endif
228
+
229
+    hi TabLine		cterm=underline
230
+    hi TabLineFill	cterm=underline
231
+    hi CursorLine	cterm=underline
232
+
233
+    " For reversed stuffs, clear the reversed prop and set the bold prop again
234
+    hi IncSearch	cterm=bold
235
+    hi StatusLine	cterm=bold
236
+    hi StatusLineNC	cterm=bold
237
+    hi VertSplit	cterm=bold
238
+    hi Visual		cterm=bold
239
+
240
+    hi NonText		cterm=bold
241
+    hi Question		cterm=bold
242
+    hi Title		cterm=bold
243
+    hi DiffDelete	cterm=bold
244
+    hi DiffText		cterm=bold
245
+    hi Statement	cterm=bold
246
+    hi Type		cterm=bold
247
+    hi MoreMsg		cterm=bold
248
+    hi ModeMsg		cterm=bold
249
+    hi TabLineSel	cterm=bold
250
+
251
+    "hi lCursor		ctermfg=bg	ctermbg=fg	cterm=NONE
252
+  endif " t_Co==256
253
+  " }}}2
254
+elseif &background=='dark' 
255
+  " for background=dark {{{2
256
+  " DARK COLOR DEFINE START
257
+
258
+  hi Normal		guifg=#d0d0d0	guibg=#202020	gui=NONE
259
+  hi Comment		guifg=#d0d090	guibg=NONE	gui=NONE
260
+  hi Constant		guifg=#80c0e0	guibg=NONE	gui=NONE
261
+  hi Number		guifg=#e0c060	guibg=NONE	gui=NONE
262
+  hi Identifier		guifg=#f0c0f0	guibg=NONE	gui=NONE
263
+  hi Statement		guifg=#c0d8f8	guibg=NONE	gui=NONE
264
+  hi PreProc		guifg=#60f080	guibg=NONE	gui=NONE
265
+  hi Type		guifg=#b0d0f0	guibg=NONE	gui=NONE
266
+  hi Special		guifg=#e0c060	guibg=NONE	gui=NONE
267
+  hi Error		guifg=#f08060	guibg=NONE	gui=NONE
268
+  hi Todo		guifg=#800000	guibg=#d0d090	gui=NONE
269
+  hi Search		guifg=NONE	guibg=#800000	gui=NONE
270
+  hi Visual		guifg=#000000	guibg=#a6caf0	gui=NONE
271
+  hi Cursor		guifg=#000000	guibg=#00f000	gui=NONE
272
+  " NOTE THIS IS IN THE COOL SECTION
273
+  hi CursorIM		guifg=#000000	guibg=#f0c0f0	gui=NONE
274
+  hi StatusLine		guifg=#000000	guibg=#a6caf0	gui=NONE
275
+  hi LineNr		guifg=#b0b0b0	guibg=NONE	gui=NONE
276
+  hi Question		guifg=#000000	guibg=#d0d090	gui=NONE
277
+  hi ModeMsg		guifg=fg	guibg=#000080	gui=NONE
278
+  hi VisualNOS		guifg=fg	guibg=#000080	gui=NONE
279
+  hi SpecialKey		guifg=#b0d0f0	guibg=NONE	gui=NONE
280
+  hi NonText		guifg=#6080f0	guibg=#101010	gui=NONE
281
+  hi Directory		guifg=#80c0e0	guibg=NONE	gui=NONE
282
+  hi ErrorMsg		guifg=#d0d090	guibg=#800000	gui=NONE
283
+  hi MoreMsg		guifg=#c0e080	guibg=NONE	gui=NONE
284
+  hi Title		guifg=#f0c0f0	guibg=NONE	gui=NONE
285
+  hi WarningMsg		guifg=#f08060	guibg=NONE	gui=NONE
286
+  hi WildMenu		guifg=#000000	guibg=#d0d090	gui=NONE
287
+  hi Folded		guifg=NONE	guibg=#004000	gui=NONE
288
+  hi FoldColumn		guifg=#e0e0e0	guibg=#008000	gui=NONE
289
+  hi DiffAdd		guifg=NONE	guibg=#000080	gui=NONE
290
+  hi DiffChange		guifg=NONE	guibg=#800080	gui=NONE
291
+  hi DiffDelete		guifg=#6080f0	guibg=#202020	gui=NONE
292
+  hi DiffText		guifg=#000000	guibg=#c0e080	gui=NONE
293
+  hi SignColumn		guifg=#e0e0e0	guibg=#008000	gui=NONE
294
+  hi IncSearch		guifg=#000000	guibg=#d0d0d0	gui=NONE
295
+  hi StatusLineNC	guifg=#000000	guibg=#c0c0c0	gui=NONE
296
+  hi VertSplit		guifg=#000000	guibg=#c0c0c0	gui=NONE
297
+  hi Underlined		guifg=#80a0ff	guibg=NONE	gui=underline 
298
+  hi Ignore		guifg=#000000	guibg=NONE
299
+  " NOTE THIS IS IN THE COOL SECTION
300
+  if v:version >= 700
301
+    if has('spell')
302
+    " the guisp= could only support in Vim 7
303
+      hi SpellBad	guifg=NONE	guibg=NONE	guisp=#f08060
304
+      hi SpellCap	guifg=NONE	guibg=NONE	guisp=#6080f0
305
+      hi SpellRare	guifg=NONE	guibg=NONE	guisp=#f0c0f0
306
+      hi SpellLocal	guifg=NONE	guibg=NONE	guisp=#c0d8f8
307
+    endif
308
+    hi Pmenu		guifg=fg	guibg=#800080
309
+    hi PmenuSel		guifg=#000000	guibg=#d0d0d0	gui=NONE
310
+    hi PmenuSbar	guifg=fg	guibg=#000080	gui=NONE
311
+    hi PmenuThumb	guifg=fg	guibg=#008000	gui=NONE
312
+    hi TabLine		guifg=fg	guibg=#008000	gui=NONE
313
+    hi TabLineFill	guifg=fg	guibg=#008000	gui=NONE
314
+    hi TabLineSel	guifg=fg	guibg=NONE	gui=NONE
315
+    hi CursorColumn	guifg=NONE	guibg=#800000	gui=NONE
316
+    hi CursorLine	guifg=NONE	guibg=NONE	gui=underline
317
+    hi MatchParen	guifg=NONE	guibg=#800080
318
+  endif
319
+
320
+  " DARK COLOR DEFINE END
321
+
322
+  " Vim 7 added stuffs
323
+  if v:version >= 700
324
+    hi Ignore	gui=NONE  
325
+
326
+    " the gui=undercurl could only support in Vim 7
327
+    if has('spell')
328
+      hi SpellBad	gui=undercurl  
329
+      hi SpellCap	gui=undercurl  
330
+      hi SpellRare	gui=undercurl  
331
+      hi SpellLocal	gui=undercurl 
332
+    endif
333
+    hi TabLine		gui=underline  
334
+    hi TabLineFill	gui=underline  
335
+    hi Underlined	gui=underline  
336
+    hi CursorLine	gui=underline 
337
+  endif
338
+
339
+  " gui define for background=dark end here
340
+
341
+  if &t_Co==8 || &t_Co==16
342
+    " for 8-color and 16-color term
343
+    " Note: if you want transparent, change all ctermbg=NONE
344
+    " from hi Normal to hi DiffDelete, and hi TabLineSel, CursorLine
345
+    hi Normal		ctermfg=LightGrey   ctermbg=Black
346
+    hi Special		ctermfg=Yellow	    ctermbg=bg
347
+    hi Comment		ctermfg=DarkYellow  ctermbg=bg
348
+    hi Constant		ctermfg=Blue	    ctermbg=bg
349
+    hi Number		ctermfg=Yellow	    ctermbg=bg
350
+    hi LineNr		ctermfg=DarkGrey    ctermbg=bg
351
+    hi PreProc		ctermfg=Green	    ctermbg=bg
352
+    hi Statement	ctermfg=Cyan	    ctermbg=bg
353
+    hi Type		ctermfg=Cyan	    ctermbg=bg
354
+    hi Error		ctermfg=Red	    ctermbg=bg
355
+    hi Identifier	ctermfg=Magenta     ctermbg=bg
356
+    hi SpecialKey	ctermfg=Cyan	    ctermbg=bg
357
+    hi NonText		ctermfg=Blue	    ctermbg=bg
358
+    hi Directory	ctermfg=Blue	    ctermbg=bg
359
+    hi MoreMsg		ctermfg=Green	    ctermbg=bg
360
+    hi Title		ctermfg=Magenta     ctermbg=bg
361
+    hi WarningMsg	ctermfg=Red	    ctermbg=bg
362
+    hi DiffDelete	ctermfg=Blue	    ctermbg=bg
363
+
364
+    hi Search		ctermfg=NONE	    ctermbg=DarkRed
365
+    hi Visual		ctermfg=Black	    ctermbg=DarkCyan
366
+    hi Cursor		ctermfg=Black	    ctermbg=Green
367
+    hi StatusLine	ctermfg=Black	    ctermbg=DarkCyan
368
+    hi Question		ctermfg=Black	    ctermbg=DarkYellow
369
+    hi Todo		ctermfg=DarkRed     ctermbg=DarkYellow
370
+    hi Folded		ctermfg=White	    ctermbg=DarkGreen
371
+    hi ModeMsg		ctermfg=Grey	    ctermbg=DarkBlue
372
+    hi VisualNOS	ctermfg=Grey	    ctermbg=DarkBlue
373
+    hi ErrorMsg		ctermfg=DarkYellow  ctermbg=DarkRed
374
+    hi WildMenu		ctermfg=Black	    ctermbg=DarkYellow
375
+    hi FoldColumn	ctermfg=White	    ctermbg=DarkGreen
376
+    hi SignColumn	ctermfg=White	    ctermbg=DarkGreen
377
+    hi DiffText		ctermfg=Black	    ctermbg=DarkYellow
378
+
379
+    if v:version >= 700
380
+      if has('spell')
381
+        hi SpellBad	ctermfg=NONE	ctermbg=DarkRed
382
+        hi SpellCap	ctermfg=NONE	ctermbg=DarkBlue
383
+        hi SpellRare	ctermfg=NONE	ctermbg=DarkMagenta
384
+        hi SpellLocal	ctermfg=NONE	ctermbg=DarkGreen
385
+      endif
386
+      hi Pmenu		ctermfg=fg	ctermbg=DarkMagenta
387
+      hi PmenuSel	ctermfg=Black	ctermbg=fg
388
+      hi PmenuSbar	ctermfg=fg	ctermbg=DarkBlue
389
+      hi PmenuThumb	ctermfg=fg	ctermbg=DarkGreen
390
+      hi TabLine	ctermfg=fg	ctermbg=DarkGreen	cterm=underline
391
+      hi TabLineFill	ctermfg=fg	ctermbg=DarkGreen	cterm=underline
392
+      hi CursorColumn	ctermfg=NONE	ctermbg=DarkRed
393
+
394
+      hi TabLineSel	ctermfg=fg	ctermbg=bg
395
+      hi CursorLine	ctermfg=NONE	ctermbg=bg		cterm=underline
396
+
397
+      hi MatchParen	ctermfg=NONE	ctermbg=DarkMagenta
398
+    endif
399
+    if &t_Co==8
400
+      " 8 colour terminal support, this assumes 16 colour is available through
401
+      " setting the 'bold' attribute, will get bright foreground colour.
402
+      " However, the bright background color is not available for 8-color terms.
403
+      "
404
+      " You can manually set t_Co=16 in your .vimrc to see if your terminal
405
+      " supports 16 colours, 
406
+      hi DiffText	cterm=none  
407
+      hi Visual		cterm=none  
408
+      hi Cursor		cterm=none  
409
+      hi Comment	cterm=none  
410
+      hi Todo		cterm=none  
411
+      hi StatusLine	cterm=none  
412
+      hi Question	cterm=none  
413
+      hi DiffChange	cterm=none  
414
+      hi ModeMsg	cterm=none  
415
+      hi VisualNOS	cterm=none  
416
+      hi ErrorMsg	cterm=none  
417
+      hi WildMenu	cterm=none  
418
+      hi DiffAdd	cterm=none  
419
+      hi Folded		cterm=none  
420
+      hi DiffDelete	cterm=none  
421
+      hi Normal		cterm=none  
422
+      hi PmenuThumb	cterm=none 
423
+      hi Search		cterm=bold  
424
+      hi Special	cterm=bold  
425
+      hi Constant	cterm=bold  
426
+      hi Number		cterm=bold  
427
+      hi LineNr		cterm=bold  
428
+      hi PreProc	cterm=bold  
429
+      hi Statement	cterm=bold  
430
+      hi Type		cterm=bold  
431
+      hi Error		cterm=bold  
432
+      hi Identifier	cterm=bold  
433
+      hi SpecialKey	cterm=bold  
434
+      hi NonText	cterm=bold  
435
+      hi MoreMsg	cterm=bold  
436
+      hi Title		cterm=bold  
437
+      hi WarningMsg	cterm=bold  
438
+      hi FoldColumn	cterm=bold  
439
+      hi SignColumn	cterm=bold  
440
+      hi Directory	cterm=bold  
441
+      hi DiffDelete	cterm=bold 
442
+    else
443
+      " Background > 7 is only available with 16 or more colors
444
+
445
+      hi WarningMsg	cterm=none  
446
+      hi Search		cterm=none  
447
+      hi Visual		cterm=none  
448
+      hi Cursor		cterm=none  
449
+      hi Special	cterm=none  
450
+      hi Comment	cterm=none  
451
+      hi Constant	cterm=none  
452
+      hi Number		cterm=none  
453
+      hi LineNr		cterm=none  
454
+      hi PreProc	cterm=none  
455
+      hi Todo		cterm=none  
456
+      hi Error		cterm=none  
457
+      hi Identifier	cterm=none  
458
+      hi Folded		cterm=none  
459
+      hi SpecialKey	cterm=none  
460
+      hi Directory	cterm=none  
461
+      hi ErrorMsg	cterm=none  
462
+      hi Normal		cterm=none  
463
+      hi PmenuThumb	cterm=none 
464
+      hi WildMenu	cterm=none  
465
+      hi FoldColumn	cterm=none  
466
+      hi SignColumn	cterm=none  
467
+      hi DiffAdd	cterm=none  
468
+      hi DiffChange	cterm=none  
469
+      hi Question	cterm=none  
470
+      hi StatusLine	cterm=none  
471
+      hi DiffText	cterm=none 
472
+      hi IncSearch	cterm=reverse  
473
+      hi StatusLineNC	cterm=reverse  
474
+      hi VertSplit	cterm=reverse 
475
+
476
+      " Well, well, bold font with color 0-7 is not possible.
477
+      " So, the Question, StatusLine, DiffText cannot act as expected.
478
+
479
+      hi Statement	cterm=none  
480
+      hi Type		cterm=none  
481
+      hi MoreMsg	cterm=none  
482
+      hi ModeMsg	cterm=none  
483
+      hi NonText	cterm=none  
484
+      hi Title		cterm=none  
485
+      hi VisualNOS	cterm=none  
486
+      hi DiffDelete	cterm=none  
487
+      hi TabLineSel	cterm=none 
488
+
489
+    endif
490
+  elseif &t_Co==256
491
+    " 256color dark terminal support here
492
+    hi Normal		ctermfg=252	ctermbg=234	cterm=NONE
493
+    " Comment/Uncomment the following line to disable/enable transparency
494
+    "hi Normal		ctermfg=252	ctermbg=NONE	cterm=NONE
495
+    hi Comment		ctermfg=186	ctermbg=NONE	cterm=NONE
496
+    hi Constant		ctermfg=110	ctermbg=NONE	cterm=NONE
497
+    hi Number		ctermfg=179	ctermbg=NONE	cterm=NONE
498
+    hi Identifier	ctermfg=219	ctermbg=NONE	cterm=NONE
499
+    hi Statement	ctermfg=153	ctermbg=NONE	cterm=NONE
500
+    hi PreProc		ctermfg=84	ctermbg=NONE	cterm=NONE
501
+    hi Type		ctermfg=153	ctermbg=NONE	cterm=NONE
502
+    hi Special		ctermfg=179	ctermbg=NONE	cterm=NONE
503
+    hi Error		ctermfg=209	ctermbg=NONE	cterm=NONE
504
+    hi Todo		ctermfg=88	ctermbg=186	cterm=NONE
505
+    hi Search		ctermfg=NONE	ctermbg=88	cterm=NONE
506
+    hi Visual		ctermfg=16	ctermbg=153	cterm=NONE
507
+    hi Cursor		ctermfg=16	ctermbg=46	cterm=NONE
508
+    " NOTE THIS IS IN THE COOL SECTION
509
+    hi CursorIM		ctermfg=16	ctermbg=219	cterm=NONE
510
+    hi StatusLine	ctermfg=16	ctermbg=153	cterm=NONE
511
+    hi LineNr		ctermfg=249	ctermbg=NONE	cterm=NONE
512
+    hi Question		ctermfg=16	ctermbg=186	cterm=NONE
513
+    hi ModeMsg		ctermfg=fg	ctermbg=18	cterm=NONE
514
+    hi VisualNOS	ctermfg=fg	ctermbg=18	cterm=NONE
515
+    hi SpecialKey	ctermfg=153	ctermbg=NONE	cterm=NONE
516
+    hi NonText		ctermfg=69	ctermbg=233	cterm=NONE
517
+    " Comment/Uncomment the following line to disable/enable transparency
518
+    "hi NonText		ctermfg=69	ctermbg=NONE	cterm=NONE
519
+    hi Directory	ctermfg=110	ctermbg=NONE	cterm=NONE
520
+    hi ErrorMsg		ctermfg=186	ctermbg=88	cterm=NONE
521
+    hi MoreMsg		ctermfg=150	ctermbg=NONE	cterm=NONE
522
+    hi Title		ctermfg=219	ctermbg=NONE	cterm=NONE
523
+    hi WarningMsg	ctermfg=209	ctermbg=NONE	cterm=NONE
524
+    hi WildMenu		ctermfg=16	ctermbg=186	cterm=NONE
525
+    hi Folded		ctermfg=NONE	ctermbg=22	cterm=NONE
526
+    hi FoldColumn	ctermfg=254	ctermbg=28	cterm=NONE
527
+    hi DiffAdd		ctermfg=NONE	ctermbg=18	cterm=NONE
528
+    hi DiffChange	ctermfg=NONE	ctermbg=90	cterm=NONE
529
+    hi DiffDelete	ctermfg=69	ctermbg=234	cterm=NONE
530
+    hi DiffText		ctermfg=16	ctermbg=150	cterm=NONE
531
+    hi SignColumn	ctermfg=254	ctermbg=28	cterm=NONE
532
+    hi IncSearch	ctermfg=16	ctermbg=252	cterm=NONE
533
+    hi StatusLineNC	ctermfg=16	ctermbg=250	cterm=NONE
534
+    hi VertSplit	ctermfg=16	ctermbg=250	cterm=NONE
535
+    hi Underlined	ctermfg=111	ctermbg=NONE	cterm=underline 
536
+    hi Ignore		ctermfg=16	ctermbg=NONE
537
+    " NOTE THIS IS IN THE COOL SECTION
538
+    if v:version >= 700
539
+      if has('spell')
540
+        " the ctermsp= is not supported in Vim 7 we simply ignored
541
+        if 0
542
+          hi SpellBad	cterm=undercurl	ctermbg=NONE	ctermfg=209
543
+          hi SpellCap	cterm=undercurl	ctermbg=NONE	ctermfg=69
544
+          hi SpellRare	cterm=undercurl	ctermbg=NONE	ctermfg=219
545
+          hi SpellLocal	cterm=undercurl	ctermbg=NONE	ctermfg=153
546
+        else
547
+          hi SpellBad	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
548
+          hi SpellCap	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
549
+          hi SpellRare	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
550
+          hi SpellLocal	cterm=undercurl	ctermbg=NONE	ctermfg=NONE
551
+        endif
552
+      endif
553
+      hi Pmenu		ctermfg=fg	ctermbg=90
554
+      hi PmenuSel	ctermfg=16	ctermbg=252	cterm=NONE
555
+      hi PmenuSbar	ctermfg=fg	ctermbg=18	cterm=NONE
556
+      hi PmenuThumb	ctermfg=fg	ctermbg=28	cterm=NONE
557
+      hi TabLine	ctermfg=fg	ctermbg=28	cterm=NONE
558
+      hi TabLineFill	ctermfg=fg	ctermbg=28	cterm=NONE
559
+      hi TabLineSel	ctermfg=fg	ctermbg=NONE	cterm=NONE
560
+      hi CursorColumn	ctermfg=NONE	ctermbg=88	cterm=NONE
561
+      hi CursorLine	ctermfg=NONE	ctermbg=NONE	cterm=underline
562
+      hi MatchParen	ctermfg=NONE	ctermbg=90
563
+      hi TabLine	cterm=underline  
564
+      hi TabLineFill	cterm=underline  
565
+      hi Underlined	cterm=underline  
566
+      hi CursorLine	cterm=underline 
567
+    endif
568
+
569
+  endif " t_Co
570
+
571
+  " }}}2
572
+endif
573
+
574
+" Links:
575
+"
576
+" COLOR LINKS DEFINE START
577
+
578
+hi link		String		Constant
579
+" Character must be different from strings because in many languages
580
+" (especially C, C++) a 'char' variable is scalar while 'string' is pointer,
581
+" mistaken a 'char' for a 'string' will cause disaster!
582
+hi link		Character	Number
583
+hi link		SpecialChar	LineNr
584
+hi link		Tag		Identifier
585
+hi link		cCppOut		LineNr
586
+" The following are not standard hi links, 
587
+" these are used by DrChip
588
+hi link		Warning		MoreMsg
589
+hi link		Notice		Constant
590
+" these are used by Calendar
591
+hi link		CalToday	PreProc
592
+" these are used by TagList
593
+hi link		MyTagListTagName	IncSearch
594
+hi link		MyTagListTagScope	Constant
595
+
596
+" COLOR LINKS DEFINE END
597
+
598
+" vim:et:nosta:sw=2:ts=8:
599
+" vim600:fdm=marker:fdl=1:
... ...
@@ -0,0 +1,43 @@
1
+" Vim color file
2
+" Maintainer:   Ian Langworth
3
+" Last Change:  2004 Dec 24
4
+" Email:        <langworth.com>
5
+
6
+" Color settings inspired by BBEdit for Mac OS, plus I liked
7
+" the low-contrast comments from the 'oceandeep' colorscheme
8
+
9
+set background=light
10
+hi clear
11
+if exists("syntax_on")
12
+    syntax reset
13
+endif
14
+let g:colors_name="tolerable"
15
+
16
+hi Cursor       guifg=white guibg=darkgreen
17
+
18
+hi Normal       gui=none guifg=black guibg=white
19
+hi NonText      gui=none guifg=orange guibg=white
20
+
21
+hi Statement    gui=none guifg=blue
22
+hi Special      gui=none guifg=red
23
+hi Constant     gui=none guifg=darkred
24
+hi Comment      gui=none guifg=#555555
25
+hi Preproc      gui=none guifg=darkcyan
26
+hi Type         gui=none guifg=darkmagenta
27
+hi Identifier   gui=none guifg=darkgreen
28
+hi Title        gui=none guifg=black
29
+
30
+hi StatusLine   gui=none guibg=#333333 guifg=white
31
+hi StatusLineNC gui=none guibg=#333333 guifg=white
32
+hi VertSplit    gui=none guibg=#333333 guifg=white
33
+
34
+hi Visual       gui=none guibg=green guifg=black
35
+hi Search       gui=none guibg=yellow
36
+hi Directory    gui=none guifg=darkblue
37
+hi WarningMsg   gui=none guifg=red 
38
+hi Error        gui=none guifg=white guibg=red
39
+hi Todo         gui=none guifg=black guibg=yellow
40
+
41
+hi MoreMsg      gui=none
42
+hi ModeMsg      gui=none
43
+
... ...
@@ -0,0 +1,248 @@
1
+" Version 2015-08-12.1 - Leader-n = number! Leader-e = nerdtree (:Explore)
2
+set nocompatible    " Use Vim defaults, forget compatibility with vi.
3
+set bs=2            " allow backspacing over everything in insert mode
4
+set wildmenu        " Allows command-line completion with tab
5
+set autoindent      " Copy indent from current line when starting a new line
6
+set smartindent     " Do smart auto indenting when starting  new line
7
+set smarttab        " Honor 'shiftwidth', 'tabstop' or 'softtabstop'
8
+set hlsearch        " highlight all matches for previous search
9
+set nofoldenable    " start unfolded
10
+set foldlevel=0
11
+set nowrap          " no wrapping text lines on the screen (exceptions below)
12
+set sidescroll=5
13
+set listchars+=tab:>-,precedes:<,extends:> " indicators of long lines
14
+
15
+if v:version >= 703
16
+  " Do save the undo tree to file, but not in the local directory.
17
+  " Don't forget to mkdir ~/.vim_undo
18
+  set undodir=~/.vim_undo,.
19
+  set undofile        " undo even after closing and reopening a file
20
+endif
21
+
22
+" The following two lines set the use of perl regex, aka "very magic"
23
+nnoremap / /\v
24
+vnoremap / /\v
25
+
26
+" nnoremap <cr> :noh<cr><cr>     " clear search highlights
27
+
28
+" Commented out because I want tags searches to always be case sensitive.
29
+" Override with \c anywhere in your search.
30
+"set ignorecase      " If you enter all lowercase, it's case insensitive,
31
+"set smartcase       " if you use mixed-case terms, it's case sensitive.
32
+
33
+syntax on
34
+
35
+" If you think this is hard to read,
36
+" change the color of comments in vim, or
37
+" use another color scheme like desert or peaksea
38
+"
39
+set t_Co=256
40
+if v:version >= 703
41
+  set colorcolumn=80
42
+endif
43
+if has('gui_running') " Didn't work: if &term != 'builtin_gui'
44
+  " Light backgrounds for GUI experiences
45
+  set background=light
46
+  " colorscheme peaksea                        " install peaksea
47
+  colorscheme tolerable                        " install tolerable
48
+  if v:version >= 703
49
+    highlight ColorColumn ctermbg=255 guibg=#F6F6F6
50
+  endif
51
+  highlight StatusLine   ctermfg=17 ctermbg=Gray " override scheme (overridden by powerline)
52
+  highlight StatusLineNC ctermfg=20 ctermbg=LightGray" override scheme
53
+  set lines=50 columns=100
54
+else
55
+  " Dark backgrounds for tty experiences
56
+  set background=dark
57
+  colorscheme desert                           " install desert
58
+  if v:version >= 703
59
+    highlight ColorColumn ctermbg=234 guibg=Black " dark gray (or 17, dark blue)
60
+  endif
61
+  highlight StatusLine   ctermfg=20 ctermbg=Gray " override scheme (overridden by powerline)
62
+  highlight StatusLineNC ctermfg=17 ctermbg=DarkGray" override scheme
63
+endif
64
+" highlight Comment     term=bold ctermfg=Blue ctermbg=0 guifg=SlateBlue guibg=Black
65
+
66
+" set mouse=v     " visual mode, not working great for PuTTY
67
+
68
+set tags=tags;/
69
+
70
+set history=50
71
+set ruler
72
+if has('statusline')
73
+  set laststatus=2
74
+  set statusline=%<%f\   " Filename
75
+  set statusline+=%w%h%m%r " Options
76
+  "set statusline+=%{fugitive#statusline()} " Git
77
+  "set statusline+=\ [%{&ff}/%Y]            " filetype
78
+  "set statusline+=\ [%{getcwd()}]          " current dir
79
+  "set statusline+=\ [A=\%03.3b/H=\%02.2B]  " ASCII / Hexadecimal value of char
80
+  set statusline+=%=%-14.(%l,%c%V%)\ %p%%   " Right aligned file nav info
81
+endif
82
+
83
+set encoding=utf-8
84
+
85
+" I don't set comma for mapleader because it's useful for reverse-finding.
86
+" let mapleader = ","
87
+" let g:mapleader = ","
88
+
89
+nmap <leader>w :w!<cr>         " Fast saving
90
+" I use relative number for cursor movement.
91
+nmap <leader>r :set relativenumber!<cr>
92
+nmap <leader>n :set number!<cr>
93
+
94
+
95
+" Useful mappings for managing tabs
96
+"
97
+nmap <leader>th <esc>:tabprevious<cr>
98
+nmap <leader>tl <esc>:tabnext<cr>
99
+nmap <leader>tn :tabnew
100
+nmap <leader>to :tabonly<cr>
101
+nmap <leader>tc :tabclose<cr>
102
+nmap <leader>tm :tabmove
103
+" Opens a new tab with the current buffer's path
104
+nmap <leader>te :tabedit <c-r>=expand("%:p:h")<cr>/
105
+
106
+" pastetoggle
107
+nmap <leader>p :set invpaste paste?<cr>
108
+
109
+nmap <leader>e :NERDTreeToggle<cr>    " install nerdtree (e for Explore)
110
+nmap <leader>l :TlistToggle<cr>       " install taglist
111
+nmap <leader>bd :Bdelete<cr>          " install vim-bbye
112
+
113
+" Visual mode mappings
114
+"""
115
+
116
+" map sort function to a key
117
+vnoremap <leader>s :sort<cr>
118
+
119
+"easier moving of code blocks
120
+vnoremap < <gv  " better indentation
121
+vnoremap > >gv  " better indentation
122
+
123
+" If too many file system events are getting triggered.
124
+set nobackup       " ~ files
125
+set nowritebackup  " Don't write buff to temp, delete orig, rename temp to orig
126
+set noswapfile     " .swp files
127
+
128
+" Allow tags to open another buffer even if this one is modified
129
+set hidden
130
+
131
+" Switch between source and header files
132
+function! SwitchSourceHeader()
133
+  let s:ext  = expand("%:e")
134
+  let s:base = expand("%:t:r")
135
+  let s:cmd  = "find " . s:base
136
+  if (s:ext == "cpp" || s:ext == "c")
137
+    if findfile(s:base . ".h"  ) != "" | exe s:cmd . ".h"   | return | en
138
+    if findfile(s:base . ".hpp") != "" | exe s:cmd . ".hpp" | return | en
139
+  else
140
+    if findfile(s:base . ".cpp") != "" | exe s:cmd . ".cpp" | return | en
141
+    if findfile(s:base . ".c"  ) != "" | exe s:cmd . ".c"   | return | en
142
+  endif
143
+endfunc
144
+
145
+" Demonstrates a way to look in a mirror directory
146
+" function! OpenOther()
147
+"    if expand("%:e") == "cpp"
148
+"      exe "split" fnameescape(expand("%:p:r:s?src?include?").".h")
149
+"    elseif expand("%:e") == "h"
150
+"      exe "split" fnameescape(expand("%:p:r:s?include?src?").".cpp")
151
+"    endif
152
+" endfunc
153
+
154
+" Delete trailing white space on save, useful for Python and CoffeeScript ;)
155
+function! DeleteTrailingWS()
156
+  exe "normal mz"
157
+  %s/\s\+$//ge
158
+  exe "normal `z"
159
+endfunc
160
+
161
+if has("autocmd")
162
+  autocmd! BufWritePost .vimrc source %           " re-source this file when saved.
163
+  autocmd BufWrite *.py :call DeleteTrailingWS()  " Delete trailing whitespace
164
+  " Don't let smartindent unindent the # character in Python files
165
+  autocmd FileType python  inoremap # X<c-h>#
166
+  autocmd FileType python  set expandtab          " Use spaces instead of tabs
167
+  autocmd Filetype make    setl noexpandtab       " ...not for files that use tabs.
168
+
169
+  " Use the vim command %retab before applying the following
170
+  " two with files that have 8-space tabs.
171
+  autocmd FileType c,cpp,python  set tabstop=4
172
+  autocmd FileType c,cpp,python  set shiftwidth=4
173
+
174
+  autocmd FileType python  set foldmethod=indent  " 'za' to fold
175
+  autocmd FileType python  set foldlevel=99
176
+
177
+  autocmd Filetype c,cpp nmap <buffer> <leader>s :call SwitchSourceHeader()<cr>
178
+  autocmd FileType c,cpp set foldmethod=syntax
179
+
180
+  if v:version >= 703
181
+    " I toggle out of relative number when Vim's focus is lost, because
182
+    " if I'm not editing, then I may be referring to errors with line numbers.
183
+    autocmd FocusLost * if &relativenumber | set number | endif
184
+    autocmd FocusGained * if &number | set relativenumber | endif
185
+  endif
186
+
187
+  " Since I have the undo tree saved to disk now (see above), I might prefer to
188
+  " automatically save the file when focus is lost.
189
+  " autocmd FocusLost * silent! wa
190
+
191
+  autocmd BufRead *.txt set tw=78                  " Limit width of text to 78 chars
192
+  autocmd BufRead *.txt set wrap linebreak nolist  " "soft" wrap of existing lines
193
+  autocmd BufRead README set wrap linebreak nolist " "soft" wrap of existing lines
194
+
195
+  autocmd BufRead *.c,*.cpp,*.python,*.h,*.hpp,*.js set nowrap
196
+
197
+  " When editing a file, always jump to the last cursor position
198
+  autocmd BufReadPost *
199
+  \ if line("'\"") > 0 && line ("'\"") <= line("$") |
200
+  \   exe "normal! g'\"" |
201
+  \ endif
202
+endif
203
+
204
+" This requires vim to be compiled with +python
205
+" Use auto complete in insert mode with ctrl-x, ctrl-o
206
+" See :help new-omni-completion for more.
207
+filetype plugin on
208
+set omnifunc=syntaxcomplete#Complete
209
+" Auto completion via ctrl-space (instead of ctrl-x ctrl-o)
210
+" set omnifunc=pythoncomplete#Complete
211
+" inoremap <Nul> <C-x><C-o>
212
+
213
+" This function attempts to reuse the same scratch
214
+" buffer over and over, so you always see output in 
215
+" the same location in your window layout.
216
+function! ExecuteFileIntoScratchBuffer()
217
+  write
218
+  let f=expand("%:p")
219
+  let cur_win = winnr()
220
+  if buflisted("_vim_output")
221
+    exe bufwinnr("_vim_output") . "wincmd w"
222
+    enew
223
+  else
224
+    vnew
225
+    let cur_win = cur_win+1
226
+  endif
227
+  setlocal buftype=nofile
228
+  setlocal bufhidden=delete
229
+  setlocal noswapfile
230
+  silent file _vim_output
231
+  execute '.! "'.f.'"'
232
+  exe cur_win . "wincmd w"
233
+endfunc
234
+nmap <F5> :call ExecuteFileIntoScratchBuffer()<cr>
235
+
236
+" Execute a selection of code
237
+" Use Visual to select a range and then hit ctrl-h to execute it.
238
+if has("python")
239
+python << EOL
240
+import vim
241
+def EvaluateCurrentRange():
242
+    eval(compile('\n'.join(vim.current.range),'','exec'),globals())
243
+EOL
244
+vnoremap <C-h> :py EvaluateCurrentRange()<cr>
245
+endif
246
+
247
+" Install Pathogen for this next call to work
248
+call pathogen#infect()
... ...
@@ -0,0 +1,14 @@
1
+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+                    Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+  0. You just DO WHAT THE FUCK YOU WANT TO.
14
+
... ...
@@ -0,0 +1,60 @@
1
+# dotfiles (home directory .files)
2
+
3
+These are some of David Blume's dot files to be installed
4
+in new user home directories.
5
+
6
+### Getting the project
7
+
8
+You can get a copy of this project by clicking on the
9
+[ZIP](http://git.dlma.com/dotfiles.git/zipball/master)
10
+or [TAR](http://git.dlma.com/dotfiles.git/tarball/master) buttons
11
+near the top right of the GitList web page.
12
+
13
+You can clone from the origin with:
14
+
15
+    git clone ssh://USERNAME@dlma.com/~/git/dotfiles.git
16
+
17
+### Installation 
18
+
19
+Run the following:
20
+
21
+    ~$ mkdir dotfiles
22
+    ~$ cd dotfiles
23
+    dotfiles$ curl -L http://git.dlma.com/dotfiles.git/tarball/master > dotfiles.tar
24
+    dotfiles$ tar -xvf dotfiles.tar
25
+    dotfiles$ rm dotfiles.tar
26
+    dotfiles$ chmod +x setup.sh
27
+
28
+Then, then you run setup.sh, it'll backup your old files to "backup_of_orig_dotfiles".
29
+
30
+    dotfiles$ ./setup.sh
31
+
32
+And see [config.dlma.com](http://config.dlma.com) for more.
33
+
34
+#### What's installed
35
+
36
+1. .bashrc and .bash_profile
37
+2. Vim resources
38
+    1. .vimrc
39
+    2. An empty .vim_undo directory
40
+    3. .vim with the following plugins:
41
+        1. [pathogen](https://github.com/tpope/vim-pathogen).
42
+        2. [bbye for :Bdelete](https://github.com/moll/vim-bbye).
43
+        3. [nerdtree](https://github.com/scrooloose/nerdtree).
44
+        4. [taglist](http://www.vim.org/scripts/script.php?script_id=273).
45
+        5. [vim-powerline](https://github.com/Lokaltog/vim-powerline).
46
+        6. Assorted favorite colors like [desert](https://github.com/dblume/desert.vim).
47
+3. .gitconfig (but it needs vimdiff and github settings.)
48
+
49
+#### What's not installed
50
+
51
+1. Private or public keys, get those from the USB4 bioport in the back of your neck.
52
+
53
+### Is it any good?
54
+
55
+[Yes](https://news.ycombinator.com/item?id=3067434).
56
+
57
+### License
58
+
59
+This software uses the [WTFPL](http://www.wtfpl.net/).
60
+
... ...
@@ -0,0 +1,38 @@
1
+#!/bin/bash
2
+set -eu -o pipefail # See: https://sipb.mit.edu/doc/safe-shell/
3
+
4
+declare -r backup_dir=$HOME/backup_of_orig_dotfiles_`date -Idate`
5
+
6
+if [ ! -d $backup_dir ]; then
7
+    mkdir -p $backup_dir
8
+fi
9
+
10
+# Move original dot files to backup
11
+if [ -e $HOME/.bashrc ]; then
12
+    mv $HOME/.bashrc $backup_dir
13
+fi
14
+if [ -e $HOME/.bash_profile ]; then
15
+    mv $HOME/.bash_profile $backup_dir
16
+fi
17
+if [ -e $HOME/.gitconfig ]; then
18
+    mv $HOME/.gitconfig $backup_dir
19
+fi
20
+if [ -d $HOME/.vim ]; then
21
+    mv $HOME/.vim $backup_dir
22
+fi
23
+
24
+echo Note: Your old dotfiles are backed up to $backup_dir
25
+
26
+# Move new dot files in
27
+mv .bashrc $HOME
28
+mv .bash_profile $HOME
29
+mv .gitconfig $HOME
30
+mv .vim $HOME
31
+
32
+# Make a directory for vim undo
33
+if [ ! -d $HOME/.vim_undo ]; then
34
+    mkdir -p $HOME/.vim_undo
35
+fi
36
+
37
+# Tell David what's left.
38
+echo Done. Check http://config.dlma.com for more.
0 39