RailsEditor 0.0.23 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+