RailsEditor 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4248 @@
1
+ " File: taglist.vim
2
+ " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
3
+ " Version: 4.0 Beta 4
4
+ " Last Modified: April 12, 2006
5
+ "
6
+ " The "Tag List" plugin is a source code browser plugin for Vim and provides
7
+ " an overview of the structure of the programming language files and allows
8
+ " you to efficiently browse through source code files for different
9
+ " programming languages. You can visit the taglist plugin home page for more
10
+ " information:
11
+ "
12
+ " http://www.geocities.com/yegappan/taglist
13
+ "
14
+ " You can subscribe to the taglist mailing list to post your questions
15
+ " or suggestions for improvement or to report bugs. Visit the following
16
+ " page for subscribing to the mailing list:
17
+ "
18
+ " http://groups.yahoo.com/group/taglist/
19
+ "
20
+ " For more information about using this plugin, after installing the
21
+ " taglist plugin, use the ":help taglist" command.
22
+ "
23
+ " Installation
24
+ " ------------
25
+ " 1. Download the taglist.zip file and unzip the files to the $HOME/.vim
26
+ " or the $HOME/vimfiles or the $VIM/vimfiles directory. This should
27
+ " unzip the following two files (the directory structure should be
28
+ " preserved):
29
+ "
30
+ " plugin/taglist.vim - main taglist plugin file
31
+ " doc/taglist.txt - documentation (help) file
32
+ "
33
+ " Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath'
34
+ " Vim help pages for more details about installing Vim plugins.
35
+ " 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or
36
+ " $VIM/doc/vimfiles directory, start Vim and run the ":helptags ."
37
+ " command to process the taglist help file.
38
+ " 3. If the exuberant ctags utility is not present in your PATH, then set the
39
+ " Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags
40
+ " utility (not to the directory) in the .vimrc file.
41
+ " 4. If you are running a terminal/console version of Vim and the
42
+ " terminal doesn't support changing the window width then set the
43
+ " 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file.
44
+ " 5. Restart Vim.
45
+ " 6. You can now use the ":TlistToggle" command to open/close the taglist
46
+ " window. You can use the ":help taglist" command to get more
47
+ " information about using the taglist plugin.
48
+ "
49
+ " ****************** Do not modify after this line ************************
50
+
51
+ " Line continuation used here
52
+ let s:cpo_save = &cpo
53
+ set cpo&vim
54
+
55
+ if !exists('loaded_taglist')
56
+ " First time loading the taglist plugin
57
+ "
58
+ " To speed up the loading of Vim, the taglist plugin uses autoload
59
+ " mechanism to load the taglist functions.
60
+ " Only define the configuration variables, user commands and some
61
+ " auto-commands and finish sourcing the file
62
+
63
+ " The taglist plugin requires the built-in Vim system() function. If this
64
+ " function is not available, then don't load the plugin.
65
+ if !exists('*system')
66
+ echomsg 'Taglist: Vim system() built-in function is not available. ' .
67
+ \ 'Plugin is not loaded.'
68
+ let loaded_taglist = 'no'
69
+ let &cpo = s:cpo_save
70
+ finish
71
+ endif
72
+
73
+ " Location of the exuberant ctags tool
74
+ if !exists('Tlist_Ctags_Cmd')
75
+ if executable('exuberant-ctags')
76
+ let Tlist_Ctags_Cmd = 'exuberant-ctags'
77
+ elseif executable('ctags')
78
+ let Tlist_Ctags_Cmd = 'ctags'
79
+ elseif executable('ctags.exe')
80
+ let Tlist_Ctags_Cmd = 'ctags.exe'
81
+ elseif executable('tags')
82
+ let Tlist_Ctags_Cmd = 'tags'
83
+ else
84
+ " echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' .
85
+ " \ 'not found in PATH. Plugin is not loaded.'
86
+ " Skip loading the plugin
87
+ let loaded_taglist = 'no'
88
+ let &cpo = s:cpo_save
89
+ finish
90
+ endif
91
+ endif
92
+
93
+
94
+ " Automatically open the taglist window on Vim startup
95
+ if !exists('Tlist_Auto_Open')
96
+ let Tlist_Auto_Open = 0
97
+ endif
98
+
99
+ " When the taglist window is toggle opened, move the cursor to the
100
+ " taglist window
101
+ if !exists('Tlist_GainFocus_On_ToggleOpen')
102
+ let Tlist_GainFocus_On_ToggleOpen = 0
103
+ endif
104
+
105
+ " Process files even when the taglist window is not open
106
+ if !exists('Tlist_Process_File_Always')
107
+ let Tlist_Process_File_Always = 0
108
+ endif
109
+
110
+ if !exists('Tlist_Show_Menu')
111
+ let Tlist_Show_Menu = 0
112
+ endif
113
+
114
+ " Tag listing sort type - 'name' or 'order'
115
+ if !exists('Tlist_Sort_Type')
116
+ let Tlist_Sort_Type = 'order'
117
+ endif
118
+
119
+ " Tag listing window split (horizontal/vertical) control
120
+ if !exists('Tlist_Use_Horiz_Window')
121
+ let Tlist_Use_Horiz_Window = 0
122
+ endif
123
+
124
+ " Open the vertically split taglist window on the left or on the right
125
+ " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to
126
+ " zero (i.e. only for vertically split windows)
127
+ if !exists('Tlist_Use_Right_Window')
128
+ let Tlist_Use_Right_Window = 0
129
+ endif
130
+
131
+ " Increase Vim window width to display vertically split taglist window.
132
+ " For MS-Windows version of Vim running in a MS-DOS window, this must be
133
+ " set to 0 otherwise the system may hang due to a Vim limitation.
134
+ if !exists('Tlist_Inc_Winwidth')
135
+ if (has('win16') || has('win95')) && !has('gui_running')
136
+ let Tlist_Inc_Winwidth = 0
137
+ else
138
+ let Tlist_Inc_Winwidth = 1
139
+ endif
140
+ endif
141
+
142
+ " Vertically split taglist window width setting
143
+ if !exists('Tlist_WinWidth')
144
+ let Tlist_WinWidth = 30
145
+ endif
146
+
147
+ " Horizontally split taglist window height setting
148
+ if !exists('Tlist_WinHeight')
149
+ let Tlist_WinHeight = 10
150
+ endif
151
+
152
+ " Display tag prototypes or tag names in the taglist window
153
+ if !exists('Tlist_Display_Prototype')
154
+ let Tlist_Display_Prototype = 0
155
+ endif
156
+
157
+ " Display tag scopes in the taglist window
158
+ if !exists('Tlist_Display_Tag_Scope')
159
+ let Tlist_Display_Tag_Scope = 1
160
+ endif
161
+
162
+ " Use single left mouse click to jump to a tag. By default this is disabled.
163
+ " Only double click using the mouse will be processed.
164
+ if !exists('Tlist_Use_SingleClick')
165
+ let Tlist_Use_SingleClick = 0
166
+ endif
167
+
168
+ " Control whether additional help is displayed as part of the taglist or
169
+ " not. Also, controls whether empty lines are used to separate the tag
170
+ " tree.
171
+ if !exists('Tlist_Compact_Format')
172
+ let Tlist_Compact_Format = 0
173
+ endif
174
+
175
+ " Exit Vim if only the taglist window is currently open. By default, this is
176
+ " set to zero.
177
+ if !exists('Tlist_Exit_OnlyWindow')
178
+ let Tlist_Exit_OnlyWindow = 0
179
+ endif
180
+
181
+ " Automatically close the folds for the non-active files in the taglist
182
+ " window
183
+ if !exists('Tlist_File_Fold_Auto_Close')
184
+ let Tlist_File_Fold_Auto_Close = 0
185
+ endif
186
+
187
+ " Close the taglist window when a tag is selected
188
+ if !exists('Tlist_Close_On_Select')
189
+ let Tlist_Close_On_Select = 0
190
+ endif
191
+
192
+ " Automatically update the taglist window to display tags for newly
193
+ " edited files
194
+ if !exists('Tlist_Auto_Update')
195
+ let Tlist_Auto_Update = 1
196
+ endif
197
+
198
+ " Automatically highlight the current tag
199
+ if !exists('Tlist_Auto_Highlight_Tag')
200
+ let Tlist_Auto_Highlight_Tag = 1
201
+ endif
202
+
203
+ " Automatically highlight the current tag on entering a buffer
204
+ if !exists('Tlist_Highlight_Tag_On_BufEnter')
205
+ let Tlist_Highlight_Tag_On_BufEnter = 1
206
+ endif
207
+
208
+ " Enable fold column to display the folding for the tag tree
209
+ if !exists('Tlist_Enable_Fold_Column')
210
+ let Tlist_Enable_Fold_Column = 1
211
+ endif
212
+
213
+ " Display the tags for only one file in the taglist window
214
+ if !exists('Tlist_Show_One_File')
215
+ let Tlist_Show_One_File = 0
216
+ endif
217
+
218
+ if !exists('Tlist_Max_Submenu_Items')
219
+ let Tlist_Max_Submenu_Items = 20
220
+ endif
221
+
222
+ if !exists('Tlist_Max_Tag_Length')
223
+ let Tlist_Max_Tag_Length = 10
224
+ endif
225
+
226
+ " Do not change the name of the taglist title variable. The winmanager
227
+ " plugin relies on this name to determine the title for the taglist
228
+ " plugin.
229
+ let TagList_title = "__Tag_List__"
230
+
231
+ " Taglist debug messages
232
+ let s:tlist_msg = ''
233
+
234
+ " Define the taglist autocommand to automatically open the taglist window
235
+ " on Vim startup
236
+ if g:Tlist_Auto_Open
237
+ autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open()
238
+ endif
239
+
240
+ " Refresh the taglist
241
+ if g:Tlist_Process_File_Always
242
+ autocmd BufEnter * call s:Tlist_Refresh()
243
+ endif
244
+
245
+ if g:Tlist_Show_Menu
246
+ autocmd GUIEnter * call s:Tlist_Menu_Init()
247
+ endif
248
+
249
+ " When the taglist buffer is created when loading a Vim session file,
250
+ " the taglist buffer needs to be initialized. The BufFilePost event
251
+ " is used to handle this case.
252
+ autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load()
253
+
254
+ " Define the user commands to manage the taglist window
255
+ command! -nargs=0 TlistToggle call s:Tlist_Window_Toggle()
256
+ command! -nargs=0 TlistOpen call s:Tlist_Window_Open()
257
+ " For backwards compatiblity define the Tlist command
258
+ command! -nargs=0 Tlist TlistToggle
259
+ command! -nargs=+ -complete=file TlistAddFiles
260
+ \ call s:Tlist_Add_Files(<f-args>)
261
+ command! -nargs=+ -complete=dir TlistAddFilesRecursive
262
+ \ call s:Tlist_Add_Files_Recursive(<f-args>)
263
+ command! -nargs=0 TlistClose call s:Tlist_Window_Close()
264
+ command! -nargs=0 TlistUpdate call s:Tlist_Update_Current_File()
265
+ command! -nargs=0 TlistHighlightTag call s:Tlist_Window_Highlight_Tag(
266
+ \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1)
267
+ " For backwards compatiblity define the TlistSync command
268
+ command! -nargs=0 TlistSync TlistHighlightTag
269
+ command! -nargs=* -complete=buffer TlistShowPrototype
270
+ \ echo Tlist_Get_Tag_Prototype_By_Line(<f-args>)
271
+ command! -nargs=* -complete=buffer TlistShowTag
272
+ \ echo Tlist_Get_Tagname_By_Line(<f-args>)
273
+ command! -nargs=* -complete=file TlistSessionLoad
274
+ \ call s:Tlist_Session_Load(<q-args>)
275
+ command! -nargs=* -complete=file TlistSessionSave
276
+ \ call s:Tlist_Session_Save(<q-args>)
277
+ command! TlistLock let Tlist_Auto_Update=0
278
+ command! TlistUnlock let Tlist_Auto_Update=1
279
+
280
+ " Commands for enabling/disabling debug and to display debug messages
281
+ command! -nargs=? -complete=file TlistDebug
282
+ \ call s:Tlist_Debug_Enable(<q-args>)
283
+ command! -nargs=0 TlistUndebug call s:Tlist_Debug_Disable()
284
+ command! -nargs=0 TlistMessages echo s:tlist_msg
285
+
286
+ " Define autocommands to autoload the taglist plugin when needed.
287
+
288
+ " Trick to get the current script ID
289
+ map <SID>xx <SID>xx
290
+ let s:sid = substitute(maparg('<SID>xx'), '<SNR>\(\d\+_\)xx$', '\1', '')
291
+ unmap <SID>xx
292
+
293
+ exe 'autocmd FuncUndefined *' . s:sid . 'Tlist_* source ' .
294
+ \ escape(expand('<sfile>'), ' ')
295
+ exe 'autocmd FuncUndefined *' . s:sid . 'Tlist_Window_* source ' .
296
+ \ escape(expand('<sfile>'), ' ')
297
+ exe 'autocmd FuncUndefined *' . s:sid . 'Tlist_Menu_* source ' .
298
+ \ escape(expand('<sfile>'), ' ')
299
+ exe 'autocmd FuncUndefined Tlist_* source ' .
300
+ \ escape(expand('<sfile>'), ' ')
301
+ exe 'autocmd FuncUndefined TagList_* source ' .
302
+ \ escape(expand('<sfile>'), ' ')
303
+
304
+ unlet! s:sid
305
+
306
+ let loaded_taglist = 'fast_load_done'
307
+
308
+ " restore 'cpo'
309
+ let &cpo = s:cpo_save
310
+ finish
311
+ endif
312
+
313
+ if loaded_taglist != 'fast_load_done'
314
+ " restore 'cpo'
315
+ let &cpo = s:cpo_save
316
+ finish
317
+ endif
318
+
319
+ " Taglist plugin functionality is available
320
+ let loaded_taglist = 'available'
321
+
322
+ "------------------- end of user configurable options --------------------
323
+
324
+ " Default language specific settings for supported file types and tag types
325
+ "
326
+ " Variable name format:
327
+ "
328
+ " s:tlist_def_{vim_ftype}_settings
329
+ "
330
+ " vim_ftype - Filetype detected by Vim
331
+ "
332
+ " Value format:
333
+ "
334
+ " <ctags_ftype>;<flag>:<name>;<flag>:<name>;...
335
+ "
336
+ " ctags_ftype - File type supported by exuberant ctags
337
+ " flag - Flag supported by exuberant ctags to generate a tag type
338
+ " name - Name of the tag type used in the taglist window to display the
339
+ " tags of this type
340
+ "
341
+
342
+ " assembly language
343
+ let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type'
344
+
345
+ " aspperl language
346
+ let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable'
347
+
348
+ " aspvbs language
349
+ let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable'
350
+
351
+ " awk language
352
+ let s:tlist_def_awk_settings = 'awk;f:function'
353
+
354
+ " beta language
355
+ let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern'
356
+
357
+ " c language
358
+ let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' .
359
+ \ 'v:variable;f:function'
360
+
361
+ " c++ language
362
+ let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' .
363
+ \ 'c:class;g:enum;s:struct;u:union;f:function'
364
+
365
+ " c# language
366
+ let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' .
367
+ \ 'E:event;g:enum;s:struct;i:interface;' .
368
+ \ 'p:properties;m:method'
369
+
370
+ " cobol language
371
+ let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' .
372
+ \ 'P:program;s:section'
373
+
374
+ " eiffel language
375
+ let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature'
376
+
377
+ " erlang language
378
+ let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function'
379
+
380
+ " expect (same as tcl) language
381
+ let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure'
382
+
383
+ " fortran language
384
+ let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' .
385
+ \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' .
386
+ \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine'
387
+
388
+ " HTML language
389
+ let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function'
390
+
391
+ " java language
392
+ let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' .
393
+ \ 'f:field;m:method'
394
+
395
+ " javascript language
396
+ let s:tlist_def_javascript_settings = 'javascript;f:function'
397
+
398
+ " lisp language
399
+ let s:tlist_def_lisp_settings = 'lisp;f:function'
400
+
401
+ " lua language
402
+ let s:tlist_def_lua_settings = 'lua;f:function'
403
+
404
+ " makefiles
405
+ let s:tlist_def_make_settings = 'make;m:macro'
406
+
407
+ " pascal language
408
+ let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure'
409
+
410
+ " perl language
411
+ let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine'
412
+
413
+ " php language
414
+ let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function'
415
+
416
+ " python language
417
+ let s:tlist_def_python_settings = 'python;c:class;m:member;f:function'
418
+
419
+ " rexx language
420
+ let s:tlist_def_rexx_settings = 'rexx;s:subroutine'
421
+
422
+ " ruby language
423
+ let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' .
424
+ \ 'm:singleton method'
425
+
426
+ " scheme language
427
+ let s:tlist_def_scheme_settings = 'scheme;s:set;f:function'
428
+
429
+ " shell language
430
+ let s:tlist_def_sh_settings = 'sh;f:function'
431
+
432
+ " C shell language
433
+ let s:tlist_def_csh_settings = 'sh;f:function'
434
+
435
+ " Z shell language
436
+ let s:tlist_def_zsh_settings = 'sh;f:function'
437
+
438
+ " slang language
439
+ let s:tlist_def_slang_settings = 'slang;n:namespace;f:function'
440
+
441
+ " sml language
442
+ let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' .
443
+ \ 'r:structure;t:type;v:value;f:function'
444
+
445
+ " sql language
446
+ let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' .
447
+ \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure'
448
+
449
+ " tcl language
450
+ let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure'
451
+
452
+ " vera language
453
+ let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' .
454
+ \ 'f:function;g:enum;m:member;p:program;' .
455
+ \ 'P:prototype;t:task;T:typedef;v:variable;' .
456
+ \ 'x:externvar'
457
+
458
+ "verilog language
459
+ let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' .
460
+ \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function'
461
+
462
+ " vim language
463
+ let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function'
464
+
465
+ " yacc language
466
+ let s:tlist_def_yacc_settings = 'yacc;l:label'
467
+
468
+ "------------------- end of language specific options --------------------
469
+
470
+ " Vim window size is changed by the taglist plugin or not
471
+ let s:tlist_winsize_chgd = 0
472
+ " Taglist window is maximized or not
473
+ let s:tlist_win_maximized = 0
474
+ " Name of files in the taglist
475
+ let s:tlist_file_names=''
476
+ " Number of files in the taglist
477
+ let s:tlist_file_count = 0
478
+ " Number of filetypes supported by taglist
479
+ let s:tlist_ftype_count = 0
480
+ " Is taglist part of other plugins like winmanager or cream?
481
+ let s:tlist_app_name = "none"
482
+ " Are we displaying brief help text
483
+ let s:tlist_brief_help = 1
484
+ " List of files removed on user request
485
+ let s:tlist_removed_flist = ""
486
+ " Index of current file displayed in the taglist window
487
+ let s:tlist_cur_file_idx = -1
488
+ " Taglist menu is empty or not
489
+ let s:tlist_menu_empty = 1
490
+
491
+ " An autocommand is used to refresh the taglist window when entering any
492
+ " buffer. We don't want to refresh the taglist window if we are entering the
493
+ " file window from one of the taglist functions. The 'Tlist_Skip_Refresh'
494
+ " variable is used to skip the refresh of the taglist window and is set
495
+ " and cleared appropriately.
496
+ let s:Tlist_Skip_Refresh = 0
497
+
498
+ " Tlist_Window_Display_Help()
499
+ function! s:Tlist_Window_Display_Help()
500
+ if s:tlist_app_name == "winmanager"
501
+ " To handle a bug in the winmanager plugin, add a space at the
502
+ " last line
503
+ call setline('$', ' ')
504
+ endif
505
+
506
+ if s:tlist_brief_help
507
+ " Add the brief help
508
+ call append(0, '" Press <F1> to display help text')
509
+ else
510
+ " Add the extensive help
511
+ call append(0, '" <enter> : Jump to tag definition')
512
+ call append(1, '" o : Jump to tag definition in new window')
513
+ call append(2, '" p : Preview the tag definition')
514
+ call append(3, '" <space> : Display tag prototype')
515
+ call append(4, '" u : Update tag list')
516
+ call append(5, '" s : Select sort field')
517
+ call append(6, '" d : Remove file from taglist')
518
+ call append(7, '" x : Zoom-out/Zoom-in taglist window')
519
+ call append(8, '" + : Open a fold')
520
+ call append(9, '" - : Close a fold')
521
+ call append(10, '" * : Open all folds')
522
+ call append(11, '" = : Close all folds')
523
+ call append(12, '" [[ : Move to the start of previous file')
524
+ call append(13, '" ]] : Move to the start of next file')
525
+ call append(14, '" q : Close the taglist window')
526
+ call append(15, '" <F1> : Remove help text')
527
+ endif
528
+ endfunction
529
+
530
+ " Tlist_Window_Toggle_Help_Text()
531
+ " Toggle taglist plugin help text between the full version and the brief
532
+ " version
533
+ function! s:Tlist_Window_Toggle_Help_Text()
534
+ if g:Tlist_Compact_Format
535
+ " In compact display mode, do not display help
536
+ return
537
+ endif
538
+
539
+ " Include the empty line displayed after the help text
540
+ let brief_help_size = 1
541
+ let full_help_size = 16
542
+
543
+ setlocal modifiable
544
+
545
+ " Set report option to a huge value to prevent informational messages
546
+ " while deleting the lines
547
+ let old_report = &report
548
+ set report=99999
549
+
550
+ " Remove the currently highlighted tag. Otherwise, the help text
551
+ " might be highlighted by mistake
552
+ match none
553
+
554
+ " Toggle between brief and full help text
555
+ if s:tlist_brief_help
556
+ let s:tlist_brief_help = 0
557
+
558
+ " Remove the previous help
559
+ exe '1,' . brief_help_size . ' delete _'
560
+
561
+ " Adjust the start/end line numbers for the files
562
+ call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size)
563
+ else
564
+ let s:tlist_brief_help = 1
565
+
566
+ " Remove the previous help
567
+ exe '1,' . full_help_size . ' delete _'
568
+
569
+ " Adjust the start/end line numbers for the files
570
+ call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size)
571
+ endif
572
+
573
+ call s:Tlist_Window_Display_Help()
574
+
575
+ " Restore the report option
576
+ let &report = old_report
577
+
578
+ setlocal nomodifiable
579
+ endfunction
580
+
581
+ " Taglist debug support
582
+ let s:tlist_debug = 0
583
+
584
+ " File for storing the debug messages
585
+ let s:tlist_debug_file = ''
586
+
587
+ " Tlist_Debug_Enable
588
+ " Enable logging of taglist debug messages.
589
+ function! s:Tlist_Debug_Enable(...)
590
+ let s:tlist_debug = 1
591
+
592
+ " Check whether a valid file name is supplied.
593
+ if a:1 != ''
594
+ let s:tlist_debug_file = fnamemodify(a:1, ':p')
595
+
596
+ " Empty the log file
597
+ exe 'redir! > ' . s:tlist_debug_file
598
+ redir END
599
+
600
+ " Check whether the log file is present/created
601
+ if !filewritable(s:tlist_debug_file)
602
+ call s:Tlist_Warning_Msg('Taglist: Unable to create log file '
603
+ \ . s:tlist_debug_file)
604
+ let s:tlist_debug_file = ''
605
+ endif
606
+ endif
607
+ endfunction
608
+
609
+ " Tlist_Debug_Disable
610
+ " Disable logging of taglist debug messages.
611
+ function! s:Tlist_Debug_Disable(...)
612
+ let s:tlist_debug = 0
613
+ let s:tlist_debug_file = ''
614
+ endfunction
615
+
616
+ " Tlist_Log_Msg
617
+ " Log the supplied debug message along with the time
618
+ function! s:Tlist_Log_Msg(msg)
619
+ if s:tlist_debug
620
+ if s:tlist_debug_file != ''
621
+ exe 'redir >> ' . s:tlist_debug_file
622
+ silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n"
623
+ redir END
624
+ else
625
+ " Log the message into a variable
626
+ " Retain only the last 3000 characters
627
+ let len = strlen(s:tlist_msg)
628
+ if len > 3000
629
+ let s:tlist_msg = strpart(s:tlist_msg, len - 3000)
630
+ endif
631
+ let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' .
632
+ \ a:msg . "\n"
633
+ endif
634
+ endif
635
+ endfunction
636
+
637
+ " Tlist_Warning_Msg()
638
+ " Display a message using WarningMsg highlight group
639
+ function! s:Tlist_Warning_Msg(msg)
640
+ echohl WarningMsg
641
+ echomsg a:msg
642
+ echohl None
643
+ endfunction
644
+
645
+ " Last returned file index for file name lookup.
646
+ " Used to speed up file lookup
647
+ let s:tlist_file_name_idx_cache = -1
648
+
649
+ " Tlist_Get_File_Index()
650
+ " Return the index of the specified filename
651
+ function! s:Tlist_Get_File_Index(fname)
652
+ if s:tlist_file_count == 0
653
+ return -1
654
+ endif
655
+
656
+ " If the new filename is same as the last accessed filename, then
657
+ " return that index
658
+ if s:tlist_file_name_idx_cache != -1 &&
659
+ \ s:tlist_file_name_idx_cache < s:tlist_file_count
660
+ if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname
661
+ " Same as the last accessed file
662
+ return s:tlist_file_name_idx_cache
663
+ endif
664
+ endif
665
+
666
+ " First, check whether the filename is present
667
+ let s_fname = a:fname . "\n"
668
+ let i = stridx(s:tlist_file_names, s_fname)
669
+ if i == -1
670
+ let s:tlist_file_name_idx_cache = -1
671
+ return -1
672
+ endif
673
+
674
+ " Second, compute the file name index
675
+ let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g')
676
+ let s:tlist_file_name_idx_cache = strlen(nl_txt)
677
+ return s:tlist_file_name_idx_cache
678
+ endfunction
679
+
680
+ " Last returned file index for line number lookup.
681
+ " Used to speed up file lookup
682
+ let s:tlist_file_lnum_idx_cache = -1
683
+
684
+ " Tlist_Window_Get_File_Index_By_Linenum()
685
+ " Return the index of the filename present in the specified line number
686
+ " Line number refers to the line number in the taglist window
687
+ function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
688
+ call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')')
689
+
690
+ " First try to see whether the new line number is within the range
691
+ " of the last returned file
692
+ if s:tlist_file_lnum_idx_cache != -1 &&
693
+ \ s:tlist_file_lnum_idx_cache < s:tlist_file_count
694
+ if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start &&
695
+ \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end
696
+ return s:tlist_file_lnum_idx_cache
697
+ endif
698
+ endif
699
+
700
+ let fidx = -1
701
+
702
+ if g:Tlist_Show_One_File
703
+ " Displaying only one file in the taglist window. Check whether
704
+ " the line is within the tags displayed for that file
705
+ if s:tlist_cur_file_idx != -1
706
+ if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start
707
+ \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end
708
+ let fidx = s:tlist_cur_file_idx
709
+ endif
710
+
711
+ endif
712
+ else
713
+ " Do a binary search in the taglist
714
+ let left = 0
715
+ let right = s:tlist_file_count - 1
716
+
717
+ while left < right
718
+ let mid = (left + right) / 2
719
+
720
+ if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end
721
+ let s:tlist_file_lnum_idx_cache = mid
722
+ return mid
723
+ endif
724
+
725
+ if a:lnum < s:tlist_{mid}_start
726
+ let right = mid - 1
727
+ else
728
+ let left = mid + 1
729
+ endif
730
+ endwhile
731
+
732
+ if left >= 0 && left < s:tlist_file_count
733
+ \ && a:lnum >= s:tlist_{left}_start
734
+ \ && a:lnum <= s:tlist_{left}_end
735
+ let fidx = left
736
+ endif
737
+ endif
738
+
739
+ let s:tlist_file_lnum_idx_cache = fidx
740
+
741
+ return fidx
742
+ endfunction
743
+
744
+ " Tlist_Exe_Cmd_No_Acmds
745
+ " Execute the specified Ex command after disabling autocommands
746
+ function! s:Tlist_Exe_Cmd_No_Acmds(cmd)
747
+ let old_eventignore = &eventignore
748
+ set eventignore=all
749
+ exe a:cmd
750
+ let &eventignore = old_eventignore
751
+ endfunction
752
+
753
+ " Tlist_Skip_File()
754
+ " Check whether tag listing is supported for the specified file
755
+ function! s:Tlist_Skip_File(filename, ftype)
756
+ " Skip buffers with no names and buffers with filetype not set
757
+ if a:filename == '' || a:ftype == ''
758
+ return 1
759
+ endif
760
+
761
+ " Skip files which are not supported by exuberant ctags
762
+ " First check whether default settings for this filetype are available.
763
+ " If it is not available, then check whether user specified settings are
764
+ " available. If both are not available, then don't list the tags for this
765
+ " filetype
766
+ let var = 's:tlist_def_' . a:ftype . '_settings'
767
+ if !exists(var)
768
+ let var = 'g:tlist_' . a:ftype . '_settings'
769
+ if !exists(var)
770
+ return 1
771
+ endif
772
+ endif
773
+
774
+ " Skip files which are not readable or files which are not yet stored
775
+ " to the disk
776
+ if !filereadable(a:filename)
777
+ return 1
778
+ endif
779
+
780
+ return 0
781
+ endfunction
782
+
783
+ " Tlist_User_Removed_File
784
+ " Returns 1 if a file is removed by a user from the taglist
785
+ function! s:Tlist_User_Removed_File(filename)
786
+ return stridx(s:tlist_removed_flist, a:filename . "\n") != -1
787
+ endfunction
788
+
789
+ " Tlist_Update_Remove_List
790
+ " Update the list of user removed files from the taglist
791
+ " add == 1, add the file to the removed list
792
+ " add == 0, delete the file from the removed list
793
+ function! s:Tlist_Update_Remove_List(filename, add)
794
+ if a:add
795
+ let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n"
796
+ else
797
+ let idx = stridx(s:tlist_removed_flist, a:filename . "\n")
798
+ let text_before = strpart(s:tlist_removed_flist, 0, idx)
799
+ let rem_text = strpart(s:tlist_removed_flist, idx)
800
+ let next_idx = stridx(rem_text, "\n")
801
+ let text_after = strpart(rem_text, next_idx + 1)
802
+
803
+ let s:tlist_removed_flist = text_before . text_after
804
+ endif
805
+ endfunction
806
+
807
+ " Tlist_FileType_Init
808
+ " Initialize the ctags arguments and tag variable for the specified
809
+ " file type
810
+ function! s:Tlist_FileType_Init(ftype)
811
+ call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')')
812
+ " If the user didn't specify any settings, then use the default
813
+ " ctags args. Otherwise, use the settings specified by the user
814
+ let var = 'g:tlist_' . a:ftype . '_settings'
815
+ if exists(var)
816
+ " User specified ctags arguments
817
+ let settings = {var} . ';'
818
+ else
819
+ " Default ctags arguments
820
+ let var = 's:tlist_def_' . a:ftype . '_settings'
821
+ if !exists(var)
822
+ " No default settings for this file type. This filetype is
823
+ " not supported
824
+ return 0
825
+ endif
826
+ let settings = s:tlist_def_{a:ftype}_settings . ';'
827
+ endif
828
+
829
+ let msg = 'Taglist: Invalid ctags option setting - ' . settings
830
+
831
+ " Format of the option that specifies the filetype and ctags arugments:
832
+ "
833
+ " <language_name>;flag1:name1;flag2:name2;flag3:name3
834
+ "
835
+
836
+ " Extract the file type to pass to ctags. This may be different from the
837
+ " file type detected by Vim
838
+ let pos = stridx(settings, ';')
839
+ if pos == -1
840
+ call s:Tlist_Warning_Msg(msg)
841
+ return 0
842
+ endif
843
+ let ctags_ftype = strpart(settings, 0, pos)
844
+ if ctags_ftype == ''
845
+ call s:Tlist_Warning_Msg(msg)
846
+ return 0
847
+ endif
848
+ " Make sure a valid filetype is supplied. If the user didn't specify a
849
+ " valid filetype, then the ctags option settings may be treated as the
850
+ " filetype
851
+ if ctags_ftype =~ ':'
852
+ call s:Tlist_Warning_Msg(msg)
853
+ return 0
854
+ endif
855
+
856
+ " Remove the file type from settings
857
+ let settings = strpart(settings, pos + 1)
858
+ if settings == ''
859
+ call s:Tlist_Warning_Msg(msg)
860
+ return 0
861
+ endif
862
+
863
+ " Process all the specified ctags flags. The format is
864
+ " flag1:name1;flag2:name2;flag3:name3
865
+ let ctags_flags = ''
866
+ let cnt = 0
867
+ while settings != ''
868
+ " Extract the flag
869
+ let pos = stridx(settings, ':')
870
+ if pos == -1
871
+ call s:Tlist_Warning_Msg(msg)
872
+ return 0
873
+ endif
874
+ let flag = strpart(settings, 0, pos)
875
+ if flag == ''
876
+ call s:Tlist_Warning_Msg(msg)
877
+ return 0
878
+ endif
879
+ " Remove the flag from settings
880
+ let settings = strpart(settings, pos + 1)
881
+
882
+ " Extract the tag type name
883
+ let pos = stridx(settings, ';')
884
+ if pos == -1
885
+ call s:Tlist_Warning_Msg(msg)
886
+ return 0
887
+ endif
888
+ let name = strpart(settings, 0, pos)
889
+ if name == ''
890
+ call s:Tlist_Warning_Msg(msg)
891
+ return 0
892
+ endif
893
+ let settings = strpart(settings, pos + 1)
894
+
895
+ let cnt = cnt + 1
896
+
897
+ let s:tlist_{a:ftype}_{cnt}_name = flag
898
+ let s:tlist_{a:ftype}_{cnt}_fullname = name
899
+ let ctags_flags = ctags_flags . flag
900
+ endwhile
901
+
902
+ let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype .
903
+ \ ' --' . ctags_ftype . '-types=' . ctags_flags
904
+ let s:tlist_{a:ftype}_count = cnt
905
+ let s:tlist_{a:ftype}_ctags_flags = ctags_flags
906
+
907
+ " Save the filetype name
908
+ let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype
909
+ let s:tlist_ftype_count = s:tlist_ftype_count + 1
910
+
911
+ return 1
912
+ endfunction
913
+
914
+ " Tlist_Get_Filetype
915
+ " Determine the filetype for the specified file
916
+ function! s:Tlist_Get_Filetype(fname)
917
+ " Ignore the filetype autocommands
918
+ let old_eventignore = &eventignore
919
+ set eventignore=FileType
920
+
921
+ " Save the 'filetype', as this will be changed temporarily
922
+ let old_filetype = &filetype
923
+
924
+ " Run the filetypedetect group of autocommands to determine
925
+ " the filetype
926
+ exe 'doautocmd filetypedetect BufRead ' . a:fname
927
+
928
+ " Save the detected filetype
929
+ let ftype = &filetype
930
+
931
+ " Restore the previous state
932
+ let &filetype = old_filetype
933
+ let &eventignore = old_eventignore
934
+
935
+ return ftype
936
+ endfunction
937
+
938
+ " Tlist_Get_Buffer_Filetype
939
+ " Get the filetype for the specified buffer
940
+ function! s:Tlist_Get_Buffer_Filetype(bnum)
941
+ if bufloaded(a:bnum)
942
+ " For loaded buffers, the 'filetype' is already determined
943
+ return getbufvar(a:bnum, '&filetype')
944
+ endif
945
+
946
+ " For unloaded buffers, if the 'filetype' option is set, return it
947
+ let ftype = getbufvar(a:bnum, '&filetype')
948
+ if ftype != ''
949
+ return ftype
950
+ endif
951
+
952
+ " Skip non-existent buffers
953
+ if !bufexists(a:bnum)
954
+ return ''
955
+ endif
956
+
957
+ " For buffers whose filetype is not yet determined, try to determine
958
+ " the filetype
959
+ let bname = bufname(a:bnum)
960
+
961
+ return s:Tlist_Get_Filetype(bname)
962
+ endfunction
963
+
964
+ " Tlist_Discard_TagInfo
965
+ " Discard the stored tag information for a file
966
+ function! s:Tlist_Discard_TagInfo(fidx)
967
+ call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' .
968
+ \ s:tlist_{a:fidx}_filename . ')')
969
+ let ftype = s:tlist_{a:fidx}_filetype
970
+
971
+ " Discard information about the tags defined in the file
972
+ let i = 1
973
+ while i <= s:tlist_{a:fidx}_tag_count
974
+ let fidx_i = 's:tlist_' . a:fidx . '_' . i
975
+ unlet! {fidx_i}_tag
976
+ unlet! {fidx_i}_tag_name
977
+ unlet! {fidx_i}_tag_type
978
+ unlet! {fidx_i}_ttype_idx
979
+ unlet! {fidx_i}_tag_proto
980
+ unlet! {fidx_i}_tag_searchpat
981
+ unlet! {fidx_i}_tag_linenum
982
+ let i = i + 1
983
+ endwhile
984
+
985
+ let s:tlist_{a:fidx}_tag_count = 0
986
+
987
+ " Discard information about tag type groups
988
+ let i = 1
989
+ while i <= s:tlist_{ftype}_count
990
+ let ttype = s:tlist_{ftype}_{i}_name
991
+ if s:tlist_{a:fidx}_{ttype} != ''
992
+ let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype
993
+ let {fidx_ttype} = ''
994
+ let {fidx_ttype}_offset = 0
995
+ let cnt = {fidx_ttype}_count
996
+ let {fidx_ttype}_count = 0
997
+ let j = 1
998
+ while j <= cnt
999
+ unlet! {fidx_ttype}_{j}
1000
+ let j = j + 1
1001
+ endwhile
1002
+ endif
1003
+ let i = i + 1
1004
+ endwhile
1005
+
1006
+ " Discard the stored menu command also
1007
+ let s:tlist_{a:fidx}_menu_cmd = ''
1008
+ endfunction
1009
+
1010
+ " Tlist_Window_Update_Line_Offsets
1011
+ " Update the line offsets for tags for files starting from start_idx
1012
+ " and displayed in the taglist window by the specified offset
1013
+ function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset)
1014
+ let i = a:start_idx
1015
+
1016
+ while i < s:tlist_file_count
1017
+ if s:tlist_{i}_visible
1018
+ " Update the start/end line number only if the file is visible
1019
+ if a:increment
1020
+ let s:tlist_{i}_start = s:tlist_{i}_start + a:offset
1021
+ let s:tlist_{i}_end = s:tlist_{i}_end + a:offset
1022
+ else
1023
+ let s:tlist_{i}_start = s:tlist_{i}_start - a:offset
1024
+ let s:tlist_{i}_end = s:tlist_{i}_end - a:offset
1025
+ endif
1026
+ endif
1027
+ let i = i + 1
1028
+ endwhile
1029
+ endfunction
1030
+
1031
+ " Tlist_Discard_FileInfo
1032
+ " Discard the stored information for a file
1033
+ function! s:Tlist_Discard_FileInfo(fidx)
1034
+ call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' .
1035
+ \ s:tlist_{a:fidx}_filename . ')')
1036
+ call s:Tlist_Discard_TagInfo(a:fidx)
1037
+
1038
+ let ftype = s:tlist_{a:fidx}_filetype
1039
+
1040
+ let i = 1
1041
+ while i <= s:tlist_{ftype}_count
1042
+ let ttype = s:tlist_{ftype}_{i}_name
1043
+ unlet! s:tlist_{a:fidx}_{ttype}
1044
+ unlet! s:tlist_{a:fidx}_{ttype}_offset
1045
+ unlet! s:tlist_{a:fidx}_{ttype}_count
1046
+ let i = i + 1
1047
+ endwhile
1048
+
1049
+ unlet! s:tlist_{a:fidx}_filename
1050
+ unlet! s:tlist_{a:fidx}_sort_type
1051
+ unlet! s:tlist_{a:fidx}_filetype
1052
+ unlet! s:tlist_{a:fidx}_mtime
1053
+ unlet! s:tlist_{a:fidx}_start
1054
+ unlet! s:tlist_{a:fidx}_end
1055
+ unlet! s:tlist_{a:fidx}_valid
1056
+ unlet! s:tlist_{a:fidx}_visible
1057
+ unlet! s:tlist_{a:fidx}_tag_count
1058
+ unlet! s:tlist_{a:fidx}_menu_cmd
1059
+ endfunction
1060
+
1061
+ " Tlist_Window_Remove_File_From_Display
1062
+ " Remove the specified file from display
1063
+ function! s:Tlist_Window_Remove_File_From_Display(fidx)
1064
+ call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' .
1065
+ \ s:tlist_{a:fidx}_filename . ')')
1066
+ " If the file is not visible then no need to remove it
1067
+ if !s:tlist_{a:fidx}_visible
1068
+ return
1069
+ endif
1070
+
1071
+ " Remove the tags displayed for the specified file from the window
1072
+ let start = s:tlist_{a:fidx}_start
1073
+ " Include the empty line after the last line also
1074
+ if g:Tlist_Compact_Format
1075
+ let end = s:tlist_{a:fidx}_end
1076
+ else
1077
+ let end = s:tlist_{a:fidx}_end + 1
1078
+ endif
1079
+
1080
+ setlocal modifiable
1081
+ exe 'silent! ' . start . ',' . end . 'delete _'
1082
+ setlocal nomodifiable
1083
+
1084
+ " Correct the start and end line offsets for all the files following
1085
+ " this file, as the tags for this file are removed
1086
+ call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1)
1087
+ endfunction
1088
+
1089
+ " Tlist_Remove_File
1090
+ " Remove the file under the cursor or the specified file index
1091
+ " user_request - User requested to remove the file from taglist
1092
+ function! s:Tlist_Remove_File(file_idx, user_request)
1093
+ let fidx = a:file_idx
1094
+
1095
+ if fidx == -1
1096
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
1097
+ if fidx == -1
1098
+ return
1099
+ endif
1100
+ endif
1101
+ call s:Tlist_Log_Msg('Tlist_Remove_File (' .
1102
+ \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')')
1103
+
1104
+ let save_winnr = winnr()
1105
+ let winnum = bufwinnr(g:TagList_title)
1106
+ if winnum != -1
1107
+ " Taglist window is open, remove the file from display
1108
+
1109
+ if save_winnr != winnum
1110
+ let old_eventignore = &eventignore
1111
+ set eventignore=all
1112
+ exe winnum . 'wincmd w'
1113
+ endif
1114
+
1115
+ call s:Tlist_Window_Remove_File_From_Display(fidx)
1116
+
1117
+ if save_winnr != winnum
1118
+ exe save_winnr . 'wincmd w'
1119
+ let &eventignore = old_eventignore
1120
+ endif
1121
+ endif
1122
+
1123
+ let fname = s:tlist_{fidx}_filename
1124
+
1125
+ if a:user_request
1126
+ " As the user requested to remove the file from taglist,
1127
+ " add it to the removed list
1128
+ call s:Tlist_Update_Remove_List(fname, 1)
1129
+ endif
1130
+
1131
+ " Remove the file name from the taglist list of filenames
1132
+ let idx = stridx(s:tlist_file_names, fname . "\n")
1133
+ let text_before = strpart(s:tlist_file_names, 0, idx)
1134
+ let rem_text = strpart(s:tlist_file_names, idx)
1135
+ let next_idx = stridx(rem_text, "\n")
1136
+ let text_after = strpart(rem_text, next_idx + 1)
1137
+ let s:tlist_file_names = text_before . text_after
1138
+
1139
+ call s:Tlist_Discard_FileInfo(fidx)
1140
+
1141
+ " Shift all the file variables by one index
1142
+ let i = fidx + 1
1143
+
1144
+ while i < s:tlist_file_count
1145
+ let j = i - 1
1146
+
1147
+ let s:tlist_{j}_filename = s:tlist_{i}_filename
1148
+ let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type
1149
+ let s:tlist_{j}_filetype = s:tlist_{i}_filetype
1150
+ let s:tlist_{j}_mtime = s:tlist_{i}_mtime
1151
+ let s:tlist_{j}_start = s:tlist_{i}_start
1152
+ let s:tlist_{j}_end = s:tlist_{i}_end
1153
+ let s:tlist_{j}_valid = s:tlist_{i}_valid
1154
+ let s:tlist_{j}_visible = s:tlist_{i}_visible
1155
+ let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count
1156
+ let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd
1157
+
1158
+ let k = 1
1159
+ while k <= s:tlist_{j}_tag_count
1160
+ let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag
1161
+ let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name
1162
+ let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k)
1163
+ let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx
1164
+ let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k)
1165
+ let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k)
1166
+ let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k)
1167
+ let k = k + 1
1168
+ endwhile
1169
+
1170
+ let ftype = s:tlist_{i}_filetype
1171
+
1172
+ let k = 1
1173
+ while k <= s:tlist_{ftype}_count
1174
+ let ttype = s:tlist_{ftype}_{k}_name
1175
+ let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype}
1176
+ let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset
1177
+ let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count
1178
+ if s:tlist_{j}_{ttype} != ''
1179
+ let l = 1
1180
+ while l <= s:tlist_{j}_{ttype}_count
1181
+ let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l}
1182
+ let l = l + 1
1183
+ endwhile
1184
+ endif
1185
+ let k = k + 1
1186
+ endwhile
1187
+
1188
+ " As the file and tag information is copied to the new index,
1189
+ " discard the previous information
1190
+ call s:Tlist_Discard_FileInfo(i)
1191
+
1192
+ let i = i + 1
1193
+ endwhile
1194
+
1195
+ " Reduce the number of files displayed
1196
+ let s:tlist_file_count = s:tlist_file_count - 1
1197
+
1198
+ if g:Tlist_Show_One_File
1199
+ " If the tags for only one file is displayed and if we just
1200
+ " now removed that file, then invalidate the current file idx
1201
+ if s:tlist_cur_file_idx == fidx
1202
+ let s:tlist_cur_file_idx = -1
1203
+ endif
1204
+ endif
1205
+ endfunction
1206
+
1207
+ " Tlist_Window_Goto_Window
1208
+ " Goto the taglist window
1209
+ function! s:Tlist_Window_Goto_Window()
1210
+ let winnum = bufwinnr(g:TagList_title)
1211
+ if winnum != -1
1212
+ if winnr() != winnum
1213
+ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w')
1214
+ endif
1215
+ endif
1216
+ endfunction
1217
+
1218
+ " Tlist_Window_Create
1219
+ " Create a new taglist window. If it is already open, jump to it
1220
+ function! s:Tlist_Window_Create()
1221
+ call s:Tlist_Log_Msg('Tlist_Window_Create()')
1222
+ " If the window is open, jump to it
1223
+ let winnum = bufwinnr(g:TagList_title)
1224
+ if winnum != -1
1225
+ " Jump to the existing window
1226
+ if winnr() != winnum
1227
+ exe winnum . 'wincmd w'
1228
+ endif
1229
+ return
1230
+ endif
1231
+
1232
+ " If used with winmanager don't open windows. Winmanager will handle
1233
+ " the window/buffer management
1234
+ if s:tlist_app_name == "winmanager"
1235
+ return
1236
+ endif
1237
+
1238
+ " Create a new window. If user prefers a horizontal window, then open
1239
+ " a horizontally split window. Otherwise open a vertically split
1240
+ " window
1241
+ if g:Tlist_Use_Horiz_Window
1242
+ " Open a horizontally split window
1243
+ let win_dir = 'botright'
1244
+ " Horizontal window height
1245
+ let win_size = g:Tlist_WinHeight
1246
+ else
1247
+ " Open a vertically split window. Increase the window size, if
1248
+ " needed, to accomodate the new window
1249
+ if g:Tlist_Inc_Winwidth &&
1250
+ \ &columns < (80 + g:Tlist_WinWidth)
1251
+ " Save the original window position
1252
+ let s:tlist_pre_winx = getwinposx()
1253
+ let s:tlist_pre_winy = getwinposy()
1254
+
1255
+ " one extra column is needed to include the vertical split
1256
+ let &columns= &columns + g:Tlist_WinWidth + 1
1257
+
1258
+ let s:tlist_winsize_chgd = 1
1259
+ else
1260
+ let s:tlist_winsize_chgd = 0
1261
+ endif
1262
+
1263
+ if g:Tlist_Use_Right_Window
1264
+ " Open the window at the rightmost place
1265
+ let win_dir = 'botright vertical'
1266
+ else
1267
+ " Open the window at the leftmost place
1268
+ let win_dir = 'topleft vertical'
1269
+ endif
1270
+ let win_size = g:Tlist_WinWidth
1271
+ endif
1272
+
1273
+ " If the tag listing temporary buffer already exists, then reuse it.
1274
+ " Otherwise create a new buffer
1275
+ let bufnum = bufnr(g:TagList_title)
1276
+ if bufnum == -1
1277
+ " Create a new buffer
1278
+ let wcmd = g:TagList_title
1279
+ else
1280
+ " Edit the existing buffer
1281
+ let wcmd = '+buffer' . bufnum
1282
+ endif
1283
+
1284
+ " Create the taglist window
1285
+ exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd
1286
+
1287
+ " Save the new window position
1288
+ let s:tlist_winx = getwinposx()
1289
+ let s:tlist_winy = getwinposy()
1290
+
1291
+ " Initialize the taglist window
1292
+ call s:Tlist_Window_Init()
1293
+ endfunction
1294
+
1295
+ " Tlist_Window_Zoom
1296
+ " Zoom (maximize/minimize) the taglist window
1297
+ function! s:Tlist_Window_Zoom()
1298
+ if s:tlist_win_maximized
1299
+ " Restore the window back to the previous size
1300
+ if g:Tlist_Use_Horiz_Window
1301
+ exe 'resize ' . g:Tlist_WinHeight
1302
+ else
1303
+ exe 'vert resize ' . g:Tlist_WinWidth
1304
+ endif
1305
+ let s:tlist_win_maximized = 0
1306
+ else
1307
+ " Set the window size to the maximum possible without closing other
1308
+ " windows
1309
+ if g:Tlist_Use_Horiz_Window
1310
+ resize
1311
+ else
1312
+ vert resize
1313
+ endif
1314
+ let s:tlist_win_maximized = 1
1315
+ endif
1316
+ endfunction
1317
+
1318
+ " Tlist_Window_Check_Width
1319
+ " Check the width of the taglist window. For horizontally split windows, the
1320
+ " 'winfixheight' option is used to fix the height of the window. For
1321
+ " vertically split windows, Vim doesn't support the 'winfixwidth' option. So
1322
+ " need to handle window width changes from this function.
1323
+ function! s:Tlist_Window_Check_Width()
1324
+ let tlist_winnr = bufwinnr(g:TagList_title)
1325
+ if tlist_winnr == -1
1326
+ return
1327
+ endif
1328
+
1329
+ let width = winwidth(tlist_winnr)
1330
+ if width != g:Tlist_WinWidth
1331
+ call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " .
1332
+ \ "width from " . width . " to " . g:Tlist_WinWidth)
1333
+ let save_winnr = winnr()
1334
+ if save_winnr != tlist_winnr
1335
+ call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w')
1336
+ endif
1337
+ exe 'vert resize ' . g:Tlist_WinWidth
1338
+ if save_winnr != tlist_winnr
1339
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
1340
+ endif
1341
+ endif
1342
+ endfunction
1343
+
1344
+ " Tlist_Window_Init
1345
+ " Set the default options for the taglist window
1346
+ function! s:Tlist_Window_Init()
1347
+ call s:Tlist_Log_Msg('Tlist_Window_Init()')
1348
+
1349
+ " Set the taglist buffer filetype to taglist
1350
+ setlocal filetype=taglist
1351
+
1352
+ " Define taglist window element highlighting
1353
+ syntax match TagListComment '^" .*'
1354
+ syntax match TagListFileName '^[^" ].*$'
1355
+ syntax match TagListTitle '^ \S.*$'
1356
+ syntax match TagListTagScope '\s\[.\{-\}\]$'
1357
+
1358
+ " Define the highlighting only if colors are supported
1359
+ if has('gui_running') || &t_Co > 2
1360
+ " Colors to highlight various taglist window elements
1361
+ " If user defined highlighting group exists, then use them.
1362
+ " Otherwise, use default highlight groups.
1363
+ if hlexists('MyTagListTagName')
1364
+ highlight link TagListTagName MyTagListTagName
1365
+ else
1366
+ highlight default link TagListTagName Search
1367
+ endif
1368
+ " Colors to highlight comments and titles
1369
+ if hlexists('MyTagListComment')
1370
+ highlight link TagListComment MyTagListComment
1371
+ else
1372
+ highlight clear TagListComment
1373
+ highlight default link TagListComment Comment
1374
+ endif
1375
+ if hlexists('MyTagListTitle')
1376
+ highlight link TagListTitle MyTagListTitle
1377
+ else
1378
+ highlight clear TagListTitle
1379
+ highlight default link TagListTitle Title
1380
+ endif
1381
+ if hlexists('MyTagListFileName')
1382
+ highlight link TagListFileName MyTagListFileName
1383
+ else
1384
+ highlight clear TagListFileName
1385
+ highlight default TagListFileName guibg=Grey ctermbg=darkgray
1386
+ \ guifg=white ctermfg=white
1387
+ endif
1388
+ if hlexists('MyTagListTagScope')
1389
+ highlight link TagListTagScope MyTagListTagScope
1390
+ else
1391
+ highlight clear TagListTagScope
1392
+ highlight default link TagListTagScope Identifier
1393
+ endif
1394
+ else
1395
+ highlight default TagListTagName term=reverse cterm=reverse
1396
+ endif
1397
+
1398
+ " Folding related settings
1399
+ setlocal foldenable
1400
+ setlocal foldminlines=0
1401
+ setlocal foldmethod=manual
1402
+ setlocal foldlevel=9999
1403
+ if g:Tlist_Enable_Fold_Column
1404
+ setlocal foldcolumn=3
1405
+ else
1406
+ setlocal foldcolumn=0
1407
+ endif
1408
+ setlocal foldtext=v:folddashes.getline(v:foldstart)
1409
+
1410
+ if s:tlist_app_name != "winmanager"
1411
+ " Mark buffer as scratch
1412
+ silent! setlocal buftype=nofile
1413
+ if s:tlist_app_name == "none"
1414
+ silent! setlocal bufhidden=delete
1415
+ endif
1416
+ silent! setlocal noswapfile
1417
+ " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted
1418
+ " buffers. So if the taglist buffer is unlisted, multiple taglist
1419
+ " windows will be opened. This bug is fixed in Vim 6.1 and above
1420
+ if v:version >= 601
1421
+ silent! setlocal nobuflisted
1422
+ endif
1423
+ endif
1424
+
1425
+ silent! setlocal nowrap
1426
+
1427
+ " If the 'number' option is set in the source window, it will affect the
1428
+ " taglist window. So forcefully disable 'number' option for the taglist
1429
+ " window
1430
+ silent! setlocal nonumber
1431
+
1432
+ " Use fixed height when horizontally split window is used
1433
+ if g:Tlist_Use_Horiz_Window
1434
+ if v:version >= 602
1435
+ set winfixheight
1436
+ endif
1437
+ endif
1438
+ if !g:Tlist_Use_Horiz_Window && v:version >= 700
1439
+ set winfixwidth
1440
+ endif
1441
+
1442
+ " Setup the cpoptions properly for the maps to work
1443
+ let old_cpoptions = &cpoptions
1444
+ set cpoptions&vim
1445
+
1446
+ " Create buffer local mappings for jumping to the tags and sorting the list
1447
+ nnoremap <buffer> <silent> <CR> :call <SID>Tlist_Window_Jump_To_Tag(0)<CR>
1448
+ nnoremap <buffer> <silent> o :call <SID>Tlist_Window_Jump_To_Tag(1)<CR>
1449
+ nnoremap <buffer> <silent> p :call <SID>Tlist_Window_Jump_To_Tag(2)<CR>
1450
+ nnoremap <buffer> <silent> <2-LeftMouse> :call <SID>Tlist_Window_Jump_To_Tag(0)<CR>
1451
+ nnoremap <buffer> <silent> s :call <SID>Tlist_Change_Sort(1, 1, '')<CR>
1452
+ nnoremap <buffer> <silent> + :silent! foldopen<CR>
1453
+ nnoremap <buffer> <silent> - :silent! foldclose<CR>
1454
+ nnoremap <buffer> <silent> * :silent! %foldopen!<CR>
1455
+ nnoremap <buffer> <silent> = :silent! %foldclose<CR>
1456
+ nnoremap <buffer> <silent> <kPlus> :silent! foldopen<CR>
1457
+ nnoremap <buffer> <silent> <kMinus> :silent! foldclose<CR>
1458
+ nnoremap <buffer> <silent> <kMultiply> :silent! %foldopen!<CR>
1459
+ nnoremap <buffer> <silent> <Space> :call <SID>Tlist_Window_Show_Info()<CR>
1460
+ nnoremap <buffer> <silent> u :call <SID>Tlist_Window_Update_File()<CR>
1461
+ nnoremap <buffer> <silent> d :call <SID>Tlist_Remove_File(-1, 1)<CR>
1462
+ nnoremap <buffer> <silent> x :call <SID>Tlist_Window_Zoom()<CR>
1463
+ nnoremap <buffer> <silent> [[ :call <SID>Tlist_Window_Move_To_File(-1)<CR>
1464
+ nnoremap <buffer> <silent> <BS> :call <SID>Tlist_Window_Move_To_File(-1)<CR>
1465
+ nnoremap <buffer> <silent> ]] :call <SID>Tlist_Window_Move_To_File(1)<CR>
1466
+ nnoremap <buffer> <silent> <Tab> :call <SID>Tlist_Window_Move_To_File(1)<CR>
1467
+ nnoremap <buffer> <silent> <F1> :call <SID>Tlist_Window_Toggle_Help_Text()<CR>
1468
+ nnoremap <buffer> <silent> q :close<CR>
1469
+
1470
+ " Insert mode mappings
1471
+ inoremap <buffer> <silent> <CR> <C-o>:call <SID>Tlist_Window_Jump_To_Tag(0)<CR>
1472
+ " Windows needs return
1473
+ inoremap <buffer> <silent> <Return> <C-o>:call <SID>Tlist_Window_Jump_To_Tag(0)<CR>
1474
+ inoremap <buffer> <silent> o <C-o>:call <SID>Tlist_Window_Jump_To_Tag(1)<CR>
1475
+ inoremap <buffer> <silent> p <C-o>:call <SID>Tlist_Window_Jump_To_Tag(2)<CR>
1476
+ inoremap <buffer> <silent> <2-LeftMouse> <C-o>:call
1477
+ \ <SID>Tlist_Window_Jump_To_Tag(0)<CR>
1478
+ inoremap <buffer> <silent> s
1479
+ \ <C-o>:call <SID>Tlist_Change_Sort(1, 1, '')<CR>
1480
+ inoremap <buffer> <silent> + <C-o>:silent! foldopen<CR>
1481
+ inoremap <buffer> <silent> - <C-o>:silent! foldclose<CR>
1482
+ inoremap <buffer> <silent> * <C-o>:silent! %foldopen!<CR>
1483
+ inoremap <buffer> <silent> = <C-o>:silent! %foldclose<CR>
1484
+ inoremap <buffer> <silent> <kPlus> <C-o>:silent! foldopen<CR>
1485
+ inoremap <buffer> <silent> <kMinus> <C-o>:silent! foldclose<CR>
1486
+ inoremap <buffer> <silent> <kMultiply> <C-o>:silent! %foldopen!<CR>
1487
+ inoremap <buffer> <silent> <Space> <C-o>:call
1488
+ \ <SID>Tlist_Window_Show_Info()<CR>
1489
+ inoremap <buffer> <silent> u
1490
+ \ <C-o>:call <SID>Tlist_Window_Update_File()<CR>
1491
+ inoremap <buffer> <silent> d <C-o>:call <SID>Tlist_Remove_File(-1, 1)<CR>
1492
+ inoremap <buffer> <silent> x <C-o>:call <SID>Tlist_Window_Zoom()<CR>
1493
+ inoremap <buffer> <silent> [[ <C-o>:call <SID>Tlist_Window_Move_To_File(-1)<CR>
1494
+ inoremap <buffer> <silent> <BS> <C-o>:call <SID>Tlist_Window_Move_To_File(-1)<CR>
1495
+ inoremap <buffer> <silent> ]] <C-o>:call <SID>Tlist_Window_Move_To_File(1)<CR>
1496
+ inoremap <buffer> <silent> <Tab> <C-o>:call <SID>Tlist_Window_Move_To_File(1)<CR>
1497
+ inoremap <buffer> <silent> <F1> <C-o>:call <SID>Tlist_Window_Toggle_Help_Text()<CR>
1498
+ inoremap <buffer> <silent> q <C-o>:close<CR>
1499
+
1500
+ " Map single left mouse click if the user wants this functionality
1501
+ if g:Tlist_Use_SingleClick == 1
1502
+ " Contributed by Bindu Wavell
1503
+ " attempt to perform single click mapping, it would be much
1504
+ " nicer if we could nnoremap <buffer> ... however vim does
1505
+ " not fire the <buffer> <leftmouse> when you use the mouse
1506
+ " to enter a buffer.
1507
+ let clickmap = ':if bufname("%") =~ "__Tag_List__" <bar> ' .
1508
+ \ 'call <SID>Tlist_Window_Jump_To_Tag(0) <bar> endif <CR>'
1509
+ if maparg('<leftmouse>', 'n') == ''
1510
+ " no mapping for leftmouse
1511
+ exe ':nnoremap <silent> <leftmouse> <leftmouse>' . clickmap
1512
+ else
1513
+ " we have a mapping
1514
+ let mapcmd = ':nnoremap <silent> <leftmouse> <leftmouse>'
1515
+ let mapcmd = mapcmd . substitute(substitute(
1516
+ \ maparg('<leftmouse>', 'n'), '|', '<bar>', 'g'),
1517
+ \ '\c^<leftmouse>', '', '')
1518
+ let mapcmd = mapcmd . clickmap
1519
+ exe mapcmd
1520
+ endif
1521
+ endif
1522
+
1523
+ " Define the taglist autocommands
1524
+ augroup TagListAutoCmds
1525
+ autocmd!
1526
+ " Display the tag prototype for the tag under the cursor.
1527
+ autocmd CursorHold __Tag_List__ call s:Tlist_Window_Show_Info()
1528
+ " Highlight the current tag periodically
1529
+ autocmd CursorHold * silent call s:Tlist_Window_Highlight_Tag(
1530
+ \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0)
1531
+
1532
+ " Adjust the Vim window width when taglist window is closed
1533
+ autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup()
1534
+ " Close the fold for this buffer when it's not visible in any window
1535
+ if g:Tlist_File_Fold_Auto_Close
1536
+ autocmd BufWinLeave * silent
1537
+ \ call s:Tlist_Window_Close_File_Fold(expand('<afile>:p'))
1538
+ endif
1539
+ " Exit Vim itself if only the taglist window is present (optional)
1540
+ if g:Tlist_Exit_OnlyWindow
1541
+ " Before quitting Vim, delete the taglist buffer so that
1542
+ " the '0 mark is correctly set to the previous buffer.
1543
+ autocmd BufEnter __Tag_List__ nested if winbufnr(2) == -1 |
1544
+ \ bdelete | quit | endif
1545
+ endif
1546
+ if s:tlist_app_name != "winmanager" &&
1547
+ \ !g:Tlist_Process_File_Always &&
1548
+ \ (!has('gui_running') || !g:Tlist_Show_Menu)
1549
+ " Auto refresh the taglist window
1550
+ autocmd BufEnter * call s:Tlist_Refresh()
1551
+ endif
1552
+
1553
+ if !g:Tlist_Use_Horiz_Window
1554
+ if v:version < 700
1555
+ autocmd WinEnter * call s:Tlist_Window_Check_Width()
1556
+ endif
1557
+ endif
1558
+ augroup end
1559
+
1560
+ " Restore the previous cpoptions settings
1561
+ let &cpoptions = old_cpoptions
1562
+ endfunction
1563
+
1564
+ " Tlist_Window_Refresh
1565
+ " Display the tags for all the files in the taglist window
1566
+ function! s:Tlist_Window_Refresh()
1567
+ call s:Tlist_Log_Msg('Tlist_Window_Refresh()')
1568
+ " Set report option to a huge value to prevent informational messages
1569
+ " while deleting the lines
1570
+ let old_report = &report
1571
+ set report=99999
1572
+
1573
+ " Mark the buffer as modifiable
1574
+ setlocal modifiable
1575
+
1576
+ " Delete the contents of the buffer to the black-hole register
1577
+ silent! %delete _
1578
+
1579
+ " As we have cleared the taglist window, mark all the files
1580
+ " as not visible
1581
+ let i = 0
1582
+ while i < s:tlist_file_count
1583
+ let s:tlist_{i}_visible = 0
1584
+ let i = i + 1
1585
+ endwhile
1586
+
1587
+ if g:Tlist_Compact_Format == 0
1588
+ " Display help in non-compact mode
1589
+ call s:Tlist_Window_Display_Help()
1590
+ endif
1591
+
1592
+ " Mark the buffer as not modifiable
1593
+ setlocal nomodifiable
1594
+
1595
+ " Restore the report option
1596
+ let &report = old_report
1597
+
1598
+ " If the tags for only one file should be displayed in the taglist
1599
+ " window, then no need to add the tags here. The bufenter autocommand
1600
+ " will add the tags for that file.
1601
+ if g:Tlist_Show_One_File
1602
+ return
1603
+ endif
1604
+
1605
+ " List all the tags for the previously processed files
1606
+ " Do this only if taglist is configured to display tags for more than
1607
+ " one file. Otherwise, when Tlist_Show_One_File is configured,
1608
+ " tags for the wrong file will be displayed.
1609
+ let i = 0
1610
+ while i < s:tlist_file_count
1611
+ call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename,
1612
+ \ s:tlist_{i}_filetype)
1613
+ let i = i + 1
1614
+ endwhile
1615
+
1616
+ if g:Tlist_Auto_Update
1617
+ " Add and list the tags for all buffers in the Vim buffer list
1618
+ let i = 1
1619
+ let last_bufnum = bufnr('$')
1620
+ while i <= last_bufnum
1621
+ if buflisted(i)
1622
+ let fname = fnamemodify(bufname(i), ':p')
1623
+ let ftype = s:Tlist_Get_Buffer_Filetype(i)
1624
+ " If the file doesn't support tag listing, skip it
1625
+ if !s:Tlist_Skip_File(fname, ftype)
1626
+ call s:Tlist_Window_Refresh_File(fname, ftype)
1627
+ endif
1628
+ endif
1629
+ let i = i + 1
1630
+ endwhile
1631
+ endif
1632
+
1633
+ " If Tlist_File_Fold_Auto_Close option is set, then close all the folds
1634
+ if g:Tlist_File_Fold_Auto_Close
1635
+ " Close all the folds
1636
+ silent! %foldclose
1637
+ endif
1638
+
1639
+ " Move the cursor to the top of the taglist window
1640
+ normal! gg
1641
+ endfunction
1642
+
1643
+ " Tlist_Post_Close_Cleanup()
1644
+ " Close the taglist window and adjust the Vim window width
1645
+ function! s:Tlist_Post_Close_Cleanup()
1646
+ call s:Tlist_Log_Msg('Tlist_Post_Close_Cleanup()')
1647
+ " Mark all the files as not visible
1648
+ let i = 0
1649
+ while i < s:tlist_file_count
1650
+ let s:tlist_{i}_visible = 0
1651
+ let i = i + 1
1652
+ endwhile
1653
+
1654
+ " Remove the taglist autocommands
1655
+ silent! autocmd! TagListAutoCmds
1656
+
1657
+ " Clear all the highlights
1658
+ match none
1659
+
1660
+ silent! syntax clear TagListTitle
1661
+ silent! syntax clear TagListComment
1662
+ silent! syntax clear TagListTagScope
1663
+
1664
+ " Remove the left mouse click mapping if it was setup initially
1665
+ if g:Tlist_Use_SingleClick
1666
+ if hasmapto('<LeftMouse>')
1667
+ nunmap <LeftMouse>
1668
+ endif
1669
+ endif
1670
+
1671
+ if s:tlist_app_name != "winmanager"
1672
+ if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 ||
1673
+ \ s:tlist_winsize_chgd == 0 ||
1674
+ \ &columns < (80 + g:Tlist_WinWidth)
1675
+ " No need to adjust window width if using horizontally split taglist
1676
+ " window or if columns is less than 101 or if the user chose not to
1677
+ " adjust the window width
1678
+ else
1679
+ " If the user didn't manually move the window, then restore the window
1680
+ " position to the pre-taglist position
1681
+ if s:tlist_pre_winx != -1 && s:tlist_pre_winy != -1 &&
1682
+ \ getwinposx() == s:tlist_winx &&
1683
+ \ getwinposy() == s:tlist_winy
1684
+ exe 'winpos ' . s:tlist_pre_winx . ' ' . s:tlist_pre_winy
1685
+ endif
1686
+
1687
+ " Adjust the Vim window width
1688
+ let &columns= &columns - (g:Tlist_WinWidth + 1)
1689
+ endif
1690
+ endif
1691
+
1692
+ " Reset taglist state variables
1693
+ if s:tlist_app_name == "winmanager"
1694
+ let s:tlist_app_name = "none"
1695
+ endif
1696
+ let s:tlist_window_initialized = 0
1697
+ endfunction
1698
+
1699
+ " Tlist_Window_Refresh_File()
1700
+ " List the tags defined in the specified file in a Vim window
1701
+ function! s:Tlist_Window_Refresh_File(filename, ftype)
1702
+ call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')')
1703
+ " First check whether the file already exists
1704
+ let fidx = s:Tlist_Get_File_Index(a:filename)
1705
+ if fidx != -1
1706
+ let file_listed = 1
1707
+ else
1708
+ let file_listed = 0
1709
+ endif
1710
+
1711
+ if !file_listed
1712
+ " Check whether this file is removed based on user request
1713
+ " If it is, then don't display the tags for this file
1714
+ if s:Tlist_User_Removed_File(a:filename)
1715
+ return
1716
+ endif
1717
+ endif
1718
+
1719
+ if file_listed && s:tlist_{fidx}_visible
1720
+ " Check whether the file tags are currently valid
1721
+ if s:tlist_{fidx}_valid
1722
+ " Goto the first line in the file
1723
+ exe s:tlist_{fidx}_start
1724
+
1725
+ " If the line is inside a fold, open the fold
1726
+ if foldclosed('.') != -1
1727
+ exe "silent! " . s:tlist_{fidx}_start . "," .
1728
+ \ s:tlist_{fidx}_end . "foldopen!"
1729
+ endif
1730
+ return
1731
+ endif
1732
+
1733
+ " Discard and remove the tags for this file from display
1734
+ call s:Tlist_Discard_TagInfo(fidx)
1735
+ call s:Tlist_Window_Remove_File_From_Display(fidx)
1736
+ endif
1737
+
1738
+ " Process and generate a list of tags defined in the file
1739
+ if !file_listed || !s:tlist_{fidx}_valid
1740
+ let ret_fidx = s:Tlist_Process_File(a:filename, a:ftype)
1741
+ if ret_fidx == -1
1742
+ return
1743
+ endif
1744
+ let fidx = ret_fidx
1745
+ endif
1746
+
1747
+ " Set report option to a huge value to prevent informational messages
1748
+ " while adding lines to the taglist window
1749
+ let old_report = &report
1750
+ set report=99999
1751
+
1752
+ if g:Tlist_Show_One_File
1753
+ " Remove the previous file
1754
+ if s:tlist_cur_file_idx != -1
1755
+ call s:Tlist_Window_Remove_File_From_Display(s:tlist_cur_file_idx)
1756
+ let s:tlist_{s:tlist_cur_file_idx}_visible = 0
1757
+ let s:tlist_{s:tlist_cur_file_idx}_start = 0
1758
+ let s:tlist_{s:tlist_cur_file_idx}_end = 0
1759
+ endif
1760
+ let s:tlist_cur_file_idx = fidx
1761
+ endif
1762
+
1763
+ " Mark the buffer as modifiable
1764
+ setlocal modifiable
1765
+
1766
+ " Add new files to the end of the window. For existing files, add them at
1767
+ " the same line where they were previously present. If the file is not
1768
+ " visible, then add it at the end
1769
+ if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible
1770
+ if g:Tlist_Compact_Format
1771
+ let s:tlist_{fidx}_start = line('$')
1772
+ else
1773
+ let s:tlist_{fidx}_start = line('$') + 1
1774
+ endif
1775
+ endif
1776
+
1777
+ let s:tlist_{fidx}_visible = 1
1778
+
1779
+ " Goto the line where this file should be placed
1780
+ if g:Tlist_Compact_Format
1781
+ exe s:tlist_{fidx}_start
1782
+ else
1783
+ exe s:tlist_{fidx}_start - 1
1784
+ endif
1785
+
1786
+ let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' .
1787
+ \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')'
1788
+ if g:Tlist_Compact_Format == 0
1789
+ silent! put =txt
1790
+ else
1791
+ silent! put! =txt
1792
+ " Move to the next line
1793
+ exe line('.') + 1
1794
+ endif
1795
+ let file_start = s:tlist_{fidx}_start
1796
+
1797
+ " Add the tag names grouped by tag type to the buffer with a title
1798
+ let i = 1
1799
+ let ttype_cnt = s:tlist_{a:ftype}_count
1800
+ while i <= ttype_cnt
1801
+ let ttype = s:tlist_{a:ftype}_{i}_name
1802
+ " Add the tag type only if there are tags for that type
1803
+ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype
1804
+ let ttype_txt = {fidx_ttype}
1805
+ if ttype_txt != ''
1806
+ let txt = ' ' . s:tlist_{a:ftype}_{i}_fullname
1807
+ if g:Tlist_Compact_Format == 0
1808
+ let ttype_start_lnum = line('.') + 1
1809
+ silent! put =txt
1810
+ else
1811
+ let ttype_start_lnum = line('.')
1812
+ silent! put! =txt
1813
+ endif
1814
+ silent! put =ttype_txt
1815
+
1816
+ let {fidx_ttype}_offset = ttype_start_lnum - file_start
1817
+
1818
+ " create a fold for this tag type
1819
+ let fold_start = ttype_start_lnum
1820
+ let fold_end = fold_start + {fidx_ttype}_count
1821
+ exe fold_start . ',' . fold_end . 'fold'
1822
+
1823
+ " Adjust the cursor position
1824
+ if g:Tlist_Compact_Format == 0
1825
+ exe ttype_start_lnum + {fidx_ttype}_count
1826
+ else
1827
+ exe ttype_start_lnum + {fidx_ttype}_count + 1
1828
+ endif
1829
+
1830
+ if g:Tlist_Compact_Format == 0
1831
+ " Separate the tag types by a empty line
1832
+ silent! put =''
1833
+ endif
1834
+ endif
1835
+ let i = i + 1
1836
+ endwhile
1837
+
1838
+ if s:tlist_{fidx}_tag_count == 0
1839
+ put =''
1840
+ endif
1841
+
1842
+ let s:tlist_{fidx}_end = line('.') - 1
1843
+
1844
+ " Create a fold for the entire file
1845
+ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold'
1846
+ if !g:Tlist_File_Fold_Auto_Close
1847
+ exe 'silent! ' . s:tlist_{fidx}_start . ',' .
1848
+ \ s:tlist_{fidx}_end . 'foldopen!'
1849
+ endif
1850
+
1851
+ " Goto the starting line for this file,
1852
+ exe s:tlist_{fidx}_start
1853
+
1854
+ if s:tlist_app_name == "winmanager"
1855
+ " To handle a bug in the winmanager plugin, add a space at the
1856
+ " last line
1857
+ call setline('$', ' ')
1858
+ endif
1859
+
1860
+ " Mark the buffer as not modifiable
1861
+ setlocal nomodifiable
1862
+
1863
+ " Restore the report option
1864
+ let &report = old_report
1865
+
1866
+ " Update the start and end line numbers for all the files following this
1867
+ " file
1868
+ let start = s:tlist_{fidx}_start
1869
+ " include the empty line after the last line
1870
+ if g:Tlist_Compact_Format
1871
+ let end = s:tlist_{fidx}_end
1872
+ else
1873
+ let end = s:tlist_{fidx}_end + 1
1874
+ endif
1875
+ call s:Tlist_Window_Update_Line_Offsets(fidx + 1, 1, end - start + 1)
1876
+
1877
+ " Now that we have updated the taglist window, update the tags
1878
+ " menu (if present)
1879
+ if g:Tlist_Show_Menu
1880
+ call s:Tlist_Menu_Update_File(1)
1881
+ endif
1882
+ endfunction
1883
+
1884
+ " Tlist_Init_File
1885
+ " Initialize the variables for a new file
1886
+ function! s:Tlist_Init_File(filename, ftype)
1887
+ call s:Tlist_Log_Msg('Tlist_Init_File (' . a:filename . ')')
1888
+ " Add new files at the end of the list
1889
+ let fidx = s:tlist_file_count
1890
+ let s:tlist_file_count = s:tlist_file_count + 1
1891
+ " Add the new file name to the taglist list of file names
1892
+ let s:tlist_file_names = s:tlist_file_names . a:filename . "\n"
1893
+
1894
+ " Initialize the file variables
1895
+ let s:tlist_{fidx}_filename = a:filename
1896
+ let s:tlist_{fidx}_sort_type = g:Tlist_Sort_Type
1897
+ let s:tlist_{fidx}_filetype = a:ftype
1898
+ let s:tlist_{fidx}_mtime = -1
1899
+ let s:tlist_{fidx}_start = 0
1900
+ let s:tlist_{fidx}_end = 0
1901
+ let s:tlist_{fidx}_valid = 0
1902
+ let s:tlist_{fidx}_visible = 0
1903
+ let s:tlist_{fidx}_tag_count = 0
1904
+ let s:tlist_{fidx}_menu_cmd = ''
1905
+
1906
+ " Initialize the tag type variables
1907
+ let i = 1
1908
+ while i <= s:tlist_{a:ftype}_count
1909
+ let ttype = s:tlist_{a:ftype}_{i}_name
1910
+ let s:tlist_{fidx}_{ttype} = ''
1911
+ let s:tlist_{fidx}_{ttype}_offset = 0
1912
+ let s:tlist_{fidx}_{ttype}_count = 0
1913
+ let i = i + 1
1914
+ endwhile
1915
+
1916
+ return fidx
1917
+ endfunction
1918
+
1919
+ " Tlist_Get_Tag_Type_By_Tag
1920
+ " Return the tag type for the specified tag index
1921
+ function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx)
1922
+ let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type'
1923
+
1924
+ " Already parsed and have the tag name
1925
+ if exists(ttype_var)
1926
+ return {ttype_var}
1927
+ endif
1928
+
1929
+ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
1930
+ let {ttype_var} = s:Tlist_Extract_Tagtype(tag_line)
1931
+
1932
+ return {ttype_var}
1933
+ endfunction
1934
+
1935
+ " Tlist_Get_Tag_Prototype
1936
+ function! s:Tlist_Get_Tag_Prototype(fidx, tidx)
1937
+ let tproto_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_proto'
1938
+
1939
+ " Already parsed and have the tag prototype
1940
+ if exists(tproto_var)
1941
+ return {tproto_var}
1942
+ endif
1943
+
1944
+ " Parse and extract the tag prototype
1945
+ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
1946
+ let start = stridx(tag_line, '/^') + 2
1947
+ let end = stridx(tag_line, '/;"' . "\t")
1948
+ if tag_line[end - 1] == '$'
1949
+ let end = end -1
1950
+ endif
1951
+ let tag_proto = strpart(tag_line, start, end - start)
1952
+ let {tproto_var} = substitute(tag_proto, '\s*', '', '')
1953
+
1954
+ return {tproto_var}
1955
+ endfunction
1956
+
1957
+ " Tlist_Get_Tag_SearchPat
1958
+ function! s:Tlist_Get_Tag_SearchPat(fidx, tidx)
1959
+ let tpat_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_searchpat'
1960
+
1961
+ " Already parsed and have the tag search pattern
1962
+ if exists(tpat_var)
1963
+ return {tpat_var}
1964
+ endif
1965
+
1966
+ " Parse and extract the tag search pattern
1967
+ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
1968
+ let start = stridx(tag_line, '/^') + 2
1969
+ let end = stridx(tag_line, '/;"' . "\t")
1970
+ if tag_line[end - 1] == '$'
1971
+ let end = end -1
1972
+ endif
1973
+ let {tpat_var} = '\V\^' . strpart(tag_line, start, end - start) .
1974
+ \ (tag_line[end] == '$' ? '\$' : '')
1975
+
1976
+ return {tpat_var}
1977
+ endfunction
1978
+
1979
+ " Tlist_Get_Tag_Linenum
1980
+ " Return the tag line number, given the tag index
1981
+ function! s:Tlist_Get_Tag_Linenum(fidx, tidx)
1982
+ let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum'
1983
+
1984
+ " Already parsed and have the tag line number
1985
+ if exists(tline_var)
1986
+ return {tline_var}
1987
+ endif
1988
+
1989
+ " Parse and extract the tag line number
1990
+ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag
1991
+ let start = strridx(tag_line, 'line:') + 5
1992
+ let end = strridx(tag_line, "\t")
1993
+ if end < start
1994
+ let {tline_var} = strpart(tag_line, start) + 0
1995
+ else
1996
+ let {tline_var} = strpart(tag_line, start, end - start) + 0
1997
+ endif
1998
+
1999
+ return {tline_var}
2000
+ endfunction
2001
+
2002
+ " Tlist_Parse_Tagline
2003
+ " Parse a tag line from the ctags output. Separate the tag output based on the
2004
+ " tag type and store it in the tag type variable.
2005
+ " The format of each line in the ctags output is:
2006
+ "
2007
+ " tag_name<TAB>file_name<TAB>ex_cmd;"<TAB>extension_fields
2008
+ "
2009
+ function! s:Tlist_Parse_Tagline(tag_line)
2010
+ if a:tag_line == ''
2011
+ " Skip empty lines
2012
+ return
2013
+ endif
2014
+
2015
+ " Extract the tag type
2016
+ let ttype = s:Tlist_Extract_Tagtype(a:tag_line)
2017
+
2018
+ " Make sure the tag type is a valid and supported one
2019
+ if ttype == '' || stridx(s:ctags_flags, ttype) == -1
2020
+ " Line is not in proper tags format or Tag type is not supported
2021
+ return
2022
+ endif
2023
+
2024
+ " Update the total tag count
2025
+ let s:tidx = s:tidx + 1
2026
+
2027
+ " The following variables are used to optimize this code. Vim is slow in
2028
+ " using curly brace names. To reduce the amount of processing needed, the
2029
+ " curly brace variables are pre-processed here
2030
+ let fidx_tidx = 's:tlist_' . s:fidx . '_' . s:tidx
2031
+ let fidx_ttype = 's:tlist_' . s:fidx . '_' . ttype
2032
+
2033
+ " Update the count of this tag type
2034
+ let ttype_idx = {fidx_ttype}_count + 1
2035
+ let {fidx_ttype}_count = ttype_idx
2036
+
2037
+ " Store the ctags output for this tag
2038
+ let {fidx_tidx}_tag = a:tag_line
2039
+
2040
+ " Store the tag index and the tag type index (back pointers)
2041
+ let {fidx_ttype}_{ttype_idx} = s:tidx
2042
+ let {fidx_tidx}_ttype_idx = ttype_idx
2043
+
2044
+ " Extract the tag name
2045
+ let tag_name = strpart(a:tag_line, 0, stridx(a:tag_line, "\t"))
2046
+
2047
+ " Extract the tag scope/prototype
2048
+ if g:Tlist_Display_Prototype
2049
+ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(s:fidx, s:tidx)
2050
+ else
2051
+ let ttxt = ' ' . tag_name
2052
+
2053
+ " Add the tag scope, if it is available and is configured. Tag
2054
+ " scope is the last field after the 'line:<num>\t' field
2055
+ if g:Tlist_Display_Tag_Scope
2056
+ let tag_scope = s:Tlist_Extract_Tag_Scope(a:tag_line)
2057
+ if tag_scope != ''
2058
+ let ttxt = ttxt . ' [' . tag_scope . ']'
2059
+ endif
2060
+ endif
2061
+ endif
2062
+
2063
+ " Add this tag to the tag type variable
2064
+ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n"
2065
+
2066
+ " Save the tag name
2067
+ let {fidx_tidx}_tag_name = tag_name
2068
+ endfunction
2069
+
2070
+ " Tlist_Process_File
2071
+ " Get the list of tags defined in the specified file and store them
2072
+ " in Vim variables. Returns the file index where the tags are stored.
2073
+ function! s:Tlist_Process_File(filename, ftype)
2074
+ call s:Tlist_Log_Msg('Tlist_Process_File (' . a:filename . ', ' .
2075
+ \ a:ftype . ')')
2076
+ " Check whether this file is supported
2077
+ if s:Tlist_Skip_File(a:filename, a:ftype)
2078
+ return -1
2079
+ endif
2080
+
2081
+ " If the tag types for this filetype are not yet created, then create
2082
+ " them now
2083
+ let var = 's:tlist_' . a:ftype . '_count'
2084
+ if !exists(var)
2085
+ if s:Tlist_FileType_Init(a:ftype) == 0
2086
+ return -1
2087
+ endif
2088
+ endif
2089
+
2090
+ " If this file is already processed, then use the cached values
2091
+ let fidx = s:Tlist_Get_File_Index(a:filename)
2092
+ if fidx == -1
2093
+ " First time, this file is loaded
2094
+ let fidx = s:Tlist_Init_File(a:filename, a:ftype)
2095
+ else
2096
+ " File was previously processed. Discard the tag information
2097
+ call s:Tlist_Discard_TagInfo(fidx)
2098
+ endif
2099
+
2100
+ let s:tlist_{fidx}_valid = 1
2101
+
2102
+ " Exuberant ctags arguments to generate a tag list
2103
+ let ctags_args = ' -f - --format=2 --excmd=pattern --fields=nks '
2104
+
2105
+ " Form the ctags argument depending on the sort type
2106
+ if s:tlist_{fidx}_sort_type == 'name'
2107
+ let ctags_args = ctags_args . '--sort=yes'
2108
+ else
2109
+ let ctags_args = ctags_args . '--sort=no'
2110
+ endif
2111
+
2112
+ " Add the filetype specific arguments
2113
+ let ctags_args = ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args
2114
+
2115
+ " Ctags command to produce output with regexp for locating the tags
2116
+ let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args
2117
+ let ctags_cmd = ctags_cmd . ' "' . a:filename . '"'
2118
+
2119
+ " In Windows 95, if not using cygwin, disable the 'shellslash'
2120
+ " option. Otherwise, this will cause problems when running the
2121
+ " ctags command.
2122
+ if has('win95') && !has('win32unix')
2123
+ let old_shellslash = &shellslash
2124
+ set noshellslash
2125
+ endif
2126
+
2127
+ call s:Tlist_Log_Msg('Cmd: ' . ctags_cmd)
2128
+
2129
+ " Run ctags and get the tag list
2130
+ let cmd_output = system(ctags_cmd)
2131
+
2132
+ " Restore the value of the 'shellslash' option.
2133
+ if has('win95') && !has('win32unix')
2134
+ let &shellslash = old_shellslash
2135
+ endif
2136
+
2137
+ " Handle errors
2138
+ if v:shell_error
2139
+ let msg = "Taglist: Failed to generate tags for " . a:filename
2140
+ call s:Tlist_Warning_Msg(msg)
2141
+ if cmd_output != ''
2142
+ call s:Tlist_Warning_Msg(cmd_output)
2143
+ endif
2144
+ return fidx
2145
+ endif
2146
+
2147
+ " No tags for current file
2148
+ if cmd_output == ''
2149
+ call s:Tlist_Log_Msg('No tags defined in ' . a:filename)
2150
+ return fidx
2151
+ endif
2152
+
2153
+ call s:Tlist_Log_Msg('Generated tags information for ' . a:filename)
2154
+
2155
+ " Store the modification time for the file
2156
+ let s:tlist_{fidx}_mtime = getftime(a:filename)
2157
+
2158
+ if v:version > 601
2159
+ " The following script local variables are used by the
2160
+ " Tlist_Parse_Tagline() function.
2161
+ let s:ctags_flags = s:tlist_{a:ftype}_ctags_flags
2162
+ let s:fidx = fidx
2163
+ let s:tidx = 0
2164
+
2165
+ " Process the ctags output one line at a time. The substitute()
2166
+ " command is used to parse the tag lines instead of using the
2167
+ " matchstr()/stridx()/strpart() functions for performance reason
2168
+ call substitute(cmd_output, "\\([^\n]\\+\\)\n",
2169
+ \ '\=s:Tlist_Parse_Tagline(submatch(1))', 'g')
2170
+
2171
+ " Save the number of tags for this file
2172
+ let s:tlist_{fidx}_tag_count = s:tidx
2173
+
2174
+ " The following script local variables are no longer needed
2175
+ unlet! s:ctags_flags
2176
+ unlet! s:tidx
2177
+ unlet! s:fidx
2178
+ else
2179
+ " Due to a bug in Vim earlier than version 6.1,
2180
+ " we cannot use substitute() to parse the ctags output.
2181
+ " Instead the slow str*() functions are used
2182
+ let ctags_flags = s:tlist_{a:ftype}_ctags_flags
2183
+ let tidx = 0
2184
+
2185
+ while cmd_output != ''
2186
+ " Extract one line at a time
2187
+ let idx = stridx(cmd_output, "\n")
2188
+ let one_line = strpart(cmd_output, 0, idx)
2189
+ " Remove the line from the tags output
2190
+ let cmd_output = strpart(cmd_output, idx + 1)
2191
+
2192
+ if one_line == ''
2193
+ " Line is not in proper tags format
2194
+ continue
2195
+ endif
2196
+
2197
+ " Extract the tag type
2198
+ let ttype = s:Tlist_Extract_Tagtype(one_line)
2199
+
2200
+ " Make sure the tag type is a valid and supported one
2201
+ if ttype == '' || stridx(s:ctags_flags, ttype) == -1
2202
+ " Line is not in proper tags format or Tag type is not
2203
+ " supported
2204
+ continue
2205
+ endif
2206
+
2207
+ " Update the total tag count
2208
+ let tidx = tidx + 1
2209
+
2210
+ " The following variables are used to optimize this code. Vim is
2211
+ " slow in using curly brace names. To reduce the amount of
2212
+ " processing needed, the curly brace variables are pre-processed
2213
+ " here
2214
+ let fidx_tidx = 's:tlist_' . fidx . '_' . tidx
2215
+ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype
2216
+
2217
+ " Update the count of this tag type
2218
+ let ttype_idx = {fidx_ttype}_count + 1
2219
+ let {fidx_ttype}_count = ttype_idx
2220
+
2221
+ " Store the ctags output for this tag
2222
+ let {fidx_tidx}_tag = one_line
2223
+
2224
+ " Store the tag index and the tag type index (back pointers)
2225
+ let {fidx_ttype}_{ttype_idx} = tidx
2226
+ let {fidx_tidx}_ttype_idx = ttype_idx
2227
+
2228
+ " Extract the tag name
2229
+ let tag_name = strpart(one_line, 0, stridx(one_line, "\t"))
2230
+
2231
+ " Extract the tag scope/prototype
2232
+ if g:Tlist_Display_Prototype
2233
+ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(fidx, tidx)
2234
+ else
2235
+ let ttxt = ' ' . tag_name
2236
+
2237
+ " Add the tag scope, if it is available and is configured. Tag
2238
+ " scope is the last field after the 'line:<num>\t' field
2239
+ if g:Tlist_Display_Tag_Scope
2240
+ let tag_scope = s:Tlist_Extract_Tag_Scope(one_line)
2241
+ if tag_scope != ''
2242
+ let ttxt = ttxt . ' [' . tag_scope . ']'
2243
+ endif
2244
+ endif
2245
+ endif
2246
+
2247
+ " Add this tag to the tag type variable
2248
+ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n"
2249
+
2250
+ " Save the tag name
2251
+ let {fidx_tidx}_tag_name = tag_name
2252
+ endwhile
2253
+
2254
+ " Save the number of tags for this file
2255
+ let s:tlist_{fidx}_tag_count = tidx
2256
+ endif
2257
+
2258
+ call s:Tlist_Log_Msg('Processed ' . s:tlist_{fidx}_tag_count .
2259
+ \ ' tags in ' . a:filename)
2260
+
2261
+ return fidx
2262
+ endfunction
2263
+
2264
+ " Tlist_Update_File
2265
+ " Update the tags for a file (if needed)
2266
+ function! Tlist_Update_File(filename, ftype)
2267
+ call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')')
2268
+ " If the file doesn't support tag listing, skip it
2269
+ if s:Tlist_Skip_File(a:filename, a:ftype)
2270
+ return
2271
+ endif
2272
+
2273
+ " Convert the file name to a full path
2274
+ let fname = fnamemodify(a:filename, ':p')
2275
+
2276
+ " First check whether the file already exists
2277
+ let fidx = s:Tlist_Get_File_Index(fname)
2278
+
2279
+ if fidx != -1 && s:tlist_{fidx}_valid
2280
+ " File exists and the tags are valid
2281
+ " Check whether the file was modified after the last tags update
2282
+ " If it is modified, then update the tags
2283
+ if s:tlist_{fidx}_mtime == getftime(fname)
2284
+ return
2285
+ endif
2286
+ else
2287
+ " If the tags were removed previously based on a user request,
2288
+ " as we are going to update the tags (based on the user request),
2289
+ " remove the filename from the deleted list
2290
+ call s:Tlist_Update_Remove_List(fname, 0)
2291
+ endif
2292
+
2293
+ " If the taglist window is opened, update it
2294
+ let winnum = bufwinnr(g:TagList_title)
2295
+ if winnum == -1
2296
+ " Taglist window is not present. Just update the taglist
2297
+ " and return
2298
+ call s:Tlist_Process_File(fname, a:ftype)
2299
+ else
2300
+ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != -1
2301
+ " If tags for only one file are displayed and we are not
2302
+ " updating the tags for that file, then no need to
2303
+ " refresh the taglist window. Otherwise, the taglist
2304
+ " window should be updated.
2305
+ if s:tlist_{s:tlist_cur_file_idx}_filename != fname
2306
+ call s:Tlist_Process_File(fname, a:ftype)
2307
+ return
2308
+ endif
2309
+ endif
2310
+
2311
+ " Save the current window number
2312
+ let save_winnr = winnr()
2313
+
2314
+ " Goto the taglist window
2315
+ call s:Tlist_Window_Goto_Window()
2316
+
2317
+ " Save the cursor position
2318
+ let save_line = line('.')
2319
+ let save_col = col('.')
2320
+
2321
+ " Update the taglist window
2322
+ call s:Tlist_Window_Refresh_File(fname, a:ftype)
2323
+
2324
+ " Restore the cursor position
2325
+ if v:version >= 601
2326
+ call cursor(save_line, save_col)
2327
+ else
2328
+ exe save_line
2329
+ exe 'normal! ' . save_col . '|'
2330
+ endif
2331
+
2332
+ if winnr() != save_winnr
2333
+ " Go back to the original window
2334
+ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w')
2335
+ endif
2336
+ endif
2337
+
2338
+ " Update the taglist menu
2339
+ if g:Tlist_Show_Menu
2340
+ call s:Tlist_Menu_Update_File(1)
2341
+ endif
2342
+ endfunction
2343
+
2344
+ " Tlist_Window_Close
2345
+ " Close the taglist window
2346
+ function! s:Tlist_Window_Close()
2347
+ call s:Tlist_Log_Msg('Tlist_Window_Close()')
2348
+ " Make sure the taglist window exists
2349
+ let winnum = bufwinnr(g:TagList_title)
2350
+ if winnum == -1
2351
+ call s:Tlist_Warning_Msg('Error: Taglist window is not open')
2352
+ return
2353
+ endif
2354
+
2355
+ if winnr() == winnum
2356
+ " Already in the taglist window. Close it and return
2357
+ if winbufnr(2) != -1
2358
+ " If a window other than the taglist window is open,
2359
+ " then only close the taglist window.
2360
+ close
2361
+ endif
2362
+ else
2363
+ " Goto the taglist window, close it and then come back to the
2364
+ " original window
2365
+ let curbufnr = bufnr('%')
2366
+ exe winnum . 'wincmd w'
2367
+ close
2368
+ " Need to jump back to the original window only if we are not
2369
+ " already in that window
2370
+ let winnum = bufwinnr(curbufnr)
2371
+ if winnr() != winnum
2372
+ exe winnum . 'wincmd w'
2373
+ endif
2374
+ endif
2375
+ endfunction
2376
+
2377
+ " Tlist_Window_Open
2378
+ " Open and refresh the taglist window
2379
+ function! s:Tlist_Window_Open()
2380
+ call s:Tlist_Log_Msg('Tlist_Window_Open()')
2381
+ " If the window is open, jump to it
2382
+ let winnum = bufwinnr(g:TagList_title)
2383
+ if winnum != -1
2384
+ " Jump to the existing window
2385
+ if winnr() != winnum
2386
+ exe winnum . 'wincmd w'
2387
+ endif
2388
+ return
2389
+ endif
2390
+
2391
+ if s:tlist_app_name == "winmanager"
2392
+ " Taglist plugin is no longer part of the winmanager app
2393
+ let s:tlist_app_name = "none"
2394
+ endif
2395
+
2396
+ " Get the filename and filetype for the specified buffer
2397
+ let curbuf_name = fnamemodify(bufname('%'), ':p')
2398
+ let curbuf_ftype = getbufvar('%', '&filetype')
2399
+ let cur_lnum = line('.')
2400
+
2401
+ " Mark the current window as the desired window to open a file
2402
+ " when a tag is selected
2403
+ let w:tlist_file_window = "yes"
2404
+
2405
+ " Open the taglist window
2406
+ call s:Tlist_Window_Create()
2407
+
2408
+ call s:Tlist_Window_Refresh()
2409
+
2410
+ if g:Tlist_Show_One_File
2411
+ " Add only the current buffer and file
2412
+ "
2413
+ " If the file doesn't support tag listing, skip it
2414
+ if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype)
2415
+ call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype)
2416
+ endif
2417
+ endif
2418
+
2419
+ if g:Tlist_File_Fold_Auto_Close
2420
+ " Open the fold for the current file, as all the folds in
2421
+ " the taglist window are closed
2422
+ let fidx = s:Tlist_Get_File_Index(curbuf_name)
2423
+ if fidx != -1
2424
+ exe "silent! " . s:tlist_{fidx}_start . "," .
2425
+ \ s:tlist_{fidx}_end . "foldopen!"
2426
+ endif
2427
+ endif
2428
+
2429
+ " Highlight the current tag
2430
+ call s:Tlist_Window_Highlight_Tag(curbuf_name, cur_lnum, 1, 1)
2431
+ endfunction
2432
+
2433
+ " Tlist_Window_Toggle()
2434
+ " Open or close a taglist window
2435
+ function! s:Tlist_Window_Toggle()
2436
+ call s:Tlist_Log_Msg('Tlist_Window_Toggle()')
2437
+ " If taglist window is open then close it.
2438
+ let winnum = bufwinnr(g:TagList_title)
2439
+ if winnum != -1
2440
+ call s:Tlist_Window_Close()
2441
+ return
2442
+ endif
2443
+
2444
+ call s:Tlist_Window_Open()
2445
+
2446
+ " Go back to the original window, if Tlist_GainFocus_On_ToggleOpen is not
2447
+ " set
2448
+ if !g:Tlist_GainFocus_On_ToggleOpen
2449
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
2450
+ endif
2451
+
2452
+ " Update the taglist menu
2453
+ if g:Tlist_Show_Menu
2454
+ call s:Tlist_Menu_Update_File(0)
2455
+ endif
2456
+ endfunction
2457
+
2458
+ " Tlist_Process_Filelist
2459
+ " Process multiple files. Each filename is separated by "\n"
2460
+ " Returns the number of processed files
2461
+ function! s:Tlist_Process_Filelist(file_names)
2462
+ let flist = a:file_names
2463
+
2464
+ " Enable lazy screen updates
2465
+ let old_lazyredraw = &lazyredraw
2466
+ set lazyredraw
2467
+
2468
+ " Keep track of the number of processed files
2469
+ let fcnt = 0
2470
+
2471
+ " Process one file at a time
2472
+ while flist != ''
2473
+ let nl_idx = stridx(flist, "\n")
2474
+ let one_file = strpart(flist, 0, nl_idx)
2475
+
2476
+ " Remove the filename from the list
2477
+ let flist = strpart(flist, nl_idx + 1)
2478
+
2479
+ if one_file == ''
2480
+ continue
2481
+ endif
2482
+
2483
+ " Skip directories
2484
+ if isdirectory(one_file)
2485
+ continue
2486
+ endif
2487
+
2488
+ let ftype = s:Tlist_Get_Filetype(one_file)
2489
+
2490
+ echon "\r "
2491
+ echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t')
2492
+
2493
+ let fcnt = fcnt + 1
2494
+
2495
+ call Tlist_Update_File(one_file, ftype)
2496
+ endwhile
2497
+
2498
+ " Clear the displayed informational messages
2499
+ echon "\r "
2500
+
2501
+ " Restore the previous state
2502
+ let &lazyredraw = old_lazyredraw
2503
+
2504
+ return fcnt
2505
+ endfunction
2506
+
2507
+ " Tlist_Process_Dir
2508
+ " Process the files in a directory matching the specified pattern
2509
+ function! s:Tlist_Process_Dir(dir_name, pat)
2510
+ let flist = glob(a:dir_name . '/' . a:pat) . "\n"
2511
+
2512
+ let fcnt = s:Tlist_Process_Filelist(flist)
2513
+
2514
+ let len = strlen(a:dir_name)
2515
+ if a:dir_name[len - 1] == '\' || a:dir_name[len - 1] == '/'
2516
+ let glob_expr = a:dir_name . '*'
2517
+ else
2518
+ let glob_expr = a:dir_name . '/*'
2519
+ endif
2520
+ let all_files = glob(glob_expr) . "\n"
2521
+
2522
+ while all_files != ''
2523
+ let nl_idx = stridx(all_files, "\n")
2524
+ let one_file = strpart(all_files, 0, nl_idx)
2525
+
2526
+ let all_files = strpart(all_files, nl_idx + 1)
2527
+ if one_file == ''
2528
+ continue
2529
+ endif
2530
+
2531
+ " Skip non-directory names
2532
+ if !isdirectory(one_file)
2533
+ continue
2534
+ endif
2535
+
2536
+ echon "\r "
2537
+ echon "\rProcessing files in directory " . fnamemodify(one_file, ':t')
2538
+ let fcnt = fcnt + s:Tlist_Process_Dir(one_file, a:pat)
2539
+ endwhile
2540
+
2541
+ return fcnt
2542
+ endfunction
2543
+
2544
+ " Tlist_Add_Files_Recursive
2545
+ " Add files recursively from a directory
2546
+ function! s:Tlist_Add_Files_Recursive(dir, ...)
2547
+ let dir_name = fnamemodify(a:dir, ':p')
2548
+ if !isdirectory(dir_name)
2549
+ call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory')
2550
+ return
2551
+ endif
2552
+
2553
+ if a:0 == 1
2554
+ " User specified file pattern
2555
+ let pat = a:1
2556
+ else
2557
+ " Default file pattern
2558
+ let pat = '*'
2559
+ endif
2560
+
2561
+ echon "\r "
2562
+ echon "\rProcessing files in directory " . fnamemodify(dir_name, ':t')
2563
+ let fcnt = s:Tlist_Process_Dir(dir_name, pat)
2564
+
2565
+ echon "\rAdded " . fcnt . " files to the taglist"
2566
+ endfunction
2567
+
2568
+ " Tlist_Add_Files
2569
+ " Add the specified list of files to the taglist
2570
+ function! s:Tlist_Add_Files(...)
2571
+ let flist = ''
2572
+ let i = 1
2573
+
2574
+ " Get all the files matching the file patterns supplied as argument
2575
+ while i <= a:0
2576
+ let flist = flist . glob(a:{i}) . "\n"
2577
+ let i = i + 1
2578
+ endwhile
2579
+
2580
+ if flist == ''
2581
+ call s:Tlist_Warning_Msg('Error: No matching files are found')
2582
+ return
2583
+ endif
2584
+
2585
+ let fcnt = s:Tlist_Process_Filelist(flist)
2586
+ echon "\rAdded " . fcnt . " files to the taglist"
2587
+ endfunction
2588
+
2589
+ " Tlist_Extract_Tagtype
2590
+ " Extract the tag type from the tag text
2591
+ function! s:Tlist_Extract_Tagtype(tag_line)
2592
+ " The tag type is after the tag prototype field. The prototype field
2593
+ " ends with the /;"\t string. We add 4 at the end to skip the characters
2594
+ " in this special string..
2595
+ let start = strridx(a:tag_line, '/;"' . "\t") + 4
2596
+ let end = strridx(a:tag_line, 'line:') - 1
2597
+ let ttype = strpart(a:tag_line, start, end - start)
2598
+
2599
+ return ttype
2600
+ endfunction
2601
+
2602
+ " Tlist_Extract_Tag_Scope
2603
+ " Extract the tag scope from the tag text
2604
+ function! s:Tlist_Extract_Tag_Scope(tag_line)
2605
+ let start = strridx(a:tag_line, 'line:')
2606
+ let end = strridx(a:tag_line, "\t")
2607
+ if end <= start
2608
+ return ''
2609
+ endif
2610
+
2611
+ let tag_scope = strpart(a:tag_line, end + 1)
2612
+ let tag_scope = strpart(tag_scope, stridx(tag_scope, ':') + 1)
2613
+
2614
+ return tag_scope
2615
+ endfunction
2616
+
2617
+ " Tlist_Refresh()
2618
+ " Refresh the taglist
2619
+ function! s:Tlist_Refresh()
2620
+ call s:Tlist_Log_Msg('Tlist_Refresh (Skip_Refresh = ' .
2621
+ \ s:Tlist_Skip_Refresh . ', ' . bufname('%') . ')')
2622
+ " If we are entering the buffer from one of the taglist functions, then
2623
+ " no need to refresh the taglist window again.
2624
+ if s:Tlist_Skip_Refresh
2625
+ " We still need to update the taglist menu
2626
+ if g:Tlist_Show_Menu
2627
+ call s:Tlist_Menu_Update_File(0)
2628
+ endif
2629
+ return
2630
+ endif
2631
+
2632
+ " If part of the winmanager plugin and not configured to process
2633
+ " tags always and not configured to display the tags menu, then return
2634
+ if (s:tlist_app_name == 'winmanager') && !g:Tlist_Process_File_Always
2635
+ \ && !g:Tlist_Show_Menu
2636
+ return
2637
+ endif
2638
+
2639
+ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help
2640
+ if &buftype != ''
2641
+ return
2642
+ endif
2643
+
2644
+ let filename = fnamemodify(bufname('%'), ':p')
2645
+ let ftype = &filetype
2646
+
2647
+ " If the file doesn't support tag listing, skip it
2648
+ if s:Tlist_Skip_File(filename, ftype)
2649
+ return
2650
+ endif
2651
+
2652
+ let tlist_win = bufwinnr(g:TagList_title)
2653
+
2654
+ " If the taglist window is not opened and not configured to process
2655
+ " tags always and not displaying the tags menu, then return
2656
+ if tlist_win == -1 && !g:Tlist_Process_File_Always && !g:Tlist_Show_Menu
2657
+ return
2658
+ endif
2659
+
2660
+ let fidx = s:Tlist_Get_File_Index(filename)
2661
+ if fidx == -1
2662
+ " Check whether this file is removed based on user request
2663
+ " If it is, then don't display the tags for this file
2664
+ if s:Tlist_User_Removed_File(filename)
2665
+ return
2666
+ endif
2667
+
2668
+ " If the taglist should not be auto updated, then return
2669
+ if !g:Tlist_Auto_Update
2670
+ return
2671
+ endif
2672
+ endif
2673
+
2674
+ let cur_lnum = line('.')
2675
+
2676
+ if fidx == -1
2677
+ " Update the tags for the file
2678
+ let fidx = s:Tlist_Process_File(filename, ftype)
2679
+ else
2680
+ let mtime = getftime(filename)
2681
+ if s:tlist_{fidx}_mtime != mtime
2682
+ " Invalidate the tags listed for this file
2683
+ let s:tlist_{fidx}_valid = 0
2684
+
2685
+ " Update the taglist and the window
2686
+ call Tlist_Update_File(filename, ftype)
2687
+
2688
+ " Store the new file modification time
2689
+ let s:tlist_{fidx}_mtime = mtime
2690
+ endif
2691
+ endif
2692
+
2693
+ " Update the taglist window
2694
+ if tlist_win != -1
2695
+ " Disable screen updates
2696
+ let old_lazyredraw = &lazyredraw
2697
+ set nolazyredraw
2698
+
2699
+ " Save the current window number
2700
+ let save_winnr = winnr()
2701
+
2702
+ " Goto the taglist window
2703
+ call s:Tlist_Window_Goto_Window()
2704
+
2705
+ if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter
2706
+ " Save the cursor position
2707
+ let save_line = line('.')
2708
+ let save_col = col('.')
2709
+ endif
2710
+
2711
+ " Update the taglist window
2712
+ call s:Tlist_Window_Refresh_File(filename, ftype)
2713
+
2714
+ " Open the fold for the file
2715
+ exe "silent! " . s:tlist_{fidx}_start . "," .
2716
+ \ s:tlist_{fidx}_end . "foldopen!"
2717
+
2718
+ if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag
2719
+ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx
2720
+ " If displaying tags for only one file in the taglist
2721
+ " window and about to display the tags for a new file,
2722
+ " then center the current tag line for the new file
2723
+ let center_tag_line = 1
2724
+ else
2725
+ let center_tag_line = 0
2726
+ endif
2727
+
2728
+ " Highlight the current tag
2729
+ call s:Tlist_Window_Highlight_Tag(filename, cur_lnum, 1, center_tag_line)
2730
+ else
2731
+ " Restore the cursor position
2732
+ if v:version >= 601
2733
+ call cursor(save_line, save_col)
2734
+ else
2735
+ exe save_line
2736
+ exe 'normal! ' . save_col . '|'
2737
+ endif
2738
+ endif
2739
+
2740
+ " Jump back to the original window
2741
+ if save_winnr != winnr()
2742
+ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w')
2743
+ endif
2744
+
2745
+ " Restore screen updates
2746
+ let &lazyredraw = old_lazyredraw
2747
+ endif
2748
+
2749
+ " Update the taglist menu
2750
+ if g:Tlist_Show_Menu
2751
+ call s:Tlist_Menu_Update_File(0)
2752
+ endif
2753
+ endfunction
2754
+
2755
+ " Tlist_Change_Sort()
2756
+ " Change the sort order of the tag listing
2757
+ " caller == 1, taglist window
2758
+ " caller == 2, taglist menu
2759
+ " action == 1, toggle sort from name to order and vice versa
2760
+ " action == 2, set the sort order to sort_type
2761
+ function! s:Tlist_Change_Sort(caller, action, sort_type)
2762
+ call s:Tlist_Log_Msg('Tlist_Change_Sort (caller = ' . a:caller .
2763
+ \ ', action = ' . a:action . ', sort_type = ' . a:sort_type . ')')
2764
+ if a:caller == 1
2765
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
2766
+ if fidx == -1
2767
+ return
2768
+ endif
2769
+
2770
+ " Remove the previous highlighting
2771
+ match none
2772
+ elseif a:caller == 2
2773
+ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
2774
+ if fidx == -1
2775
+ return
2776
+ endif
2777
+ endif
2778
+
2779
+ if a:action == 1
2780
+ let sort_type = s:tlist_{fidx}_sort_type
2781
+
2782
+ " Toggle the sort order from 'name' to 'order' and vice versa
2783
+ if sort_type == 'name'
2784
+ let s:tlist_{fidx}_sort_type = 'order'
2785
+ else
2786
+ let s:tlist_{fidx}_sort_type = 'name'
2787
+ endif
2788
+ else
2789
+ let s:tlist_{fidx}_sort_type = a:sort_type
2790
+ endif
2791
+
2792
+ " Invalidate the tags listed for this file
2793
+ let s:tlist_{fidx}_valid = 0
2794
+
2795
+ if a:caller == 1
2796
+ " Save the current line for later restoration
2797
+ let curline = '\V\^' . getline('.') . '\$'
2798
+
2799
+ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename,
2800
+ \ s:tlist_{fidx}_filetype)
2801
+
2802
+ " Go back to the cursor line before the tag list is sorted
2803
+ call search(curline, 'w')
2804
+
2805
+ call s:Tlist_Menu_Update_File(1)
2806
+ else
2807
+ call s:Tlist_Menu_Remove_File()
2808
+
2809
+ call s:Tlist_Refresh()
2810
+ endif
2811
+ endfunction
2812
+
2813
+ " Tlist_Update_Current_File()
2814
+ " Update taglist for the current buffer by regenerating the tag list
2815
+ " Contributed by WEN Guopeng.
2816
+ function! s:Tlist_Update_Current_File()
2817
+ call s:Tlist_Log_Msg('Tlist_Update_Current_File()')
2818
+ if winnr() == bufwinnr(g:TagList_title)
2819
+ " In the taglist window. Update the current file
2820
+ call s:Tlist_Window_Update_File()
2821
+ else
2822
+ " Not in the taglist window. Update the current buffer
2823
+ let filename = fnamemodify(bufname('%'), ':p')
2824
+ let fidx = s:Tlist_Get_File_Index(filename)
2825
+ if fidx != -1
2826
+ let s:tlist_{fidx}_valid = 0
2827
+ endif
2828
+ call Tlist_Update_File(filename, &filetype)
2829
+ endif
2830
+ endfunction
2831
+
2832
+ " Tlist_Window_Update_File()
2833
+ " Update the tags displayed in the taglist window
2834
+ function! s:Tlist_Window_Update_File()
2835
+ call s:Tlist_Log_Msg('Tlist_Window_Update_File()')
2836
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
2837
+ if fidx == -1
2838
+ return
2839
+ endif
2840
+
2841
+ " Remove the previous highlighting
2842
+ match none
2843
+
2844
+ " Save the current line for later restoration
2845
+ let curline = '\V\^' . getline('.') . '\$'
2846
+
2847
+ let s:tlist_{fidx}_valid = 0
2848
+
2849
+ " Update the taglist window
2850
+ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename,
2851
+ \ s:tlist_{fidx}_filetype)
2852
+
2853
+ " Go back to the tag line before the list is updated
2854
+ call search(curline, 'w')
2855
+ endfunction
2856
+
2857
+ " Tlist_Window_Get_Tag_Type_By_Linenum()
2858
+ " Return the tag type index for the specified line in the taglist window
2859
+ function! s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum)
2860
+ let ftype = s:tlist_{a:fidx}_filetype
2861
+
2862
+ " Determine to which tag type the current line number belongs to using the
2863
+ " tag type start line number and the number of tags in a tag type
2864
+ let i = 1
2865
+ while i <= s:tlist_{ftype}_count
2866
+ let ttype = s:tlist_{ftype}_{i}_name
2867
+ let start_lnum =
2868
+ \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset
2869
+ let end = start_lnum + s:tlist_{a:fidx}_{ttype}_count
2870
+ if a:lnum >= start_lnum && a:lnum <= end
2871
+ break
2872
+ endif
2873
+ let i = i + 1
2874
+ endwhile
2875
+
2876
+ " Current line doesn't belong to any of the displayed tag types
2877
+ if i > s:tlist_{ftype}_count
2878
+ return ''
2879
+ endif
2880
+
2881
+ return ttype
2882
+ endfunction
2883
+
2884
+ " Tlist_Window_Get_Tag_Index()
2885
+ " Return the tag index for the specified line in the taglist window
2886
+ function! s:Tlist_Window_Get_Tag_Index(fidx, lnum)
2887
+ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(a:fidx, a:lnum)
2888
+
2889
+ " Current line doesn't belong to any of the displayed tag types
2890
+ if ttype == ''
2891
+ return 0
2892
+ endif
2893
+
2894
+ " Compute the index into the displayed tags for the tag type
2895
+ let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset
2896
+ let tidx = a:lnum - ttype_lnum
2897
+ if tidx == 0
2898
+ return 0
2899
+ endif
2900
+
2901
+ " Get the corresponding tag line and return it
2902
+ return s:tlist_{a:fidx}_{ttype}_{tidx}
2903
+ endfunction
2904
+
2905
+ " Tlist_Window_Highlight_Line
2906
+ " Highlight the current line
2907
+ function! s:Tlist_Window_Highlight_Line()
2908
+ " Clear previously selected name
2909
+ match none
2910
+
2911
+ " Highlight the current line
2912
+ if g:Tlist_Display_Prototype == 0
2913
+ let pat = '/\%' . line('.') . 'l\s\+\zs.*/'
2914
+ else
2915
+ let pat = '/\%' . line('.') . 'l.*/'
2916
+ endif
2917
+
2918
+ exe 'match TagListTagName ' . pat
2919
+ endfunction
2920
+
2921
+ " Tlist_Window_Open_File
2922
+ " Open the specified file in either a new window or an existing window
2923
+ " and place the cursor at the specified tag pattern
2924
+ function! s:Tlist_Window_Open_File(win_ctrl, filename, tagpat)
2925
+ call s:Tlist_Log_Msg('Tlist_Window_Open_File (' . a:filename . ')')
2926
+ let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh
2927
+ let s:Tlist_Skip_Refresh = 1
2928
+
2929
+ if s:tlist_app_name == "winmanager"
2930
+ " Let the winmanager edit the file
2931
+ call WinManagerFileEdit(a:filename, a:win_ctrl)
2932
+ else
2933
+
2934
+ " Goto the window containing the file. If the window is not there, open a
2935
+ " new window
2936
+ let winnum = bufwinnr(a:filename)
2937
+ if winnum == -1
2938
+ " Locate the previously used window for opening a file
2939
+ let fwin_num = 0
2940
+ let first_usable_win = 0
2941
+
2942
+ let i = 1
2943
+ let bnum = winbufnr(i)
2944
+ while bnum != -1
2945
+ if getwinvar(i, 'tlist_file_window') == 'yes'
2946
+ let fwin_num = i
2947
+ break
2948
+ endif
2949
+ if first_usable_win == 0 && bufname(bnum) != g:TagList_title &&
2950
+ \ getbufvar(bnum, '&buftype') == ''
2951
+ " First non-taglist and a non-plugin window
2952
+ let first_usable_win = i
2953
+ endif
2954
+ let i = i + 1
2955
+ let bnum = winbufnr(i)
2956
+ endwhile
2957
+
2958
+ " If a previously used window is not found, then use the first
2959
+ " non-taglist window
2960
+ if fwin_num == 0
2961
+ let fwin_num = first_usable_win
2962
+ endif
2963
+
2964
+ if fwin_num != 0
2965
+ " Jump to the file window
2966
+ exe fwin_num . "wincmd w"
2967
+
2968
+ " If the user asked to jump to the tag in a new window, then split
2969
+ " the existing window into two.
2970
+ if a:win_ctrl == 1
2971
+ split
2972
+ endif
2973
+ exe "edit " . escape(a:filename, ' ')
2974
+ else
2975
+ " Open a new window
2976
+ if g:Tlist_Use_Horiz_Window
2977
+ exe 'leftabove split ' . escape(a:filename, ' ')
2978
+ else
2979
+ if winbufnr(2) == -1
2980
+ " Only the taglist window is present
2981
+ if g:Tlist_Use_Right_Window
2982
+ exe 'leftabove vertical split ' .
2983
+ \ escape(a:filename, ' ')
2984
+ else
2985
+ exe 'rightbelow vertical split ' .
2986
+ \ escape(a:filename, ' ')
2987
+ endif
2988
+
2989
+ " Go to the taglist window to change the window size to
2990
+ " the user configured value
2991
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
2992
+ if g:Tlist_Use_Horiz_Window
2993
+ exe 'resize ' . g:Tlist_WinHeight
2994
+ else
2995
+ exe 'vertical resize ' . g:Tlist_WinWidth
2996
+ endif
2997
+ " Go back to the file window
2998
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
2999
+ else
3000
+ " A plugin or help window is also present
3001
+ wincmd w
3002
+ exe 'leftabove split ' . escape(a:filename, ' ')
3003
+ endif
3004
+ endif
3005
+ endif
3006
+ " Mark the window, so that it can be reused.
3007
+ let w:tlist_file_window = "yes"
3008
+ else
3009
+ exe winnum . 'wincmd w'
3010
+
3011
+ " If the user asked to jump to the tag in a new window, then split the
3012
+ " existing window into two.
3013
+ if a:win_ctrl == 1
3014
+ split
3015
+ endif
3016
+ endif
3017
+ endif
3018
+
3019
+ " Jump to the tag
3020
+ if a:tagpat != ''
3021
+ " Add the current cursor position to the jump list, so that user can
3022
+ " jump back using the ' and ` marks.
3023
+ mark '
3024
+ silent call search(a:tagpat, 'w')
3025
+
3026
+ " Bring the line to the middle of the window
3027
+ normal! z.
3028
+
3029
+ " If the line is inside a fold, open the fold
3030
+ if foldclosed('.') != -1
3031
+ .foldopen
3032
+ endif
3033
+ endif
3034
+
3035
+ " If the user selects to preview the tag then jump back to the
3036
+ " taglist window
3037
+ if a:win_ctrl == 2
3038
+ " Go back to the taglist window
3039
+ let winnum = bufwinnr(g:TagList_title)
3040
+ exe winnum . 'wincmd w'
3041
+ else
3042
+ " If the user has selected to close the taglist window, when a
3043
+ " tag is selected, close the taglist window
3044
+ if g:Tlist_Close_On_Select
3045
+ call s:Tlist_Window_Goto_Window()
3046
+ close
3047
+
3048
+ " Go back to the window displaying the selected file
3049
+ let wnum = bufwinnr(a:filename)
3050
+ if wnum != -1 && wnum != winnr()
3051
+ call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w')
3052
+ endif
3053
+ endif
3054
+ endif
3055
+
3056
+ let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh
3057
+ endfunction
3058
+
3059
+ " Tlist_Window_Jump_To_Tag()
3060
+ " Jump to the location of the current tag
3061
+ " win_ctrl == 0 - Reuse the existing file window
3062
+ " win_ctrl == 1 - Open a new window
3063
+ " win_ctrl == 2 - Preview the tag
3064
+ function! s:Tlist_Window_Jump_To_Tag(win_ctrl)
3065
+ call s:Tlist_Log_Msg('Tlist_Window_Jump_To_Tag()')
3066
+ " Do not process comment lines and empty lines
3067
+ let curline = getline('.')
3068
+ if curline =~ '^\s*$' || curline[0] == '"'
3069
+ return
3070
+ endif
3071
+
3072
+ " If inside a closed fold, then use the first line of the fold
3073
+ " and jump to the file.
3074
+ let lnum = foldclosed('.')
3075
+ if lnum == -1
3076
+ " Jump to the selected tag or file
3077
+ let lnum = line('.')
3078
+ else
3079
+ " Open the closed fold
3080
+ .foldopen!
3081
+ endif
3082
+
3083
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
3084
+ if fidx == -1
3085
+ return
3086
+ endif
3087
+
3088
+ " Get the tag output for the current tag
3089
+ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum)
3090
+ if tidx != 0
3091
+ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx)
3092
+
3093
+ " Highlight the tagline
3094
+ call s:Tlist_Window_Highlight_Line()
3095
+ else
3096
+ " Selected a line which is not a tag name. Just edit the file
3097
+ let tagpat = ''
3098
+ endif
3099
+
3100
+ call s:Tlist_Window_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat)
3101
+ endfunction
3102
+
3103
+ " Tlist_Window_Show_Info()
3104
+ " Display information about the entry under the cursor
3105
+ function! s:Tlist_Window_Show_Info()
3106
+ call s:Tlist_Log_Msg('Tlist_Window_Show_Info()')
3107
+
3108
+ " Clear the previously displayed line
3109
+ echo
3110
+
3111
+ " Do not process comment lines and empty lines
3112
+ let curline = getline('.')
3113
+ if curline =~ '^\s*$' || curline[0] == '"'
3114
+ return
3115
+ endif
3116
+
3117
+ " If inside a fold, then don't display the prototype
3118
+ if foldclosed('.') != -1
3119
+ return
3120
+ endif
3121
+
3122
+ let lnum = line('.')
3123
+
3124
+ " Get the file index
3125
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum)
3126
+ if fidx == -1
3127
+ return
3128
+ endif
3129
+
3130
+ if lnum == s:tlist_{fidx}_start
3131
+ " Cursor is on a file name
3132
+ let fname = s:tlist_{fidx}_filename
3133
+ if strlen(fname) > 50
3134
+ let fname = fnamemodify(fname, ':t')
3135
+ endif
3136
+ echo fname . ', Filetype=' . s:tlist_{fidx}_filetype .
3137
+ \ ', Tag count=' . s:tlist_{fidx}_tag_count
3138
+ return
3139
+ endif
3140
+
3141
+ " Get the tag output line for the current tag
3142
+ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum)
3143
+ if tidx == 0
3144
+ " Cursor is on a tag type
3145
+ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum)
3146
+ if ttype == ''
3147
+ return
3148
+ endif
3149
+
3150
+ let ttype_name = ''
3151
+
3152
+ let ftype = s:tlist_{fidx}_filetype
3153
+ let i = 1
3154
+ while i <= s:tlist_{ftype}_count
3155
+ if ttype == s:tlist_{ftype}_{i}_name
3156
+ let ttype_name = s:tlist_{ftype}_{i}_fullname
3157
+ break
3158
+ endif
3159
+ let i = i + 1
3160
+ endwhile
3161
+
3162
+ echo 'Tag type=' . ttype_name .
3163
+ \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count
3164
+ return
3165
+ endif
3166
+
3167
+ " Get the tag search pattern and display it
3168
+ echo s:Tlist_Get_Tag_Prototype(fidx, tidx)
3169
+ endfunction
3170
+
3171
+ " Tlist_Find_Nearest_Tag_Idx
3172
+ " Find the tag idx nearest to the supplied line number
3173
+ " Returns -1, if a tag couldn't be found for the specified line number
3174
+ function! s:Tlist_Find_Nearest_Tag_Idx(fidx, linenum)
3175
+ let sort_type = s:tlist_{a:fidx}_sort_type
3176
+
3177
+ let left = 1
3178
+ let right = s:tlist_{a:fidx}_tag_count
3179
+
3180
+ if sort_type == 'order'
3181
+ " Tag list sorted by order, do a binary search comparing the line
3182
+ " numbers and pick a tag entry that contains the current line and
3183
+ " highlight it. The idea behind this function is taken from the
3184
+ " ctags.vim script (by Alexey Marinichev) available at the Vim online
3185
+ " website.
3186
+
3187
+ " If the current line is the less than the first tag, then no need to
3188
+ " search
3189
+ let first_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, 1)
3190
+
3191
+ if a:linenum < first_lnum
3192
+ return -1
3193
+ endif
3194
+
3195
+ while left < right
3196
+ let middle = (right + left + 1) / 2
3197
+ let middle_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, middle)
3198
+
3199
+ if middle_lnum == a:linenum
3200
+ let left = middle
3201
+ break
3202
+ endif
3203
+
3204
+ if middle_lnum > a:linenum
3205
+ let right = middle - 1
3206
+ else
3207
+ let left = middle
3208
+ endif
3209
+ endwhile
3210
+ else
3211
+ " sorted by name, brute force method (Dave Eggum)
3212
+ let closest_lnum = 0
3213
+ let final_left = 0
3214
+ while left <= right
3215
+ let lnum = s:Tlist_Get_Tag_Linenum(a:fidx, left)
3216
+
3217
+ if lnum < a:linenum && lnum > closest_lnum
3218
+ let closest_lnum = lnum
3219
+ let final_left = left
3220
+ elseif lnum == a:linenum
3221
+ let closest_lnum = lnum
3222
+ let final_left = left
3223
+ break
3224
+ else
3225
+ let left = left + 1
3226
+ endif
3227
+ endwhile
3228
+ if closest_lnum == 0
3229
+ return -1
3230
+ endif
3231
+ if left >= right
3232
+ let left = final_left
3233
+ endif
3234
+ endif
3235
+
3236
+ return left
3237
+ endfunction
3238
+
3239
+ " Tlist_Window_Highlight_Tag()
3240
+ " Highlight the current tag
3241
+ " cntx == 1, Called by the taglist plugin itself
3242
+ " cntx == 2, Forced by the user through the TlistHighlightTag command
3243
+ " center = 1, move the tag line to the center of the taglist window
3244
+ function! s:Tlist_Window_Highlight_Tag(filename, cur_lnum, cntx, center)
3245
+ " Highlight the current tag only if the user configured the
3246
+ " taglist plugin to do so or if the user explictly invoked the
3247
+ " command to highlight the current tag.
3248
+ if !g:Tlist_Auto_Highlight_Tag && a:cntx == 1
3249
+ return
3250
+ endif
3251
+
3252
+ if a:filename == ''
3253
+ return
3254
+ endif
3255
+
3256
+ " Make sure the taglist window is present
3257
+ let winnum = bufwinnr(g:TagList_title)
3258
+ if winnum == -1
3259
+ call s:Tlist_Warning_Msg('Error: Taglist window is not open')
3260
+ return
3261
+ endif
3262
+
3263
+ let fidx = s:Tlist_Get_File_Index(a:filename)
3264
+ if fidx == -1
3265
+ return
3266
+ endif
3267
+
3268
+ " If the file is currently not displayed in the taglist window, then retrn
3269
+ if !s:tlist_{fidx}_visible
3270
+ return
3271
+ endif
3272
+
3273
+ " If there are no tags for this file, then no need to proceed further
3274
+ if s:tlist_{fidx}_tag_count == 0
3275
+ return
3276
+ endif
3277
+
3278
+ " Ignore all autocommands
3279
+ let old_ei = &eventignore
3280
+ set eventignore=all
3281
+
3282
+ " Save the original window number
3283
+ let org_winnr = winnr()
3284
+
3285
+ if org_winnr == winnum
3286
+ let in_taglist_window = 1
3287
+ else
3288
+ let in_taglist_window = 0
3289
+ endif
3290
+
3291
+ " Go to the taglist window
3292
+ if !in_taglist_window
3293
+ exe winnum . 'wincmd w'
3294
+ endif
3295
+
3296
+ " Clear previously selected name
3297
+ match none
3298
+
3299
+ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, a:cur_lnum)
3300
+ if tidx == -1
3301
+ " Make sure the current tag line is visible in the taglist window.
3302
+ " Calling the winline() function makes the line visible. Don't know
3303
+ " of a better way to achieve this.
3304
+ let lnum = line('.')
3305
+
3306
+ if lnum < s:tlist_{fidx}_start || lnum > s:tlist_{fidx}_end
3307
+ " Move the cursor to the beginning of the file
3308
+ exe s:tlist_{fidx}_start
3309
+ endif
3310
+
3311
+ if foldclosed('.') != -1
3312
+ .foldopen
3313
+ endif
3314
+
3315
+ call winline()
3316
+
3317
+ if !in_taglist_window
3318
+ exe org_winnr . 'wincmd w'
3319
+ endif
3320
+
3321
+ " Restore the autocommands
3322
+ let &eventignore = old_ei
3323
+ return
3324
+ endif
3325
+
3326
+ " Extract the tag type
3327
+ let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx)
3328
+
3329
+ " Compute the line number
3330
+ " Start of file + Start of tag type + offset
3331
+ let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset +
3332
+ \ s:tlist_{fidx}_{tidx}_ttype_idx
3333
+
3334
+ " Goto the line containing the tag
3335
+ exe lnum
3336
+
3337
+ " Open the fold
3338
+ if foldclosed('.') != -1
3339
+ .foldopen
3340
+ endif
3341
+
3342
+ if a:center
3343
+ " Move the tag line to the center of the taglist window
3344
+ normal! z.
3345
+ else
3346
+ " Make sure the current tag line is visible in the taglist window.
3347
+ " Calling the winline() function makes the line visible. Don't know
3348
+ " of a better way to achieve this.
3349
+ call winline()
3350
+ endif
3351
+
3352
+ " Highlight the tag name
3353
+ call s:Tlist_Window_Highlight_Line()
3354
+
3355
+ " Go back to the original window
3356
+ if !in_taglist_window
3357
+ exe org_winnr . 'wincmd w'
3358
+ endif
3359
+
3360
+ " Restore the autocommands
3361
+ let &eventignore = old_ei
3362
+ return
3363
+ endfunction
3364
+
3365
+ " Tlist_Get_Tag_Prototype_By_Line
3366
+ " Get the prototype for the tag on or before the specified line number in the
3367
+ " current buffer
3368
+ function! Tlist_Get_Tag_Prototype_By_Line(...)
3369
+ if a:0 == 0
3370
+ " Arguments are not supplied. Use the current buffer name
3371
+ " and line number
3372
+ let filename = bufname('%')
3373
+ let linenr = line('.')
3374
+ elseif a:0 == 2
3375
+ " Filename and line number are specified
3376
+ let filename = a:1
3377
+ let linenr = a:2
3378
+ if linenr !~ '\d\+'
3379
+ " Invalid line number
3380
+ return ""
3381
+ endif
3382
+ else
3383
+ " Sufficient arguments are not supplied
3384
+ let msg = 'Usage: Tlist_Get_Tag_Prototype_By_Line <filename> ' .
3385
+ \ '<line_number>'
3386
+ call s:Tlist_Warning_Msg(msg)
3387
+ return ""
3388
+ endif
3389
+
3390
+ " Expand the file to a fully qualified name
3391
+ let filename = fnamemodify(filename, ':p')
3392
+ if filename == ''
3393
+ return ""
3394
+ endif
3395
+
3396
+ let fidx = s:Tlist_Get_File_Index(filename)
3397
+ if fidx == -1
3398
+ return ""
3399
+ endif
3400
+
3401
+ " If there are no tags for this file, then no need to proceed further
3402
+ if s:tlist_{fidx}_tag_count == 0
3403
+ return ""
3404
+ endif
3405
+
3406
+ " Get the tag text using the line number
3407
+ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr)
3408
+ if tidx == -1
3409
+ return ""
3410
+ endif
3411
+
3412
+ return s:Tlist_Get_Tag_Prototype(fidx, tidx)
3413
+ endfunction
3414
+
3415
+ " Tlist_Get_Tagname_By_Line
3416
+ " Get the tag name on or before the specified line number in the
3417
+ " current buffer
3418
+ function! Tlist_Get_Tagname_By_Line(...)
3419
+ if a:0 == 0
3420
+ " Arguments are not supplied. Use the current buffer name
3421
+ " and line number
3422
+ let filename = bufname('%')
3423
+ let linenr = line('.')
3424
+ elseif a:0 == 2
3425
+ " Filename and line number are specified
3426
+ let filename = a:1
3427
+ let linenr = a:2
3428
+ if linenr !~ '\d\+'
3429
+ " Invalid line number
3430
+ return ""
3431
+ endif
3432
+ else
3433
+ " Sufficient arguments are not supplied
3434
+ let msg = 'Usage: Tlist_Get_Tagname_By_Line <filename> <line_number>'
3435
+ call s:Tlist_Warning_Msg(msg)
3436
+ return ""
3437
+ endif
3438
+
3439
+ " Make sure the current file has a name
3440
+ let filename = fnamemodify(filename, ':p')
3441
+ if filename == ''
3442
+ return ""
3443
+ endif
3444
+
3445
+ let fidx = s:Tlist_Get_File_Index(filename)
3446
+ if fidx == -1
3447
+ return ""
3448
+ endif
3449
+
3450
+ " If there are no tags for this file, then no need to proceed further
3451
+ if s:tlist_{fidx}_tag_count == 0
3452
+ return ""
3453
+ endif
3454
+
3455
+ " Get the tag name using the line number
3456
+ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr)
3457
+ if tidx == -1
3458
+ return ""
3459
+ endif
3460
+
3461
+ return s:tlist_{fidx}_{tidx}_tag_name
3462
+ endfunction
3463
+
3464
+ " Tlist_Window_Move_To_File
3465
+ " Move the cursor to the beginning of the current file or the next file
3466
+ " or the previous file in the taglist window
3467
+ " dir == -1, move to start of current or previous function
3468
+ " dir == 1, move to start of next function
3469
+ function! s:Tlist_Window_Move_To_File(dir)
3470
+ if foldlevel('.') == 0
3471
+ " Cursor is on a non-folded line (it is not in any of the files)
3472
+ " Move it to a folded line
3473
+ if a:dir == -1
3474
+ normal! zk
3475
+ else
3476
+ " While moving down to the start of the next fold,
3477
+ " no need to do go to the start of the next file.
3478
+ normal! zj
3479
+ return
3480
+ endif
3481
+ endif
3482
+
3483
+ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.'))
3484
+ if fidx == -1
3485
+ return
3486
+ endif
3487
+
3488
+ let cur_lnum = line('.')
3489
+
3490
+ if a:dir == -1
3491
+ if cur_lnum > s:tlist_{fidx}_start
3492
+ " Move to the beginning of the current file
3493
+ exe s:tlist_{fidx}_start
3494
+ return
3495
+ endif
3496
+
3497
+ if fidx != 0
3498
+ " Move to the beginning of the previous file
3499
+ let fidx = fidx - 1
3500
+ else
3501
+ " Cursor is at the first file, wrap around to the last file
3502
+ let fidx = s:tlist_file_count - 1
3503
+ endif
3504
+
3505
+ exe s:tlist_{fidx}_start
3506
+ return
3507
+ else
3508
+ " Move to the beginning of the next file
3509
+ let fidx = fidx + 1
3510
+
3511
+ if fidx >= s:tlist_file_count
3512
+ " Cursor is at the last file, wrap around to the first file
3513
+ let fidx = 0
3514
+ endif
3515
+
3516
+ if s:tlist_{fidx}_start != 0
3517
+ exe s:tlist_{fidx}_start
3518
+ endif
3519
+ return
3520
+ endif
3521
+ endfunction
3522
+
3523
+ " Tlist_Session_Load
3524
+ " Load a taglist session (information about all the displayed files
3525
+ " and the tags) from the specified file
3526
+ function! s:Tlist_Session_Load(...)
3527
+ if a:0 == 0 || a:1 == ''
3528
+ call s:Tlist_Warning_Msg('Usage: TlistSessionLoad <filename>')
3529
+ return
3530
+ endif
3531
+
3532
+ let sessionfile = a:1
3533
+
3534
+ if !filereadable(sessionfile)
3535
+ let msg = 'Taglist: Error - Unable to open file ' . sessionfile
3536
+ call s:Tlist_Warning_Msg(msg)
3537
+ return
3538
+ endif
3539
+
3540
+ " Mark the current window as the file window
3541
+ if bufname('%') !~ g:TagList_title
3542
+ let w:tlist_file_window = "yes"
3543
+ endif
3544
+
3545
+ " Source the session file
3546
+ exe 'source ' . sessionfile
3547
+
3548
+ let new_file_count = g:tlist_file_count
3549
+ unlet! g:tlist_file_count
3550
+
3551
+ let i = 0
3552
+ while i < new_file_count
3553
+ let ftype = g:tlist_{i}_filetype
3554
+ unlet! g:tlist_{i}_filetype
3555
+
3556
+ if !exists('s:tlist_' . ftype . '_count')
3557
+ if s:Tlist_FileType_Init(ftype) == 0
3558
+ let i = i + 1
3559
+ continue
3560
+ endif
3561
+ endif
3562
+
3563
+ let fname = g:tlist_{i}_filename
3564
+ unlet! g:tlist_{i}_filename
3565
+
3566
+ let fidx = s:Tlist_Get_File_Index(fname)
3567
+ if fidx != -1
3568
+ let s:tlist_{fidx}_visible = 0
3569
+ let i = i + 1
3570
+ continue
3571
+ else
3572
+ " As we are loading the tags from the session file, if this
3573
+ " file was previously deleted by the user, now we need to
3574
+ " add it back. So remove the file from the deleted list.
3575
+ call s:Tlist_Update_Remove_List(fname, 0)
3576
+ endif
3577
+
3578
+ let fidx = s:Tlist_Init_File(fname, ftype)
3579
+
3580
+ let s:tlist_{fidx}_filename = fname
3581
+
3582
+ let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type
3583
+ unlet! g:tlist_{i}_sort_type
3584
+
3585
+ let s:tlist_{fidx}_filetype = ftype
3586
+ let s:tlist_{fidx}_mtime = getftime(fname)
3587
+
3588
+ let s:tlist_{fidx}_start = 0
3589
+ let s:tlist_{fidx}_end = 0
3590
+
3591
+ let s:tlist_{fidx}_valid = 1
3592
+
3593
+ let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count
3594
+ unlet! g:tlist_{i}_tag_count
3595
+
3596
+ let j = 1
3597
+ while j <= s:tlist_{fidx}_tag_count
3598
+ let s:tlist_{fidx}_{j}_tag = g:tlist_{i}_{j}_tag
3599
+ let s:tlist_{fidx}_{j}_tag_name = g:tlist_{i}_{j}_tag_name
3600
+ let s:tlist_{fidx}_{j}_ttype_idx = g:tlist_{i}_{j}_ttype_idx
3601
+ unlet! g:tlist_{i}_{j}_tag
3602
+ unlet! g:tlist_{i}_{j}_tag_name
3603
+ unlet! g:tlist_{i}_{j}_ttype_idx
3604
+ let j = j + 1
3605
+ endwhile
3606
+
3607
+ let j = 1
3608
+ while j <= s:tlist_{ftype}_count
3609
+ let ttype = s:tlist_{ftype}_{j}_name
3610
+
3611
+ if exists('g:tlist_' . i . '_' . ttype)
3612
+ let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype}
3613
+ unlet! g:tlist_{i}_{ttype}
3614
+ let s:tlist_{fidx}_{ttype}_offset = 0
3615
+ let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count
3616
+ unlet! g:tlist_{i}_{ttype}_count
3617
+
3618
+ let k = 1
3619
+ while k <= s:tlist_{fidx}_{ttype}_count
3620
+ let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k}
3621
+ unlet! g:tlist_{i}_{ttype}_{k}
3622
+ let k = k + 1
3623
+ endwhile
3624
+ else
3625
+ let s:tlist_{fidx}_{ttype} = ''
3626
+ let s:tlist_{fidx}_{ttype}_offset = 0
3627
+ let s:tlist_{fidx}_{ttype}_count = 0
3628
+ endif
3629
+
3630
+ let j = j + 1
3631
+ endwhile
3632
+
3633
+ let i = i + 1
3634
+ endwhile
3635
+
3636
+ " If the taglist window is open, then update it
3637
+ let winnum = bufwinnr(g:TagList_title)
3638
+ if winnum != -1
3639
+ let save_winnr = winnr()
3640
+
3641
+ " Goto the taglist window
3642
+ call s:Tlist_Window_Goto_Window()
3643
+
3644
+ " Refresh the taglist window
3645
+ call s:Tlist_Window_Refresh()
3646
+
3647
+ " Go back to the original window
3648
+ if save_winnr != winnr()
3649
+ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p')
3650
+ endif
3651
+ endif
3652
+ endfunction
3653
+
3654
+ " Tlist_Session_Save
3655
+ " Save a taglist session (information about all the displayed files
3656
+ " and the tags) into the specified file
3657
+ function! s:Tlist_Session_Save(...)
3658
+ if a:0 == 0 || a:1 == ''
3659
+ call s:Tlist_Warning_Msg('Usage: TlistSessionSave <filename>')
3660
+ return
3661
+ endif
3662
+
3663
+ let sessionfile = a:1
3664
+
3665
+ if s:tlist_file_count == 0
3666
+ " There is nothing to save
3667
+ call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.')
3668
+ return
3669
+ endif
3670
+
3671
+ if filereadable(sessionfile)
3672
+ let ans = input('Do you want to overwrite ' . sessionfile . ' (Y/N)?')
3673
+ if ans !=? 'y'
3674
+ return
3675
+ endif
3676
+
3677
+ echo "\n"
3678
+ endif
3679
+
3680
+ let old_verbose = &verbose
3681
+ set verbose&vim
3682
+
3683
+ exe 'redir! > ' . sessionfile
3684
+
3685
+ silent! echo '" Taglist session file. This file is auto-generated.'
3686
+ silent! echo '" File information'
3687
+ silent! echo 'let tlist_file_count = ' . s:tlist_file_count
3688
+
3689
+ let i = 0
3690
+
3691
+ while i < s:tlist_file_count
3692
+ " Store information about the file
3693
+ silent! echo 'let tlist_' . i . "_filename = '" .
3694
+ \ s:tlist_{i}_filename . "'"
3695
+ silent! echo 'let tlist_' . i . '_sort_type = "' .
3696
+ \ s:tlist_{i}_sort_type . '"'
3697
+ silent! echo 'let tlist_' . i . '_filetype = "' .
3698
+ \ s:tlist_{i}_filetype . '"'
3699
+ silent! echo 'let tlist_' . i . '_tag_count = ' .
3700
+ \ s:tlist_{i}_tag_count
3701
+ " Store information about all the tags
3702
+ let j = 1
3703
+ while j <= s:tlist_{i}_tag_count
3704
+ let txt = escape(s:tlist_{i}_{j}_tag, '"\\')
3705
+ silent! echo 'let tlist_' . i . '_' . j . '_tag = "' . txt . '"'
3706
+ silent! echo 'let tlist_' . i . '_' . j . '_tag_name = "' .
3707
+ \ s:tlist_{i}_{j}_tag_name . '"'
3708
+ silent! echo 'let tlist_' . i . '_' . j . '_ttype_idx' . ' = ' .
3709
+ \ s:tlist_{i}_{j}_ttype_idx
3710
+ let j = j + 1
3711
+ endwhile
3712
+
3713
+ " Store information about all the tags grouped by their type
3714
+ let ftype = s:tlist_{i}_filetype
3715
+ let j = 1
3716
+ while j <= s:tlist_{ftype}_count
3717
+ let ttype = s:tlist_{ftype}_{j}_name
3718
+ if s:tlist_{i}_{ttype}_count != 0
3719
+ let txt = substitute(s:tlist_{i}_{ttype}, "\n", "\\\\n", 'g')
3720
+ silent! echo 'let tlist_' . i . '_' . ttype . ' = "' .
3721
+ \ txt . '"'
3722
+ silent! echo 'let tlist_' . i . '_' . ttype . '_count = ' .
3723
+ \ s:tlist_{i}_{ttype}_count
3724
+ let k = 1
3725
+ while k <= s:tlist_{i}_{ttype}_count
3726
+ silent! echo 'let tlist_' . i . '_' . ttype . '_' . k .
3727
+ \ ' = ' . s:tlist_{i}_{ttype}_{k}
3728
+ let k = k + 1
3729
+ endwhile
3730
+ endif
3731
+ let j = j + 1
3732
+ endwhile
3733
+
3734
+ silent! echo
3735
+
3736
+ let i = i + 1
3737
+ endwhile
3738
+
3739
+ redir END
3740
+
3741
+ let &verbose = old_verbose
3742
+ endfunction
3743
+
3744
+ " Tlist_Buffer_Removed
3745
+ " A buffer is removed from the Vim buffer list. Remove the tags defined
3746
+ " for that file
3747
+ function! s:Tlist_Buffer_Removed(filename)
3748
+ call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename . ')')
3749
+
3750
+ " Make sure a valid filename is supplied
3751
+ if a:filename == ''
3752
+ return
3753
+ endif
3754
+
3755
+ " Get tag list index of the specified file
3756
+ let fidx = s:Tlist_Get_File_Index(a:filename)
3757
+ if fidx == -1
3758
+ " File not present in the taglist
3759
+ return
3760
+ endif
3761
+
3762
+ " Remove the file from the list
3763
+ call s:Tlist_Remove_File(fidx, 0)
3764
+ endfunction
3765
+
3766
+ " When a buffer is deleted, remove the file from the taglist
3767
+ autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand('<afile>:p'))
3768
+
3769
+ " Tlist_Window_Close_File_Fold
3770
+ " Close the fold for the specified file
3771
+ function! s:Tlist_Window_Close_File_Fold(filename)
3772
+ call s:Tlist_Log_Msg('Tlist_Window_Close_File_Fold (' . a:filename . ')')
3773
+ " Make sure a valid filename is supplied
3774
+ if a:filename == ''
3775
+ return
3776
+ endif
3777
+
3778
+ " Make sure the taglist window is present
3779
+ let winnum = bufwinnr(g:TagList_title)
3780
+ if winnum == -1
3781
+ call s:Tlist_Warning_Msg('Taglist: Error - Taglist window is not open')
3782
+ return
3783
+ endif
3784
+
3785
+ " Get tag list index of the specified file
3786
+ let fidx = s:Tlist_Get_File_Index(a:filename)
3787
+ if fidx == -1
3788
+ " File not present in the taglist window
3789
+ return
3790
+ endif
3791
+
3792
+ " Save the original window number
3793
+ let org_winnr = winnr()
3794
+ if org_winnr == winnum
3795
+ let in_taglist_window = 1
3796
+ else
3797
+ let in_taglist_window = 0
3798
+ endif
3799
+
3800
+ " Go to the taglist window
3801
+ if !in_taglist_window
3802
+ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w')
3803
+ endif
3804
+
3805
+ " Save the cursor position
3806
+ let save_lnum = line('.')
3807
+
3808
+ " Perform the requested action on the file
3809
+ " Close the fold for the file
3810
+ exe "silent! " . s:tlist_{fidx}_start . "," .
3811
+ \ s:tlist_{fidx}_end . "foldclose"
3812
+
3813
+ " Move the cursor to the original location
3814
+ exe save_lnum
3815
+
3816
+ " Go back to the original window
3817
+ if !in_taglist_window
3818
+ call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w')
3819
+ endif
3820
+ endfunction
3821
+
3822
+ " Tlist_Window_Check_Auto_Open
3823
+ " Open the taglist window automatically on Vim startup.
3824
+ " Open the window only when files present in any of the Vim windows support
3825
+ " tags.
3826
+ function! s:Tlist_Window_Check_Auto_Open()
3827
+ let open = 0
3828
+
3829
+ let i = 1
3830
+ let buf_num = winbufnr(i)
3831
+ while buf_num != -1
3832
+ let filename = fnamemodify(bufname(buf_num), ':p')
3833
+ if !s:Tlist_Skip_File(filename, getbufvar(buf_num, '&filetype'))
3834
+ let open = 1
3835
+ break
3836
+ endif
3837
+ let i = i + 1
3838
+ let buf_num = winbufnr(i)
3839
+ endwhile
3840
+
3841
+ if open
3842
+ call s:Tlist_Window_Toggle()
3843
+ endif
3844
+ endfunction
3845
+
3846
+ function! s:Tlist_Menu_Add_Base_Menu()
3847
+ call s:Tlist_Log_Msg('Adding the base menu')
3848
+
3849
+ " Add the menu
3850
+ anoremenu <silent> T&ags.Refresh\ menu :call <SID>Tlist_Menu_Refresh()<CR>
3851
+ anoremenu <silent> T&ags.Sort\ menu\ by.Name
3852
+ \ :call <SID>Tlist_Change_Sort(2, 2, 'name')<CR>
3853
+ anoremenu <silent> T&ags.Sort\ menu\ by.Order
3854
+ \ :call <SID>Tlist_Change_Sort(2, 2, 'order')<CR>
3855
+ anoremenu T&ags.-SEP1- :
3856
+
3857
+ if &mousemodel =~ 'popup'
3858
+ anoremenu <silent> PopUp.T&ags.Refresh\ menu
3859
+ \ :call <SID>Tlist_Menu_Refresh()<CR>
3860
+ anoremenu <silent> PopUp.T&ags.Sort\ menu\ by.Name
3861
+ \ :call <SID>Tlist_Change_Sort(2, 2, 'name')<CR>
3862
+ anoremenu <silent> PopUp.T&ags.Sort\ menu\ by.Order
3863
+ \ :call <SID>Tlist_Change_Sort(2, 2, 'order')<CR>
3864
+ anoremenu PopUp.T&ags.-SEP1- :
3865
+ endif
3866
+ endfunction
3867
+
3868
+ let s:menu_char_prefix =
3869
+ \ '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
3870
+
3871
+ " Tlist_Menu_Get_Tag_Type_Cmd
3872
+ " Get the menu command for the specified tag type
3873
+ " fidx - File type index
3874
+ " ftype - File Type
3875
+ " add_ttype_name - To add or not to add the tag type name to the menu entries
3876
+ " ttype_idx - Tag type index
3877
+ function! s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, ttype_idx)
3878
+ " Curly brace variable name optimization
3879
+ let ftype_ttype_idx = a:ftype . '_' . a:ttype_idx
3880
+
3881
+ let ttype = s:tlist_{ftype_ttype_idx}_name
3882
+ if a:add_ttype_name
3883
+ " If the tag type name contains space characters, escape it. This
3884
+ " will be used to create the menu entries.
3885
+ let ttype_fullname = escape(s:tlist_{ftype_ttype_idx}_fullname, ' ')
3886
+ endif
3887
+
3888
+ " Curly brace variable name optimization
3889
+ let fidx_ttype = a:fidx . '_' . ttype
3890
+
3891
+ " Number of tag entries for this tag type
3892
+ let tcnt = s:tlist_{fidx_ttype}_count
3893
+ if tcnt == 0 " No entries for this tag type
3894
+ return ''
3895
+ endif
3896
+
3897
+ let mcmd = ''
3898
+
3899
+ " Create the menu items for the tags.
3900
+ " Depending on the number of tags of this type, split the menu into
3901
+ " multiple sub-menus, if needed.
3902
+ if tcnt > g:Tlist_Max_Submenu_Items
3903
+ let j = 1
3904
+ while j <= tcnt
3905
+ let final_index = j + g:Tlist_Max_Submenu_Items - 1
3906
+ if final_index > tcnt
3907
+ let final_index = tcnt
3908
+ endif
3909
+
3910
+ " Extract the first and last tag name and form the
3911
+ " sub-menu name
3912
+ let tidx = s:tlist_{fidx_ttype}_{j}
3913
+ let first_tag = s:tlist_{a:fidx}_{tidx}_tag_name
3914
+
3915
+ let tidx = s:tlist_{fidx_ttype}_{final_index}
3916
+ let last_tag = s:tlist_{a:fidx}_{tidx}_tag_name
3917
+
3918
+ " Truncate the names, if they are greater than the
3919
+ " max length
3920
+ let first_tag = strpart(first_tag, 0, g:Tlist_Max_Tag_Length)
3921
+ let last_tag = strpart(last_tag, 0, g:Tlist_Max_Tag_Length)
3922
+
3923
+ " Form the menu command prefix
3924
+ let m_prefix = 'anoremenu <silent> T\&ags.'
3925
+ if a:add_ttype_name
3926
+ let m_prefix = m_prefix . ttype_fullname . '.'
3927
+ endif
3928
+ let m_prefix = m_prefix . first_tag . '\.\.\.' . last_tag . '.'
3929
+
3930
+ " Character prefix used to number the menu items (hotkey)
3931
+ let m_prefix_idx = 0
3932
+
3933
+ while j <= final_index
3934
+ let tidx = s:tlist_{fidx_ttype}_{j}
3935
+
3936
+ let tname = s:tlist_{a:fidx}_{tidx}_tag_name
3937
+
3938
+ let mcmd = mcmd . m_prefix . '\&' .
3939
+ \ s:menu_char_prefix[m_prefix_idx] . '\.' .
3940
+ \ tname . ' :call <SID>Tlist_Menu_Jump_To_Tag(' .
3941
+ \ tidx . ')<CR>|'
3942
+
3943
+ let m_prefix_idx = m_prefix_idx + 1
3944
+ let j = j + 1
3945
+ endwhile
3946
+ endwhile
3947
+ else
3948
+ " Character prefix used to number the menu items (hotkey)
3949
+ let m_prefix_idx = 0
3950
+
3951
+ let m_prefix = 'anoremenu <silent> T\&ags.'
3952
+ if a:add_ttype_name
3953
+ let m_prefix = m_prefix . ttype_fullname . '.'
3954
+ endif
3955
+ let j = 1
3956
+ while j <= tcnt
3957
+ let tidx = s:tlist_{fidx_ttype}_{j}
3958
+
3959
+ let tname = s:tlist_{a:fidx}_{tidx}_tag_name
3960
+
3961
+ let mcmd = mcmd . m_prefix . '\&' .
3962
+ \ s:menu_char_prefix[m_prefix_idx] . '\.' .
3963
+ \ tname . ' :call <SID>Tlist_Menu_Jump_To_Tag(' . tidx
3964
+ \ . ')<CR>|'
3965
+
3966
+ let m_prefix_idx = m_prefix_idx + 1
3967
+ let j = j + 1
3968
+ endwhile
3969
+ endif
3970
+
3971
+ return mcmd
3972
+ endfunction
3973
+
3974
+ " Update the taglist menu with the tags for the specified file
3975
+ function! s:Tlist_Menu_File_Refresh(fidx)
3976
+ call s:Tlist_Log_Msg('Refreshing the tag menu for ' . s:tlist_{a:fidx}_filename)
3977
+ " The 'B' flag is needed in the 'cpoptions' option
3978
+ let old_cpoptions = &cpoptions
3979
+ set cpoptions&vim
3980
+
3981
+ exe s:tlist_{a:fidx}_menu_cmd
3982
+
3983
+ " Update the popup menu (if enabled)
3984
+ if &mousemodel =~ 'popup'
3985
+ let cmd = substitute(s:tlist_{a:fidx}_menu_cmd, ' T\\&ags\.',
3986
+ \ ' PopUp.T\\\&ags.', "g")
3987
+ exe cmd
3988
+ endif
3989
+
3990
+ " The taglist menu is not empty now
3991
+ let s:tlist_menu_empty = 0
3992
+
3993
+ " Restore the 'cpoptions' settings
3994
+ let &cpoptions = old_cpoptions
3995
+ endfunction
3996
+
3997
+ " Tlist_Menu_Update_File
3998
+ " Add the taglist menu
3999
+ function! s:Tlist_Menu_Update_File(clear_menu)
4000
+ if !has('gui_running')
4001
+ " Not running in GUI mode
4002
+ return
4003
+ endif
4004
+
4005
+ call s:Tlist_Log_Msg('Updating the tag menu, clear_menu = ' . a:clear_menu)
4006
+
4007
+ " Remove the tags menu
4008
+ if a:clear_menu
4009
+ call s:Tlist_Menu_Remove_File()
4010
+ endif
4011
+
4012
+ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help
4013
+ if &buftype != ''
4014
+ return
4015
+ endif
4016
+
4017
+ let filename = fnamemodify(bufname('%'), ':p')
4018
+ let ftype = &filetype
4019
+
4020
+ " If the file doesn't support tag listing, skip it
4021
+ if s:Tlist_Skip_File(filename, ftype)
4022
+ return
4023
+ endif
4024
+
4025
+ let fidx = s:Tlist_Get_File_Index(filename)
4026
+ if fidx == -1 || !s:tlist_{fidx}_valid
4027
+ " Check whether this file is removed based on user request
4028
+ " If it is, then don't display the tags for this file
4029
+ if s:Tlist_User_Removed_File(filename)
4030
+ return
4031
+ endif
4032
+
4033
+ " Process the tags for the file
4034
+ let fidx = s:Tlist_Process_File(filename, ftype)
4035
+ if fidx == -1
4036
+ return
4037
+ endif
4038
+ endif
4039
+
4040
+ if !s:tlist_{fidx}_tag_count
4041
+ return
4042
+ endif
4043
+
4044
+ if s:tlist_{fidx}_menu_cmd != ''
4045
+ " Update the menu with the cached command
4046
+ call s:Tlist_Menu_File_Refresh(fidx)
4047
+
4048
+ return
4049
+ endif
4050
+
4051
+ " We are going to add entries to the tags menu, so the menu won't be
4052
+ " empty
4053
+ let s:tlist_menu_empty = 0
4054
+
4055
+ let cmd = ''
4056
+
4057
+ " Determine whether the tag type name needs to be added to the menu
4058
+ " If more than one tag type is present in the taglisting for a file,
4059
+ " then the tag type name needs to be present
4060
+ let add_ttype_name = -1
4061
+ let i = 1
4062
+ while i <= s:tlist_{ftype}_count && add_ttype_name < 1
4063
+ let ttype = s:tlist_{ftype}_{i}_name
4064
+ if s:tlist_{fidx}_{ttype}_count
4065
+ let add_ttype_name = add_ttype_name + 1
4066
+ endif
4067
+ let i = i + 1
4068
+ endwhile
4069
+
4070
+ " Process the tags by the tag type and get the menu command
4071
+ let i = 1
4072
+ while i <= s:tlist_{ftype}_count
4073
+ let mcmd = s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, i)
4074
+ if mcmd != ''
4075
+ let cmd = cmd . mcmd
4076
+ endif
4077
+
4078
+ let i = i + 1
4079
+ endwhile
4080
+
4081
+ " Cache the menu command for reuse
4082
+ let s:tlist_{fidx}_menu_cmd = cmd
4083
+
4084
+ " Update the menu
4085
+ call s:Tlist_Menu_File_Refresh(fidx)
4086
+ endfunction
4087
+
4088
+ " Tlist_Menu_Remove_File
4089
+ " Remove the tags displayed in the tags menu
4090
+ function! s:Tlist_Menu_Remove_File()
4091
+ if !has('gui_running') || s:tlist_menu_empty
4092
+ return
4093
+ endif
4094
+
4095
+ call s:Tlist_Log_Msg('Removing the tags menu for a file')
4096
+
4097
+ " Cleanup the Tags menu
4098
+ silent! unmenu T&ags
4099
+ if &mousemodel =~ 'popup'
4100
+ silent! unmenu PopUp.T&ags
4101
+ endif
4102
+
4103
+ " Add a dummy menu item to retain teared off menu
4104
+ noremenu T&ags.Dummy l
4105
+
4106
+ silent! unmenu! T&ags
4107
+ if &mousemodel =~ 'popup'
4108
+ silent! unmenu! PopUp.T&ags
4109
+ endif
4110
+
4111
+ call s:Tlist_Menu_Add_Base_Menu()
4112
+
4113
+ " Remove the dummy menu item
4114
+ unmenu T&ags.Dummy
4115
+
4116
+ let s:tlist_menu_empty = 1
4117
+ endfunction
4118
+
4119
+ " Tlist_Menu_Refresh
4120
+ " Refresh the taglist menu
4121
+ function! s:Tlist_Menu_Refresh()
4122
+ call s:Tlist_Log_Msg('Refreshing the tags menu')
4123
+ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
4124
+ if fidx != -1
4125
+ " Invalidate the cached menu command
4126
+ let s:tlist_{fidx}_menu_cmd = ''
4127
+ endif
4128
+
4129
+ " Update the taglist, menu and window
4130
+ call s:Tlist_Update_Current_File()
4131
+ endfunction
4132
+
4133
+ " Tlist_Menu_Jump_To_Tag
4134
+ " Jump to the selected tag
4135
+ function! s:Tlist_Menu_Jump_To_Tag(tidx)
4136
+ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p'))
4137
+ if fidx == -1
4138
+ return
4139
+ endif
4140
+
4141
+ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, a:tidx)
4142
+ if tagpat == ''
4143
+ return
4144
+ endif
4145
+
4146
+ " Add the current cursor position to the jump list, so that user can
4147
+ " jump back using the ' and ` marks.
4148
+ mark '
4149
+
4150
+ silent call search(tagpat, 'w')
4151
+
4152
+ " Bring the line to the middle of the window
4153
+ normal! z.
4154
+
4155
+ " If the line is inside a fold, open the fold
4156
+ if foldclosed('.') != -1
4157
+ .foldopen
4158
+ endif
4159
+ endfunction
4160
+
4161
+ " Tlist_Menu_Init
4162
+ " Initialize the taglist menu
4163
+ function! s:Tlist_Menu_Init()
4164
+ call s:Tlist_Menu_Add_Base_Menu()
4165
+
4166
+ " Automatically add the tags defined in the current file to the menu
4167
+ augroup TagListMenuCmds
4168
+ autocmd!
4169
+
4170
+ if !g:Tlist_Process_File_Always
4171
+ autocmd BufEnter * call s:Tlist_Refresh()
4172
+ endif
4173
+ autocmd BufLeave * call s:Tlist_Menu_Remove_File()
4174
+ augroup end
4175
+
4176
+ call s:Tlist_Menu_Update_File(0)
4177
+ endfunction
4178
+
4179
+ " Tlist_Vim_Session_Load
4180
+ " Initialize the taglist window/buffer, which is created when loading
4181
+ " a Vim session file.
4182
+ function! s:Tlist_Vim_Session_Load()
4183
+ call s:Tlist_Log_Msg('Tlist_Vim_Session_Load')
4184
+
4185
+ " Initialize the taglist window
4186
+ call s:Tlist_Window_Init()
4187
+
4188
+ " Refresh the taglist window
4189
+ call s:Tlist_Window_Refresh()
4190
+ endfunction
4191
+
4192
+ " Tlist_Set_App
4193
+ " Set the name of the external plugin/application to which taglist
4194
+ " belongs.
4195
+ " Taglist plugin is part of another plugin like cream or winmanager.
4196
+ function! Tlist_Set_App(name)
4197
+ if a:name == ""
4198
+ return
4199
+ endif
4200
+
4201
+ let s:tlist_app_name = a:name
4202
+ endfunction
4203
+
4204
+ " Winmanager integration
4205
+
4206
+ " Initialization required for integration with winmanager
4207
+ function! TagList_Start()
4208
+ " If current buffer is not taglist buffer, then don't proceed
4209
+ if bufname('%') != '__Tag_List__'
4210
+ return
4211
+ endif
4212
+
4213
+ call Tlist_Set_App('winmanager')
4214
+
4215
+ " Get the current filename from the winmanager plugin
4216
+ let bufnum = WinManagerGetLastEditedFile()
4217
+ if bufnum != -1
4218
+ let filename = fnamemodify(bufname(bufnum), ':p')
4219
+ let ftype = getbufvar(bufnum, '&filetype')
4220
+ endif
4221
+
4222
+ " Initialize the taglist window, if it is not already initialized
4223
+ if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized
4224
+ call s:Tlist_Window_Init()
4225
+ call s:Tlist_Window_Refresh()
4226
+ let s:tlist_window_initialized = 1
4227
+ endif
4228
+
4229
+ " Update the taglist window
4230
+ if bufnum != -1
4231
+ if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update
4232
+ call s:Tlist_Window_Refresh_File(filename, ftype)
4233
+ endif
4234
+ endif
4235
+ endfunction
4236
+
4237
+ function! TagList_IsValid()
4238
+ return 0
4239
+ endfunction
4240
+
4241
+ function! TagList_WrapUp()
4242
+ return 0
4243
+ endfunction
4244
+
4245
+ " restore 'cpo'
4246
+ let &cpo = s:cpo_save
4247
+ unlet s:cpo_save
4248
+