tomkersten-vixploder 0.1.1 → 0.1.2

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.
Files changed (106) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +105 -0
  3. data/PostInstall.txt +21 -0
  4. data/README.rdoc +131 -0
  5. data/Rakefile +21 -0
  6. data/bin/256colors2.pl +63 -0
  7. data/bin/colortest +365 -0
  8. data/bin/vixplode +10 -0
  9. data/lib/dotfiles/aliases +30 -0
  10. data/lib/dotfiles/gvimrc +20 -0
  11. data/lib/dotfiles/vim/.VimballRecord +2 -0
  12. data/lib/dotfiles/vim/after/ftplugin/actionscript_snippets.vim +9 -0
  13. data/lib/dotfiles/vim/after/ftplugin/aspvbs_snippets.vim +17 -0
  14. data/lib/dotfiles/vim/after/ftplugin/c_snippets.vim +58 -0
  15. data/lib/dotfiles/vim/after/ftplugin/css_snippets.vim +30 -0
  16. data/lib/dotfiles/vim/after/ftplugin/django_model_snippets.vim +61 -0
  17. data/lib/dotfiles/vim/after/ftplugin/django_template_snippets.vim +32 -0
  18. data/lib/dotfiles/vim/after/ftplugin/f-script_snippets.vim +14 -0
  19. data/lib/dotfiles/vim/after/ftplugin/haskell_snippets.vim +9 -0
  20. data/lib/dotfiles/vim/after/ftplugin/html_snippets.vim +57 -0
  21. data/lib/dotfiles/vim/after/ftplugin/java_snippets.vim +52 -0
  22. data/lib/dotfiles/vim/after/ftplugin/javascript_snippets.vim +10 -0
  23. data/lib/dotfiles/vim/after/ftplugin/latex_snippets.vim +13 -0
  24. data/lib/dotfiles/vim/after/ftplugin/logo_snippets.vim +9 -0
  25. data/lib/dotfiles/vim/after/ftplugin/markdown_snippets.vim +10 -0
  26. data/lib/dotfiles/vim/after/ftplugin/movable_type_snippets.vim +14 -0
  27. data/lib/dotfiles/vim/after/ftplugin/objc_snippets.vim +53 -0
  28. data/lib/dotfiles/vim/after/ftplugin/ocaml_snippets.vim +26 -0
  29. data/lib/dotfiles/vim/after/ftplugin/perl_snippets.vim +23 -0
  30. data/lib/dotfiles/vim/after/ftplugin/php_snippets.vim +30 -0
  31. data/lib/dotfiles/vim/after/ftplugin/phpdoc_snippets.vim +19 -0
  32. data/lib/dotfiles/vim/after/ftplugin/propel_snippets.vim +14 -0
  33. data/lib/dotfiles/vim/after/ftplugin/python_snippets.vim +202 -0
  34. data/lib/dotfiles/vim/after/ftplugin/rails_snippets.vim +54 -0
  35. data/lib/dotfiles/vim/after/ftplugin/ruby_snippets.vim +32 -0
  36. data/lib/dotfiles/vim/after/ftplugin/sh_snippets.vim +12 -0
  37. data/lib/dotfiles/vim/after/ftplugin/slate_snippets.vim +19 -0
  38. data/lib/dotfiles/vim/after/ftplugin/smarty_snippets.vim +35 -0
  39. data/lib/dotfiles/vim/after/ftplugin/symfony_snippets.vim +21 -0
  40. data/lib/dotfiles/vim/after/ftplugin/tcl_snippets.vim +14 -0
  41. data/lib/dotfiles/vim/after/ftplugin/template_toolkit_snippets.vim +13 -0
  42. data/lib/dotfiles/vim/after/ftplugin/tex_snippets.vim +13 -0
  43. data/lib/dotfiles/vim/after/ftplugin/xhtml_snippets.vim +48 -0
  44. data/lib/dotfiles/vim/autoload/fakeclip.vim +253 -0
  45. data/lib/dotfiles/vim/autoload/rails.vim +4377 -0
  46. data/lib/dotfiles/vim/autoload/rubycomplete.vim +802 -0
  47. data/lib/dotfiles/vim/colors/inkpot.vim +212 -0
  48. data/lib/dotfiles/vim/colors/ir_black.vim +212 -0
  49. data/lib/dotfiles/vim/colors/ir_black_mod.vim +213 -0
  50. data/lib/dotfiles/vim/colors/railscasts.vim +100 -0
  51. data/lib/dotfiles/vim/colors/rubyblue.vim +74 -0
  52. data/lib/dotfiles/vim/colors/twilight.vim +75 -0
  53. data/lib/dotfiles/vim/colors/twilight2.vim +74 -0
  54. data/lib/dotfiles/vim/colors/wombat256.vim +302 -0
  55. data/lib/dotfiles/vim/compiler/eruby.vim +41 -0
  56. data/lib/dotfiles/vim/compiler/ruby.vim +68 -0
  57. data/lib/dotfiles/vim/compiler/rubyunit.vim +35 -0
  58. data/lib/dotfiles/vim/doc/NERD_tree.txt +1235 -0
  59. data/lib/dotfiles/vim/doc/fakeclip.txt +190 -0
  60. data/lib/dotfiles/vim/doc/matchit.txt +406 -0
  61. data/lib/dotfiles/vim/doc/project.txt +710 -0
  62. data/lib/dotfiles/vim/doc/rails.txt +1123 -0
  63. data/lib/dotfiles/vim/doc/snippets_emu.txt +354 -0
  64. data/lib/dotfiles/vim/doc/surround.txt +218 -0
  65. data/lib/dotfiles/vim/doc/tags +433 -0
  66. data/lib/dotfiles/vim/filetype.vim +13 -0
  67. data/lib/dotfiles/vim/ftdetect/gist.vim +3 -0
  68. data/lib/dotfiles/vim/ftdetect/ruby.vim +14 -0
  69. data/lib/dotfiles/vim/ftplugin/eruby.vim +101 -0
  70. data/lib/dotfiles/vim/ftplugin/ruby.vim +230 -0
  71. data/lib/dotfiles/vim/indent/eruby.vim +73 -0
  72. data/lib/dotfiles/vim/indent/ruby.vim +373 -0
  73. data/lib/dotfiles/vim/plugin/NERD_tree.vim +3536 -0
  74. data/lib/dotfiles/vim/plugin/comments.vim +321 -0
  75. data/lib/dotfiles/vim/plugin/fakeclip.vim +174 -0
  76. data/lib/dotfiles/vim/plugin/fuzzyfinder.vim +1676 -0
  77. data/lib/dotfiles/vim/plugin/fuzzyfinder_textmate.vim +150 -0
  78. data/lib/dotfiles/vim/plugin/gist.vim +241 -0
  79. data/lib/dotfiles/vim/plugin/gitdiff.vim +141 -0
  80. data/lib/dotfiles/vim/plugin/matchit.vim +812 -0
  81. data/lib/dotfiles/vim/plugin/mru.vim +787 -0
  82. data/lib/dotfiles/vim/plugin/rails.vim +310 -0
  83. data/lib/dotfiles/vim/plugin/rspec.vim +12 -0
  84. data/lib/dotfiles/vim/plugin/snippets.vim +17 -0
  85. data/lib/dotfiles/vim/plugin/snippetsEmu.vim +973 -0
  86. data/lib/dotfiles/vim/plugin/supertab.vim +531 -0
  87. data/lib/dotfiles/vim/plugin/surround.vim +632 -0
  88. data/lib/dotfiles/vim/ref_vimrc +80 -0
  89. data/lib/dotfiles/vim/ruby/fuzzy_file_finder.rb +353 -0
  90. data/lib/dotfiles/vim/syntax/eruby.vim +85 -0
  91. data/lib/dotfiles/vim/syntax/haml.vim +113 -0
  92. data/lib/dotfiles/vim/syntax/mkd.vim +86 -0
  93. data/lib/dotfiles/vim/syntax/ruby.vim +324 -0
  94. data/lib/dotfiles/vim/syntax/sass.vim +93 -0
  95. data/lib/dotfiles/vimrc +269 -0
  96. data/lib/vixplode/cli.rb +73 -0
  97. data/lib/vixploder.rb +6 -0
  98. data/script/console +10 -0
  99. data/script/destroy +14 -0
  100. data/script/generate +14 -0
  101. data/spec/spec.opts +1 -0
  102. data/spec/spec_helper.rb +10 -0
  103. data/spec/vixplode_cli_spec.rb +15 -0
  104. data/spec/vixploder_spec.rb +7 -0
  105. data/tasks/rspec.rake +21 -0
  106. metadata +202 -8
@@ -0,0 +1,1676 @@
1
+ "=============================================================================
2
+ " fuzzyfinder.vim : Fuzzy/Partial pattern explorer for
3
+ " buffer/file/MRU/command/favorite/tag/etc.
4
+ "=============================================================================
5
+ "
6
+ " Author: Takeshi NISHIDA <ns9tks@DELETE-ME.gmail.com>
7
+ " Version: 2.13, for Vim 7.1
8
+ " Licence: MIT Licence
9
+ " URL: http://www.vim.org/scripts/script.php?script_id=1984
10
+ "
11
+ " GetLatestVimScripts: 1984 1 :AutoInstall: fuzzyfinder.vim
12
+ "
13
+ "=============================================================================
14
+ " DOCUMENT: {{{1
15
+ " Japanese: http://vim.g.hatena.ne.jp/keyword/fuzzyfinder.vim
16
+ "
17
+ "-----------------------------------------------------------------------------
18
+ " Description:
19
+ " Fuzzyfinder provides convenient ways to quickly reach the buffer/file you
20
+ " want. Fuzzyfinder finds matching files/buffers with a fuzzy/partial
21
+ " pattern to which it converted the entered pattern.
22
+ "
23
+ " E.g.: entered pattern -> fuzzy pattern / partial pattern
24
+ " abc -> *a*b*c* / *abc*
25
+ " a?c -> *a?c* / *a?c*
26
+ " dir/file -> dir/*f*i*l*e* / dir/*file*
27
+ " d*r/file -> d*r/*f*i*l*e* / d*r/*file*
28
+ " ../**/s -> ../**/*s* / ../**/*s*
29
+ "
30
+ " (** allows searching a directory tree.)
31
+ "
32
+ " You will be happy when:
33
+ " "./OhLongLongLongLongLongFile.txt"
34
+ " "./AhLongLongLongLongLongName.txt"
35
+ " "./AhLongLongLongLongLongFile.txt" <- you want :O
36
+ " Type "AF" and "AhLongLongLongLongLongFile.txt" will be select. :D
37
+ "
38
+ " Fuzzyfinder has some modes:
39
+ " - Buffer mode
40
+ " - File mode
41
+ " - Directory mode (yet another :cd command)
42
+ " - MRU-file mode (most recently used files)
43
+ " - MRU-command mode (most recently used command-lines)
44
+ " - Favorite-file mode
45
+ " - Tag mode (yet another :tag command)
46
+ " - Tagged-file mode (files which are included in current tags)
47
+ "
48
+ " Fuzzyfinder supports the multibyte.
49
+ "
50
+ "-----------------------------------------------------------------------------
51
+ " Installation:
52
+ " Drop this file in your plugin directory.
53
+ "
54
+ "-----------------------------------------------------------------------------
55
+ " Usage:
56
+ " Starting Fuzzyfinder:
57
+ " You can start Fuzzyfinder by the following commands:
58
+ "
59
+ " :FuzzyFinderBuffer - launchs buffer-mode Fuzzyfinder.
60
+ " :FuzzyFinderFile - launchs file-mode Fuzzyfinder.
61
+ " :FuzzyFinderDir - launchs directory-mode Fuzzyfinder.
62
+ " :FuzzyFinderMruFile - launchs MRU-file-mode Fuzzyfinder.
63
+ " :FuzzyFinderMruCmd - launchs MRU-command-mode Fuzzyfinder.
64
+ " :FuzzyFinderFavFile - launchs favorite-file-mode Fuzzyfinder.
65
+ " :FuzzyFinderTag - launchs tag-mode Fuzzyfinder.
66
+ " :FuzzyFinderTaggedFile - launchs tagged-file-mode Fuzzyfinder.
67
+ "
68
+ " It is recommended to map these commands. These commands can take initial
69
+ " text as a command argument. The text will be entered after Fuzzyfinder
70
+ " launched. If a command was executed with a ! modifier (e.g.
71
+ " :FuzzyFinderTag!), it enables the partial matching instead of the fuzzy
72
+ " matching.
73
+ "
74
+ "
75
+ " In Fuzzyfinder:
76
+ " The entered pattern is converted to the fuzzy pattern and buffers/files
77
+ " which match the pattern is shown in a completion menu.
78
+ "
79
+ " A completion menu is shown when you type at the end of the line and the
80
+ " length of entered pattern is more than setting value. By default, it is
81
+ " shown at the beginning.
82
+ "
83
+ " If too many items (200, by default) were matched, the completion is
84
+ " aborted to reduce nonresponse.
85
+ "
86
+ " If an item were matched with entered pattern exactly, it is shown first.
87
+ " The item whose file name has longer prefix matching is placed upper.
88
+ " Also, an item which matched more sequentially is placed upper. The item
89
+ " whose index were matched with a number suffixed with entered pattern is
90
+ " placed lower. the first item in the completion menu will be selected
91
+ " automatically.
92
+ "
93
+ " You can open a selected item in various ways:
94
+ " <CR> - opens in a previous window.
95
+ " <C-j> - opens in a split window.
96
+ " <C-k> - opens in a vertical-split window.
97
+ " <C-]> - opens in a new tab page.
98
+ " In MRU-command mode, <CR> executes a selected command and others just
99
+ " put it into a command-line. These key mappings are customizable.
100
+ "
101
+ " To cancel and return to previous window, leave Insert mode.
102
+ "
103
+ " To Switch the mode without leaving Insert mode, use <C-l> or <C-o>.
104
+ " This key mapping is customizable.
105
+ "
106
+ " If you want to temporarily change whether or not to ignore case, use
107
+ " <C-t>. This key mapping is customizable.
108
+ "
109
+ " To Hide The Completion Temporarily Menu In Fuzzyfinder:
110
+ " You can close it by <C-e> and reopen it by <C-x><C-u>.
111
+ "
112
+ " About Highlighting:
113
+ " Fuzzyfinder highlights the buffer with "Error" group when the completion
114
+ " item was not found or the completion process was aborted.
115
+ "
116
+ " About Alternative Approach For Tag Jump:
117
+ " Following mappings are replacements for :tag and <C-]>:
118
+ "
119
+ " nnoremap <silent> <C-f><C-t> :FuzzyFinderTag!<CR>
120
+ " nnoremap <silent> <C-]> :FuzzyFinderTag! <C-r>=expand('<cword>')<CR><CR>
121
+ "
122
+ " In the tag mode, it is recommended to use partial matching instead of
123
+ " fuzzy matching.
124
+ "
125
+ " About Tagged File Mode:
126
+ " The files which are included in the current tags are the ones which are
127
+ " related to the current working environment. So this mode is a pseudo
128
+ " project mode.
129
+ "
130
+ " About Usage Of Command Argument:
131
+ " As an example, if you want to launch file-mode Fuzzyfinder with the full
132
+ " path of current directory, map like below:
133
+ "
134
+ " nnoremap <C-p> :FuzzyFinderFile <C-r>=fnamemodify(getcwd(), ':p')<CR><CR>
135
+ "
136
+ " Instead, if you want the directory of current buffer and not current
137
+ " directory:
138
+ "
139
+ " nnoremap <C-p> :FuzzyFinderFile <C-r>=expand('%:~:.')[:-1-len(expand('%:~:.:t'))]<CR><CR>
140
+ "
141
+ " About Abbreviations And Multiple Search:
142
+ " You can use abbreviations and multiple search in each mode. For example,
143
+ " set as below:
144
+ "
145
+ " let g:FuzzyFinderOptions.Base.abbrev_map = {
146
+ " \ "^WORK" : [
147
+ " \ "~/project/**/src/",
148
+ " \ ".vim/plugin/",
149
+ " \ ],
150
+ " \ }
151
+ "
152
+ " And type "WORKtxt" in file-mode Fuzzyfinder, then it searches by
153
+ " following patterns:
154
+ "
155
+ " "~/project/**/src/*t*x*t*"
156
+ " ".vim/plugin/*t*x*t*"
157
+ "
158
+ " Adding Favorite Files:
159
+ " You can add a favorite file by the following commands:
160
+ "
161
+ " :FuzzyFinderAddFavFile {filename}
162
+ "
163
+ " If you do not specify the filename, current file name is used.
164
+ "
165
+ " About Information File:
166
+ " Fuzzyfinder writes information of the MRU, favorite, etc to the file by
167
+ " default (~/.vimfuzzyfinder).
168
+
169
+ " :FuzzyFinderEditInfo command is helpful in editing your information
170
+ " file. This command reads the information file in new unnamed buffer.
171
+ " Write the buffer and the information file will be updated.
172
+ "
173
+ " About Cache:
174
+ " Once a cache was created, It is not updated automatically to improve
175
+ " response by default. To update it, use :FuzzyFinderRemoveCache command.
176
+ "
177
+ " About Migemo:
178
+ " Migemo is a search method for Japanese language.
179
+ "
180
+ "-----------------------------------------------------------------------------
181
+ " Options:
182
+ " You can set options via g:FuzzyFinderOptions which is a dictionary. See
183
+ " the folded section named "GLOBAL OPTIONS:" for details. To easily set
184
+ " options for customization, put necessary entries from GLOBAL OPTIONS into
185
+ " your vimrc file and edit those values.
186
+ "
187
+ "-----------------------------------------------------------------------------
188
+ " Setting Example:
189
+ " let g:FuzzyFinderOptions = { 'Base':{}, 'Buffer':{}, 'File':{}, 'Dir':{}, 'MruFile':{}, 'MruCmd':{}, 'FavFile':{}, 'Tag':{}, 'TaggedFile':{}}
190
+ " let g:FuzzyFinderOptions.Base.ignore_case = 1
191
+ " let g:FuzzyFinderOptions.Base.abbrev_map = {
192
+ " \ '\C^VR' : [
193
+ " \ '$VIMRUNTIME/**',
194
+ " \ '~/.vim/**',
195
+ " \ '$VIM/.vim/**',
196
+ " \ '$VIM/vimfiles/**',
197
+ " \ ],
198
+ " \ }
199
+ " let g:FuzzyFinderOptions.MruFile.max_item = 200
200
+ " let g:FuzzyFinderOptions.MruCmd.max_item = 200
201
+ " nnoremap <silent> <C-n> :FuzzyFinderBuffer<CR>
202
+ " nnoremap <silent> <C-m> :FuzzyFinderFile <C-r>=expand('%:~:.')[:-1-len(expand('%:~:.:t'))]<CR><CR>
203
+ " nnoremap <silent> <C-j> :FuzzyFinderMruFile<CR>
204
+ " nnoremap <silent> <C-k> :FuzzyFinderMruCmd<CR>
205
+ " nnoremap <silent> <C-p> :FuzzyFinderDir <C-r>=expand('%:p:~')[:-1-len(expand('%:p:~:t'))]<CR><CR>
206
+ " nnoremap <silent> <C-f><C-d> :FuzzyFinderDir<CR>
207
+ " nnoremap <silent> <C-f><C-f> :FuzzyFinderFavFile<CR>
208
+ " nnoremap <silent> <C-f><C-t> :FuzzyFinderTag!<CR>
209
+ " nnoremap <silent> <C-f><C-g> :FuzzyFinderTaggedFile<CR>
210
+ " noremap <silent> g] :FuzzyFinderTag! <C-r>=expand('<cword>')<CR><CR>
211
+ " nnoremap <silent> <C-f>F :FuzzyFinderAddFavFile<CR>
212
+ " nnoremap <silent> <C-f><C-e> :FuzzyFinderEditInfo<CR>
213
+ "
214
+ "-----------------------------------------------------------------------------
215
+ " Special Thanks:
216
+ " Vincent Wang
217
+ " Ingo Karkat
218
+ " Nikolay Golubev
219
+ " Brian Doyle
220
+ " id:secondlife
221
+ " Matt Tolton
222
+ "
223
+ "-----------------------------------------------------------------------------
224
+ " ChangeLog:
225
+ " 2.13:
226
+ " - Fixed a bug that a directory disappeared when a file in that directroy
227
+ " was being opened in File/Mru-File mode.
228
+ "
229
+ " 2.12:
230
+ " - Changed to be able to show completion items in the order of recently
231
+ " used in Buffer mode.
232
+ " - Added g:FuzzyFinderOptions.Buffer.mru_order option.
233
+ "
234
+ " 2.11:
235
+ " - Changed that a dot sequence of entered pattern is expanded to parent
236
+ " directroies in File/Dir mode.
237
+ " E.g.: "foo/...bar" -> "foo/../../bar"
238
+ " - Fixed a bug that a prompt string was excessively inserted.
239
+ "
240
+ " 2.10:
241
+ " - Changed not to show a current buffer in a completion menu.
242
+ " - Fixed a bug that a filename to open was not been escaped.
243
+ " - Added 'prompt' option.
244
+ " - Added 'prompt_highlight' option.
245
+ " - Removed g:FuzzyFinderOptions.MruFile.no_special_buffer option.
246
+ "
247
+ " 2.9:
248
+ " - Enhanced <BS> behavior in Fuzzyfinder and added 'smart_bs' option.
249
+ " - Fixed a bug that entered pattern was not been escaped.
250
+ " - Fixed not to insert "zv" with "c/pattern<CR>" command in Normal mode.
251
+ " - Avoid the slow down problem caused by filereadable() check for the MRU
252
+ " information in BufEnter/BufWritePost.
253
+ "
254
+ " 2.8.1:
255
+ " - Fixed a bug caused by the non-escaped buffer name "[Fuzzyfinder]".
256
+ " - Fixed a command to open in a new tab page in Buffer mode.
257
+ " 2.8:
258
+ " - Added 'trim_length' option.
259
+ " - Added 'switch_order' option.
260
+ " - Fixed a bug that entered command did not become the newest in the
261
+ " history.
262
+ " - Fixed a bug that folds could not open with <CR> in a command-line when
263
+ " searching.
264
+ " - Removed 'excluded_indicator' option. Now a completion list in Buffer
265
+ " mode is the same as a result of :buffers.
266
+ "
267
+ " 2.7:
268
+ " - Changed to find an item whose index is matched with the number
269
+ " suffixed with entered pattern.
270
+ " - Fixed the cache bug after changing current directroy in File mode.
271
+ "
272
+ " 2.6.2:
273
+ " - Fixed not to miss changes in options when updates the MRU information.
274
+ "
275
+ " 2.6.1:
276
+ " - Fixed a bug related to floating-point support.
277
+ " - Added support for GetLatestVimScripts.
278
+ "
279
+ " 2.6:
280
+ " - Revived MRU-command mode. The problem with a command-line abbreviation
281
+ " was solved.
282
+ " - Changed the specification of the information file.
283
+ " - Added :FuzzyFinderEditInfo command.
284
+
285
+ " 2.5.1:
286
+ " - Fixed to be able to match "foo/./bar" by "foo/**/bar" in File mode.
287
+ " - Fixed to be able to open a space-containing file in File mode.
288
+ " - Fixed to honor the current working directory properly in File mode.
289
+ "
290
+ " 2.5:
291
+ " - Fixed the bug that a wrong initial text is entered after switching to a
292
+ " next mode.
293
+ " - Fixed the bug that it does not return to previous window after leaving
294
+ " Fuzzyfinder one.
295
+ "
296
+ " 2.4:
297
+ " - Fixed the bug that Fuzzyfinder fails to open a file caused by auto-cd
298
+ " plugin/script.
299
+ "
300
+ " 2.3:
301
+ " - Added a key mapping to open items in a new tab page and
302
+ " g:FuzzyFinderOptions.Base.key_open_tab opton.
303
+ " - Changed to show Fuzzyfinder window above last window even if
304
+ " 'splitbelow' was set.
305
+ " - Changed to set nocursorline and nocursorcolumn in Fuzzyfinder.
306
+ " - Fixed not to push up a buffer number unlimitedly.
307
+ "
308
+ " 2.2:
309
+ " - Added new feature, which is the partial matching.
310
+ " - Fixed the bug that an error occurs when "'" was entered.
311
+ "
312
+ " 2.1:
313
+ " - Restructured the option system AGAIN. Sorry :p
314
+ " - Changed to inherit a typed text when switching a mode without leaving
315
+ " Insert mode.
316
+ " - Changed commands which launch explorers to be able to take a argument
317
+ " for initial text.
318
+ " - Changed to complete file names by relative path and not full path in
319
+ " the buffer/mru-file/tagged-file mode.
320
+ " - Changed to highlight a typed text when the completion item was not
321
+ " found or the completion process was aborted.
322
+ " - Changed to create caches for each tag file and not working directory
323
+ " in the tag/tagged-file mode.
324
+ " - Fixed the bug that the buffer mode couldn't open a unnamed buffer.
325
+ " - Added 'matching_limit' option.
326
+ " - Removed 'max_match' option. Use 'matching_limit' option instead.
327
+ " - Removed 'initial_text' option. Use command argument instead.
328
+ " - Removed the MRU-command mode.
329
+ "
330
+ " 2.0:
331
+ " - Added the tag mode.
332
+ " - Added the tagged-file mode.
333
+ " - Added :FuzzyFinderRemoveCache command.
334
+ " - Restructured the option system. many options are changed names or
335
+ " default values of some options.
336
+ " - Changed to hold and reuse caches of completion lists by default.
337
+ " - Changed to set filetype 'fuzzyfinder'.
338
+ " - Disabled the MRU-command mode by default because there are problems.
339
+ " - Removed FuzzyFinderAddMode command.
340
+ "
341
+ " 1.5:
342
+ " - Added the directory mode.
343
+ " - Fixed the bug that it caused an error when switch a mode in Insert
344
+ " mode.
345
+ " - Changed g:FuzzyFinder_KeySwitchMode type to a list.
346
+ "
347
+ " 1.4:
348
+ " - Changed the specification of the information file.
349
+ " - Added the MRU-commands mode.
350
+ " - Renamed :FuzzyFinderAddFavorite command to :FuzzyFinderAddFavFile.
351
+ " - Renamed g:FuzzyFinder_MruModeVars option to
352
+ " g:FuzzyFinder_MruFileModeVars.
353
+ " - Renamed g:FuzzyFinder_FavoriteModeVars option to
354
+ " g:FuzzyFinder_FavFileModeVars.
355
+ " - Changed to show registered time of each item in MRU/favorite mode.
356
+ " - Added 'timeFormat' option for MRU/favorite modes.
357
+ "
358
+ " 1.3:
359
+ " - Fixed a handling of multi-byte characters.
360
+ "
361
+ " 1.2:
362
+ " - Added support for Migemo. (Migemo is Japanese search method.)
363
+ "
364
+ " 1.1:
365
+ " - Added the favorite mode.
366
+ " - Added new features, which are abbreviations and multiple search.
367
+ " - Added 'abbrevMap' option for each mode.
368
+ " - Added g:FuzzyFinder_MruModeVars['ignoreSpecialBuffers'] option.
369
+ " - Fixed the bug that it did not work correctly when a user have mapped
370
+ " <C-p> or <Down>.
371
+ "
372
+ " 1.0:
373
+ " - Added the MRU mode.
374
+ " - Added commands to add and use original mode.
375
+ " - Improved the sorting algorithm for completion items.
376
+ " - Added 'initialInput' option to automatically insert a text at the
377
+ " beginning of a mode.
378
+ " - Changed that 'excludedPath' option works for the entire path.
379
+ " - Renamed some options.
380
+ " - Changed default values of some options.
381
+ " - Packed the mode-specific options to dictionaries.
382
+ " - Removed some options.
383
+ "
384
+ " 0.6:
385
+ " - Fixed some bugs.
386
+
387
+ " 0.5:
388
+ " - Improved response by aborting processing too many items.
389
+ " - Changed to be able to open a buffer/file not only in previous window
390
+ " but also in new window.
391
+ " - Fixed a bug that recursive searching with '**' does not work.
392
+ " - Added g:FuzzyFinder_CompletionItemLimit option.
393
+ " - Added g:FuzzyFinder_KeyOpen option.
394
+ "
395
+ " 0.4:
396
+ " - Improved response of the input.
397
+ " - Improved the sorting algorithm for completion items. It is based on
398
+ " the matching level. 1st is perfect matching, 2nd is prefix matching,
399
+ " and 3rd is fuzzy matching.
400
+ " - Added g:FuzzyFinder_ExcludePattern option.
401
+ " - Removed g:FuzzyFinder_WildIgnore option.
402
+ " - Removed g:FuzzyFinder_EchoPattern option.
403
+ " - Removed g:FuzzyFinder_PathSeparator option.
404
+ " - Changed the default value of g:FuzzyFinder_MinLengthFile from 1 to 0.
405
+ "
406
+ " 0.3:
407
+ " - Added g:FuzzyFinder_IgnoreCase option.
408
+ " - Added g:FuzzyFinder_KeyToggleIgnoreCase option.
409
+ " - Added g:FuzzyFinder_EchoPattern option.
410
+ " - Changed the open command in a buffer mode from ":edit" to ":buffer" to
411
+ " avoid being reset cursor position.
412
+ " - Changed the default value of g:FuzzyFinder_KeyToggleMode from
413
+ " <C-Space> to <F12> because <C-Space> does not work on some CUI
414
+ " environments.
415
+ " - Changed to avoid being loaded by Vim before 7.0.
416
+ " - Fixed a bug with making a fuzzy pattern which has '\'.
417
+ "
418
+ " 0.2:
419
+ " - A bug it does not work on Linux is fixed.
420
+ "
421
+ " 0.1:
422
+ " - First release.
423
+ "
424
+ " }}}1
425
+ "=============================================================================
426
+ " INCLUDE GUARD: {{{1
427
+ if exists('loaded_fuzzyfinder') || v:version < 701
428
+ finish
429
+ endif
430
+ let loaded_fuzzyfinder = 1
431
+
432
+ " }}}1
433
+ "=============================================================================
434
+ " FUNCTION: {{{1
435
+ "-----------------------------------------------------------------------------
436
+ " LIST FUNCTIONS:
437
+
438
+ function! s:Unique(in)
439
+ let sorted = sort(a:in)
440
+ if len(sorted) < 2
441
+ return sorted
442
+ endif
443
+ let last = remove(sorted, 0)
444
+ let result = [last]
445
+ for item in sorted
446
+ if item != last
447
+ call add(result, item)
448
+ let last = item
449
+ endif
450
+ endfor
451
+ return result
452
+ endfunction
453
+
454
+ " [ [0], [1,2], [3] ] -> [ 0, 1, 2, 3 ]
455
+ function! s:Concat(in)
456
+ let result = []
457
+ for l in a:in
458
+ let result += l
459
+ endfor
460
+ return result
461
+ endfunction
462
+
463
+ " [ [ 0, 1 ], [ 2, 3, 4 ], ] -> [ [0,2], [0,3], [0,4], [1,2], [1,3], [1,4] ]
464
+ function! s:CartesianProduct(lists)
465
+ if empty(a:lists)
466
+ return []
467
+ endif
468
+ "let result = map((a:lists[0]), '[v:val]')
469
+ let result = [ [] ]
470
+ for l in a:lists
471
+ let temp = []
472
+ for r in result
473
+ let temp += map(copy(l), 'add(copy(r), v:val)')
474
+ endfor
475
+ let result = temp
476
+ endfor
477
+ return result
478
+ endfunction
479
+
480
+ " copy + filter + limit
481
+ function! s:FilterEx(in, expr, limit)
482
+ if a:limit <= 0
483
+ return filter(copy(a:in), a:expr)
484
+ endif
485
+ let result = []
486
+ let stride = a:limit * 3 / 2 " x1.5
487
+ for i in range(0, len(a:in) - 1, stride)
488
+ let result += filter(a:in[i : i + stride - 1], a:expr)
489
+ if len(result) >= a:limit
490
+ return remove(result, 0, a:limit - 1)
491
+ endif
492
+ endfor
493
+ return result
494
+ endfunction
495
+
496
+ "
497
+ function! s:FilterMatching(entries, key, pattern, index, limit)
498
+ return s:FilterEx(a:entries, 'v:val[''' . a:key . '''] =~ ' . string(a:pattern) . ' || v:val.index == ' . a:index, a:limit)
499
+ endfunction
500
+
501
+ function! s:ExtendIndexToEach(in, offset)
502
+ for i in range(len(a:in))
503
+ let a:in[i].index = i + a:offset
504
+ endfor
505
+ return a:in
506
+ endfunction
507
+
508
+ function! s:UpdateMruList(mrulist, new_item, key, max_item, excluded)
509
+ let result = copy(a:mrulist)
510
+ let result = filter(result,'v:val[a:key] != a:new_item[a:key]')
511
+ let result = insert(result, a:new_item)
512
+ let result = filter(result, 'v:val[a:key] !~ a:excluded')
513
+ return result[0 : a:max_item - 1]
514
+ endfunction
515
+
516
+ "-----------------------------------------------------------------------------
517
+ " STRING FUNCTIONS:
518
+
519
+ " trims a:str and add a:mark if a length of a:str is more than a:len
520
+ function! s:TrimLast(str, len)
521
+ if a:len <= 0 || len(a:str) <= a:len
522
+ return a:str
523
+ endif
524
+ return a:str[:(a:len - len(s:ABBR_TRIM_MARK) - 1)] . s:ABBR_TRIM_MARK
525
+ endfunction
526
+
527
+ " takes suffix numer. if no digits, returns -1
528
+ function! s:SuffixNumber(str)
529
+ let s = matchstr(a:str, '\d\+$')
530
+ return (len(s) ? str2nr(s) : -1)
531
+ endfunction
532
+
533
+ function! s:ConvertWildcardToRegexp(expr)
534
+ let re = escape(a:expr, '\')
535
+ for [pat, sub] in [ [ '*', '\\.\\*' ], [ '?', '\\.' ], [ '[', '\\[' ], ]
536
+ let re = substitute(re, pat, sub, 'g')
537
+ endfor
538
+ return '\V' . re
539
+ endfunction
540
+
541
+ " "foo/bar/hoge" -> { head: "foo/bar/", tail: "hoge" }
542
+ function! s:SplitPath(path)
543
+ let dir = matchstr(a:path, '^.*[/\\]')
544
+ return {
545
+ \ 'head' : dir,
546
+ \ 'tail' : a:path[strlen(dir):]
547
+ \ }
548
+ endfunction
549
+
550
+ function! s:EscapeFilename(fn)
551
+ return escape(a:fn, " \t\n*?[{`$%#'\"|!<")
552
+ endfunction
553
+
554
+ " "foo/.../bar/...hoge" -> "foo/.../bar/../../hoge"
555
+ function! s:ExpandTailDotSequenceToParentDir(base)
556
+ return substitute(a:base, '^\(.*[/\\]\)\?\zs\.\(\.\+\)\ze[^/\\]*$',
557
+ \ '\=repeat(".." . s:PATH_SEPARATOR, len(submatch(2)))', '')
558
+ endfunction
559
+
560
+ "-----------------------------------------------------------------------------
561
+ " FUNCTIONS FOR COMPLETION ITEM:
562
+
563
+ function! s:FormatCompletionItem(expr, number, abbr, trim_len, time, base_pattern, evals_path_tail)
564
+ if a:evals_path_tail
565
+ let rate = s:EvaluateMatchingRate(s:SplitPath(matchstr(a:expr, '^.*[^/\\]')).tail,
566
+ \ s:SplitPath(a:base_pattern).tail)
567
+ else
568
+ let rate = s:EvaluateMatchingRate(a:expr, a:base_pattern)
569
+ endif
570
+ return {
571
+ \ 'word' : a:expr,
572
+ \ 'abbr' : s:TrimLast((a:number >= 0 ? printf('%2d: ', a:number) : '') . a:abbr, a:trim_len),
573
+ \ 'menu' : printf('%s[%s]', (len(a:time) ? a:time . ' ' : ''), s:MakeRateStar(rate, 5)),
574
+ \ 'ranks' : [-rate, (a:number >= 0 ? a:number : a:expr)]
575
+ \ }
576
+ endfunction
577
+
578
+ function! s:EvaluateMatchingRate(expr, pattern)
579
+ if a:expr == a:pattern
580
+ return s:MATCHING_RATE_BASE
581
+ endif
582
+ let rate = 0
583
+ let rate_increment = (s:MATCHING_RATE_BASE * 9) / (len(a:pattern) * 10) " zero divide ok
584
+ let matched = 1
585
+ let i_pattern = 0
586
+ for i_expr in range(len(a:expr))
587
+ if a:expr[i_expr] == a:pattern[i_pattern]
588
+ let rate += rate_increment
589
+ let matched = 1
590
+ let i_pattern += 1
591
+ if i_pattern >= len(a:pattern)
592
+ break
593
+ endif
594
+ elseif matched
595
+ let rate_increment = rate_increment / 2
596
+ let matched = 0
597
+ endif
598
+ endfor
599
+ return rate
600
+ endfunction
601
+
602
+ function! s:MakeRateStar(rate, base)
603
+ let len = (a:base * a:rate) / s:MATCHING_RATE_BASE
604
+ return repeat('*', len) . repeat('.', a:base - len)
605
+ endfunction
606
+
607
+ "-----------------------------------------------------------------------------
608
+ " MISC FUNCTIONS:
609
+
610
+ function! s:IsAvailableMode(mode)
611
+ return exists('a:mode.mode_available') && a:mode.mode_available
612
+ endfunction
613
+
614
+ function! s:GetAvailableModes()
615
+ return filter(values(g:FuzzyFinderMode), 's:IsAvailableMode(v:val)')
616
+ endfunction
617
+
618
+ function! s:GetSortedAvailableModes()
619
+ let modes = filter(items(g:FuzzyFinderMode), 's:IsAvailableMode(v:val[1])')
620
+ let modes = map(modes, 'extend(v:val[1], { "ranks" : [v:val[1].switch_order, v:val[0]] })')
621
+ return sort(modes, 's:CompareRanks')
622
+ endfunction
623
+
624
+ function! s:GetSidPrefix()
625
+ return matchstr(expand('<sfile>'), '<SNR>\d\+_')
626
+ endfunction
627
+
628
+ function! s:OnCmdCR()
629
+ for m in s:GetAvailableModes()
630
+ call m.extend_options()
631
+ call m.on_command_pre(getcmdtype() . getcmdline())
632
+ endfor
633
+ " lets last entry become the newest in the history
634
+ if getcmdtype() =~ '[:/=@]'
635
+ call histadd(getcmdtype(), getcmdline())
636
+ endif
637
+
638
+ " this is not mapped again (:help recursive_mapping)
639
+ return "\<CR>"
640
+ endfunction
641
+
642
+ function! s:ExpandAbbrevMap(base, abbrev_map)
643
+ let result = [a:base]
644
+
645
+ " expand
646
+ for [pattern, sub_list] in items(a:abbrev_map)
647
+ let exprs = result
648
+ let result = []
649
+ for expr in exprs
650
+ let result += map(copy(sub_list), 'substitute(expr, pattern, v:val, "g")')
651
+ endfor
652
+ endfor
653
+
654
+ return s:Unique(result)
655
+ endfunction
656
+
657
+ " "**" is expanded to ["**", "."]. E.g.: "foo/**/bar" -> [ "foo/./bar", "foo/**/bar" ]
658
+ function! s:ExpandEx(dir)
659
+ if a:dir !~ '\S'
660
+ return ['']
661
+ endif
662
+
663
+ " [ ["foo/"], ["**/", "./" ], ["bar/"] ]
664
+ let lists = []
665
+ for i in split(a:dir, '[/\\]\zs')
666
+ let m = matchlist(i, '^\*\{2,}\([/\\]*\)$')
667
+ call add(lists, (empty(m) ? [i] : [i, '.' . m[1]]))
668
+ endfor
669
+
670
+ " expand wlidcards
671
+ return split(join(map(s:CartesianProduct(lists), 'expand(join(v:val, ""))'), "\n"), "\n")
672
+ endfunction
673
+
674
+ function! s:EnumExpandedDirsEntries(dir, excluded)
675
+ let dirs = s:ExpandEx(a:dir)
676
+ let entries = s:Concat(map(copy(dirs), 'split(glob(v:val . ".*"), "\n") + ' .
677
+ \ 'split(glob(v:val . "*" ), "\n")'))
678
+ if len(dirs) <= 1
679
+ call map(entries, 'extend(s:SplitPath(v:val), { "suffix" : (isdirectory(v:val) ? s:PATH_SEPARATOR : ""), "head" : a:dir })')
680
+ else
681
+ call map(entries, 'extend(s:SplitPath(v:val), { "suffix" : (isdirectory(v:val) ? s:PATH_SEPARATOR : "") })')
682
+ endif
683
+ if len(a:excluded)
684
+ call filter(entries, '(v:val.head . v:val.tail . v:val.suffix) !~ a:excluded')
685
+ endif
686
+ return entries
687
+ endfunction
688
+
689
+ function! s:GetTagList(tagfile)
690
+ return map(readfile(a:tagfile), 'matchstr(v:val, ''^[^!\t][^\t]*'')')
691
+ endfunction
692
+
693
+ function! s:GetTaggedFileList(tagfile)
694
+ execute 'cd ' . fnamemodify(a:tagfile, ':h')
695
+ let result = map(readfile(a:tagfile), 'fnamemodify(matchstr(v:val, ''^[^!\t][^\t]*\t\zs[^\t]\+''), '':p:~'')')
696
+ cd -
697
+ return result
698
+ endfunction
699
+
700
+ function! s:HighlightPrompt(prompt, highlight)
701
+ syntax clear
702
+ execute printf('syntax match %s /^\V%s/', a:highlight, escape(a:prompt, '\'))
703
+ endfunction
704
+
705
+ function! s:HighlightError()
706
+ syntax clear
707
+ syntax match Error /^.*$/
708
+ endfunction
709
+
710
+ function! s:CompareTimeDescending(i1, i2)
711
+ return a:i1.time == a:i2.time ? 0 : a:i1.time > a:i2.time ? -1 : +1
712
+ endfunction
713
+
714
+ function! s:CompareRanks(i1, i2)
715
+ if exists('a:i1.ranks') && exists('a:i2.ranks')
716
+ for i in range(min([len(a:i1.ranks), len(a:i2.ranks)]))
717
+ if a:i1.ranks[i] > a:i2.ranks[i]
718
+ return +1
719
+ elseif a:i1.ranks[i] < a:i2.ranks[i]
720
+ return -1
721
+ endif
722
+ endfor
723
+ endif
724
+ return 0
725
+ endfunction
726
+
727
+ function! s:GetCurrentTagFiles()
728
+ return sort(filter(map(tagfiles(), 'fnamemodify(v:val, '':p'')'), 'filereadable(v:val)'))
729
+ endfunction
730
+
731
+ " }}}1
732
+ "=============================================================================
733
+ " OBJECT: {{{1
734
+ "-----------------------------------------------------------------------------
735
+ let g:FuzzyFinderMode = { 'Base' : {} }
736
+
737
+ function! g:FuzzyFinderMode.Base.launch(initial_text, partial_matching, prev_bufnr, tag_files)
738
+ " initializes this object
739
+ call self.extend_options()
740
+ let self.partial_matching = a:partial_matching
741
+ let self.prev_bufnr = a:prev_bufnr
742
+ let self.tag_files = a:tag_files " to get local value of current buffer
743
+ let self.last_col = -1
744
+ call s:InfoFileManager.load()
745
+ if !s:IsAvailableMode(self)
746
+ echo 'This mode is not available: ' . self.to_str()
747
+ return
748
+ endif
749
+
750
+ call s:WindowManager.activate(self.make_complete_func('CompleteFunc'))
751
+ call s:OptionManager.set('completeopt', 'menuone')
752
+ call s:OptionManager.set('ignorecase', self.ignore_case)
753
+
754
+ " local autocommands
755
+ augroup FuzzyfinderLocal
756
+ autocmd!
757
+ execute 'autocmd CursorMovedI <buffer> call ' . self.to_str('on_cursor_moved_i()')
758
+ execute 'autocmd InsertLeave <buffer> nested call ' . self.to_str('on_insert_leave()' )
759
+ augroup END
760
+
761
+ " local mapping
762
+ for [lhs, rhs] in [
763
+ \ [ self.key_open , self.to_str('on_cr(0, 0)' ) ],
764
+ \ [ self.key_open_split , self.to_str('on_cr(1, 0)' ) ],
765
+ \ [ self.key_open_vsplit, self.to_str('on_cr(2, 0)' ) ],
766
+ \ [ self.key_open_tab , self.to_str('on_cr(3, 0)' ) ],
767
+ \ [ '<BS>' , self.to_str('on_bs()' ) ],
768
+ \ [ '<C-h>' , self.to_str('on_bs()' ) ],
769
+ \ [ self.key_next_mode , self.to_str('on_switch_mode(+1)' ) ],
770
+ \ [ self.key_prev_mode , self.to_str('on_switch_mode(-1)' ) ],
771
+ \ [ self.key_ignore_case, self.to_str('on_switch_ignore_case()') ],
772
+ \ ]
773
+ " hacks to be able to use feedkeys().
774
+ execute printf('inoremap <buffer> <silent> %s <C-r>=%s ? "" : ""<CR>', lhs, rhs)
775
+ endfor
776
+
777
+ call self.on_mode_enter()
778
+
779
+ " Starts Insert mode and makes CursorMovedI event now. Command prompt is
780
+ " needed to forces a completion menu to update every typing.
781
+ call setline(1, self.prompt . a:initial_text)
782
+ call feedkeys("A", 'n') " startinsert! does not work in InsertLeave handler
783
+ endfunction
784
+
785
+ function! g:FuzzyFinderMode.Base.on_cursor_moved_i()
786
+ let ln = getline('.')
787
+ let cl = col('.')
788
+ if !self.exists_prompt(ln)
789
+ " if command prompt is removed
790
+ "call setline('.', self.prompt . ln)
791
+ call setline('.', self.restore_prompt(ln))
792
+ call feedkeys(repeat("\<Right>", len(getline('.')) - len(ln)), 'n')
793
+ elseif cl <= len(self.prompt)
794
+ " if the cursor is moved before command prompt
795
+ call feedkeys(repeat("\<Right>", len(self.prompt) - cl + 1), 'n')
796
+ elseif cl > strlen(ln) && cl != self.last_col
797
+ " if the cursor is placed on the end of the line and has been actually moved.
798
+ let self.last_col = cl
799
+ call feedkeys("\<C-x>\<C-u>", 'n')
800
+ endif
801
+ endfunction
802
+
803
+ function! g:FuzzyFinderMode.Base.on_insert_leave()
804
+ let text = getline('.')
805
+ call self.on_mode_leave()
806
+ call self.empty_cache_if_existed(0)
807
+ call s:OptionManager.restore_all()
808
+ call s:WindowManager.deactivate()
809
+
810
+ " switchs to next mode, or finishes fuzzyfinder.
811
+ if exists('s:reserved_switch_mode')
812
+ let m = self.next_mode(s:reserved_switch_mode < 0)
813
+ call m.launch(self.remove_prompt(text), self.partial_matching, self.prev_bufnr, self.tag_files)
814
+ unlet s:reserved_switch_mode
815
+ else
816
+ if exists('s:reserved_command')
817
+ call feedkeys(self.on_open(s:reserved_command[0], s:reserved_command[1]), 'n')
818
+ unlet s:reserved_command
819
+ endif
820
+ endif
821
+ endfunction
822
+
823
+ function! g:FuzzyFinderMode.Base.on_buf_enter()
824
+ endfunction
825
+
826
+ function! g:FuzzyFinderMode.Base.on_buf_write_post()
827
+ endfunction
828
+
829
+ function! g:FuzzyFinderMode.Base.on_command_pre(cmd)
830
+ endfunction
831
+
832
+ function! g:FuzzyFinderMode.Base.on_cr(index, check_dir)
833
+ if pumvisible()
834
+ call feedkeys(printf("\<C-y>\<C-r>=%s(%d, 1) ? '' : ''\<CR>", self.to_str('on_cr'), a:index), 'n')
835
+ elseif !a:check_dir || getline('.') !~ '[/\\]$'
836
+ let s:reserved_command = [self.remove_prompt(getline('.')), a:index]
837
+ call feedkeys("\<Esc>", 'n')
838
+ endif
839
+ endfunction
840
+
841
+ function! g:FuzzyFinderMode.Base.on_bs()
842
+ let bs_count = 1
843
+ if self.smart_bs && col('.') > 2 && getline('.')[col('.') - 2] =~ '[/\\]'
844
+ let bs_count = len(matchstr(getline('.')[:col('.') - 3], '[^/\\]*$')) + 1
845
+ endif
846
+ call feedkeys((pumvisible() ? "\<C-e>" : "") . repeat("\<BS>", bs_count), 'n')
847
+ endfunction
848
+
849
+ function! g:FuzzyFinderMode.Base.on_mode_enter()
850
+ endfunction
851
+
852
+ function! g:FuzzyFinderMode.Base.on_mode_leave()
853
+ endfunction
854
+
855
+ function! g:FuzzyFinderMode.Base.on_open(expr, mode)
856
+ return [
857
+ \ ':edit ',
858
+ \ ':split ',
859
+ \ ':vsplit ',
860
+ \ ':tabedit ',
861
+ \ ][a:mode] . s:EscapeFilename(a:expr) . "\<CR>"
862
+ endfunction
863
+
864
+ function! g:FuzzyFinderMode.Base.on_switch_mode(next_prev)
865
+ let s:reserved_switch_mode = a:next_prev
866
+ call feedkeys("\<Esc>", 'n')
867
+ endfunction
868
+
869
+ function! g:FuzzyFinderMode.Base.on_switch_ignore_case()
870
+ let &ignorecase = !&ignorecase
871
+ echo "ignorecase = " . &ignorecase
872
+ let self.last_col = -1
873
+ call self.on_cursor_moved_i()
874
+ endfunction
875
+
876
+ " export string list
877
+ function! g:FuzzyFinderMode.Base.serialize_info()
878
+ let header = self.to_key() . "\t"
879
+ return map(copy(self.info), 'header . string(v:val)')
880
+ endfunction
881
+
882
+ " import related items from string list
883
+ function! g:FuzzyFinderMode.Base.deserialize_info(lines)
884
+ let header = self.to_key() . "\t"
885
+ let self.info = map(filter(copy(a:lines), 'v:val[: len(header) - 1] ==# header'),
886
+ \ 'eval(v:val[len(header) :])')
887
+ endfunction
888
+
889
+ function! g:FuzzyFinderMode.Base.complete(findstart, base)
890
+ if a:findstart
891
+ return 0
892
+ elseif !self.exists_prompt(a:base) || len(self.remove_prompt(a:base)) < self.min_length
893
+ return []
894
+ endif
895
+ call s:HighlightPrompt(self.prompt, self.prompt_highlight)
896
+ " FIXME: ExpandAbbrevMap duplicates index
897
+ let result = []
898
+ for expanded_base in s:ExpandAbbrevMap(self.remove_prompt(a:base), self.abbrev_map)
899
+ let result += self.on_complete(expanded_base)
900
+ endfor
901
+ call sort(result, 's:CompareRanks')
902
+ if empty(result)
903
+ call s:HighlightError()
904
+ else
905
+ call feedkeys("\<C-p>\<Down>", 'n')
906
+ endif
907
+ return result
908
+ endfunction
909
+
910
+ " This function is set to 'completefunc' which doesn't accept dictionary-functions.
911
+ function! g:FuzzyFinderMode.Base.make_complete_func(name)
912
+ execute printf("function! s:%s(findstart, base)\n" .
913
+ \ " return %s.complete(a:findstart, a:base)\n" .
914
+ \ "endfunction", a:name, self.to_str())
915
+ return s:GetSidPrefix() . a:name
916
+ endfunction
917
+
918
+ " fuzzy : 'str' -> {'base':'str', 'wi':'*s*t*r*', 're':'\V\.\*s\.\*t\.\*r\.\*'}
919
+ " partial: 'str' -> {'base':'str', 'wi':'*str*', 're':'\V\.\*str\.\*'}
920
+ function! g:FuzzyFinderMode.Base.make_pattern(base)
921
+ if self.partial_matching
922
+ let wi = (a:base !~ '^[*?]' ? '*' : '') . a:base .
923
+ \ (a:base =~ '[^*?]$' ? '*' : '')
924
+ let re = s:ConvertWildcardToRegexp(wi)
925
+ return { 'base': a:base, 'wi':wi, 're': re }
926
+ else
927
+ let wi = ''
928
+ for char in split(a:base, '\zs')
929
+ if wi !~ '[*?]$' && char !~ '[*?]'
930
+ let wi .= '*'. char
931
+ else
932
+ let wi .= char
933
+ endif
934
+ endfor
935
+
936
+ if wi !~ '[*?]$'
937
+ let wi .= '*'
938
+ endif
939
+
940
+ let re = s:ConvertWildcardToRegexp(wi)
941
+
942
+ if self.migemo_support && a:base !~ '[^\x01-\x7e]'
943
+ let re .= '\|\m.*' . substitute(migemo(a:base), '\\_s\*', '.*', 'g') . '.*'
944
+ endif
945
+
946
+ return { 'base': a:base, 'wi':wi, 're': re }
947
+ endif
948
+ endfunction
949
+
950
+ " glob with caching-feature, etc.
951
+ function! g:FuzzyFinderMode.Base.glob_ex(dir, file, excluded, index, matching_limit)
952
+ let key = fnamemodify(a:dir, ':p')
953
+ call extend(self, { 'cache' : {} }, 'keep')
954
+ if !exists('self.cache[key]')
955
+ echo 'Caching file list...'
956
+ let self.cache[key] = s:EnumExpandedDirsEntries(key, a:excluded)
957
+ call s:ExtendIndexToEach(self.cache[key], 1)
958
+ endif
959
+ echo 'Filtering file list...'
960
+ "return map(s:FilterEx(self.cache[key], 'v:val.tail =~ ' . string(a:file), a:matching_limit),
961
+ return map(s:FilterMatching(self.cache[key], 'tail', a:file, a:index, a:matching_limit),
962
+ \ '{ "index" : v:val.index, "path" : (v:val.head == key ? a:dir : v:val.head) . v:val.tail . v:val.suffix }')
963
+ endfunction
964
+
965
+ function! g:FuzzyFinderMode.Base.glob_dir_ex(dir, file, excluded, index, matching_limit)
966
+ let key = fnamemodify(a:dir, ':p')
967
+ call extend(self, { 'cache' : {} }, 'keep')
968
+ if !exists('self.cache[key]')
969
+ echo 'Caching file list...'
970
+ let self.cache[key] = filter(s:EnumExpandedDirsEntries(key, a:excluded), 'len(v:val.suffix)')
971
+ call insert(self.cache[key], { 'head' : key, 'tail' : '..', 'suffix' : s:PATH_SEPARATOR })
972
+ call insert(self.cache[key], { 'head' : key, 'tail' : '.' , 'suffix' : '' })
973
+ call s:ExtendIndexToEach(self.cache[key], 1)
974
+ endif
975
+ echo 'Filtering file list...'
976
+ "return map(s:FilterEx(self.cache[key], 'v:val.tail =~ ' . string(a:file), a:matching_limit),
977
+ return map(s:FilterMatching(self.cache[key], 'tail', a:file, a:index, a:matching_limit),
978
+ \ '{ "index" : v:val.index, "path" : (v:val.head == key ? a:dir : v:val.head) . v:val.tail . v:val.suffix }')
979
+ endfunction
980
+
981
+ function! g:FuzzyFinderMode.Base.empty_cache_if_existed(force)
982
+ if exists('self.cache') && (a:force || !exists('self.lasting_cache') || !self.lasting_cache)
983
+ unlet self.cache
984
+ "let self.cache = (type(self.cache) == type({}) ? {} :
985
+ " \ type(self.cache) == type([]) ? [] :
986
+ " \ type(self.cache) == type('') ? '' : 0)
987
+ endif
988
+ endfunction
989
+
990
+ function! g:FuzzyFinderMode.Base.to_key()
991
+ return filter(keys(g:FuzzyFinderMode), 'g:FuzzyFinderMode[v:val] is self')[0]
992
+ endfunction
993
+
994
+ " returns 'g:FuzzyFinderMode.{key}{.argument}'
995
+ function! g:FuzzyFinderMode.Base.to_str(...)
996
+ return 'g:FuzzyFinderMode.' . self.to_key() . (a:0 > 0 ? '.' . a:1 : '')
997
+ endfunction
998
+
999
+ " takes in g:FuzzyFinderOptions
1000
+ function! g:FuzzyFinderMode.Base.extend_options()
1001
+ let n = filter(keys(g:FuzzyFinderMode), 'g:FuzzyFinderMode[v:val] is self')[0]
1002
+ call extend(self, g:FuzzyFinderOptions.Base, 'force')
1003
+ call extend(self, g:FuzzyFinderOptions[self.to_key()], 'force')
1004
+ endfunction
1005
+
1006
+ function! g:FuzzyFinderMode.Base.next_mode(rev)
1007
+ let modes = (a:rev ? s:GetSortedAvailableModes() : reverse(s:GetSortedAvailableModes()))
1008
+ let m_last = modes[-1]
1009
+ for m in modes
1010
+ if m is self
1011
+ break
1012
+ endif
1013
+ let m_last = m
1014
+ endfor
1015
+ return m_last
1016
+ " vim crashed using map()
1017
+ endfunction
1018
+
1019
+ function! g:FuzzyFinderMode.Base.exists_prompt(in)
1020
+ return strlen(a:in) >= strlen(self.prompt) && a:in[:strlen(self.prompt) -1] ==# self.prompt
1021
+ endfunction
1022
+
1023
+ function! g:FuzzyFinderMode.Base.remove_prompt(in)
1024
+ return a:in[(self.exists_prompt(a:in) ? strlen(self.prompt) : 0):]
1025
+ endfunction
1026
+
1027
+ function! g:FuzzyFinderMode.Base.restore_prompt(in)
1028
+ let i = 0
1029
+ while i < len(self.prompt) && i < len(a:in) && self.prompt[i] ==# a:in[i]
1030
+ let i += 1
1031
+ endwhile
1032
+ return self.prompt . a:in[i : ]
1033
+ endfunction
1034
+
1035
+ "-----------------------------------------------------------------------------
1036
+ let g:FuzzyFinderMode.Buffer = copy(g:FuzzyFinderMode.Base)
1037
+
1038
+ function! g:FuzzyFinderMode.Buffer.on_complete(base)
1039
+ let patterns = self.make_pattern(a:base)
1040
+ let result = s:FilterMatching(self.cache, 'path', patterns.re, s:SuffixNumber(patterns.base), 0)
1041
+ return map(result, 's:FormatCompletionItem(v:val.path, v:val.index, v:val.path, self.trim_length, v:val.time, a:base, 1)')
1042
+ endfunction
1043
+
1044
+ function! g:FuzzyFinderMode.Buffer.on_open(expr, mode)
1045
+ " attempts to convert the path to the number for handling unnamed buffer
1046
+ return printf([
1047
+ \ ':%sbuffer',
1048
+ \ ':%ssbuffer',
1049
+ \ ':vertical :%ssbuffer',
1050
+ \ ':tab :%ssbuffer',
1051
+ \ ][a:mode] . "\<CR>", filter(self.cache, 'v:val.path == a:expr')[0].buf_nr)
1052
+ endfunction
1053
+
1054
+ function! g:FuzzyFinderMode.Buffer.on_mode_enter()
1055
+ let self.cache = map(filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != self.prev_bufnr'),
1056
+ \ 'self.make_item(v:val)')
1057
+ if self.mru_order
1058
+ call s:ExtendIndexToEach(sort(self.cache, 's:CompareTimeDescending'), 1)
1059
+ endif
1060
+ endfunction
1061
+
1062
+ function! g:FuzzyFinderMode.Buffer.on_buf_enter()
1063
+ call self.update_buf_times()
1064
+ endfunction
1065
+
1066
+ function! g:FuzzyFinderMode.Buffer.on_buf_write_post()
1067
+ call self.update_buf_times()
1068
+ endfunction
1069
+
1070
+ function! g:FuzzyFinderMode.Buffer.update_buf_times()
1071
+ if !exists('self.buf_times')
1072
+ let self.buf_times = {}
1073
+ endif
1074
+ let self.buf_times[bufnr('%')] = localtime()
1075
+ endfunction
1076
+
1077
+ function! g:FuzzyFinderMode.Buffer.make_item(nr)
1078
+ return {
1079
+ \ 'index' : a:nr,
1080
+ \ 'buf_nr' : a:nr,
1081
+ \ 'path' : empty(bufname(a:nr)) ? '[No Name]' : fnamemodify(bufname(a:nr), ':~:.'),
1082
+ \ 'time' : (exists('self.buf_times[a:nr]') ? strftime(self.time_format, self.buf_times[a:nr]) : ''),
1083
+ \ }
1084
+ endfunction
1085
+
1086
+ "-----------------------------------------------------------------------------
1087
+ let g:FuzzyFinderMode.File = copy(g:FuzzyFinderMode.Base)
1088
+
1089
+ function! g:FuzzyFinderMode.File.on_complete(base)
1090
+ let base = s:ExpandTailDotSequenceToParentDir(a:base)
1091
+ let patterns = map(s:SplitPath(base), 'self.make_pattern(v:val)')
1092
+ let result = self.glob_ex(patterns.head.base, patterns.tail.re, self.excluded_path, s:SuffixNumber(patterns.tail.base), self.matching_limit)
1093
+ let result = filter(result, 'bufnr("^" . v:val.path . "$") != self.prev_bufnr')
1094
+ if len(result) >= self.matching_limit
1095
+ call s:HighlightError()
1096
+ endif
1097
+ return map(result, 's:FormatCompletionItem(v:val.path, v:val.index, v:val.path, self.trim_length, "", base, 1)')
1098
+ endfunction
1099
+
1100
+ "-----------------------------------------------------------------------------
1101
+ let g:FuzzyFinderMode.Dir = copy(g:FuzzyFinderMode.Base)
1102
+
1103
+ function! g:FuzzyFinderMode.Dir.on_complete(base)
1104
+ let base = s:ExpandTailDotSequenceToParentDir(a:base)
1105
+ let patterns = map(s:SplitPath(base), 'self.make_pattern(v:val)')
1106
+ let result = self.glob_dir_ex(patterns.head.base, patterns.tail.re, self.excluded_path, s:SuffixNumber(patterns.tail.base), 0)
1107
+ return map(result, 's:FormatCompletionItem(v:val.path, v:val.index, v:val.path, self.trim_length, "", base, 1)')
1108
+ endfunction
1109
+
1110
+ function! g:FuzzyFinderMode.Dir.on_open(expr, mode)
1111
+ return ':cd ' . escape(a:expr, ' ') . [
1112
+ \ "\<CR>",
1113
+ \ "",
1114
+ \ "",
1115
+ \ "",
1116
+ \ ][a:mode]
1117
+ endfunction
1118
+
1119
+ "-----------------------------------------------------------------------------
1120
+ let g:FuzzyFinderMode.MruFile = copy(g:FuzzyFinderMode.Base)
1121
+
1122
+ function! g:FuzzyFinderMode.MruFile.on_complete(base)
1123
+ let patterns = self.make_pattern(a:base)
1124
+ let result = s:FilterMatching(self.cache, 'path', patterns.re, s:SuffixNumber(patterns.base), 0)
1125
+ return map(result, 's:FormatCompletionItem(v:val.path, v:val.index, v:val.path, self.trim_length, v:val.time, a:base, 1)')
1126
+ endfunction
1127
+
1128
+ function! g:FuzzyFinderMode.MruFile.on_mode_enter()
1129
+ let self.cache = copy(self.info)
1130
+ let self.cache = filter(self.cache, 'bufnr("^" . v:val.path . "$") != self.prev_bufnr')
1131
+ let self.cache = filter(self.cache, 'filereadable(v:val.path)')
1132
+ let self.cache = map(self.cache, '{ "path" : fnamemodify(v:val.path, ":~:."), "time" : strftime(self.time_format, v:val.time) }')
1133
+ let self.cache = s:ExtendIndexToEach(self.cache, 1)
1134
+ endfunction
1135
+
1136
+ function! g:FuzzyFinderMode.MruFile.on_buf_enter()
1137
+ call self.update_info()
1138
+ endfunction
1139
+
1140
+ function! g:FuzzyFinderMode.MruFile.on_buf_write_post()
1141
+ call self.update_info()
1142
+ endfunction
1143
+
1144
+ function! g:FuzzyFinderMode.MruFile.update_info()
1145
+ "if !empty(&buftype) || !filereadable(expand('%'))
1146
+ if !empty(&buftype)
1147
+ return
1148
+ endif
1149
+ call s:InfoFileManager.load()
1150
+ let self.info = s:UpdateMruList(self.info, { 'path' : expand('%:p'), 'time' : localtime() },
1151
+ \ 'path', self.max_item, self.excluded_path)
1152
+ call s:InfoFileManager.save()
1153
+ endfunction
1154
+
1155
+ "-----------------------------------------------------------------------------
1156
+ let g:FuzzyFinderMode.MruCmd = copy(g:FuzzyFinderMode.Base)
1157
+
1158
+ function! g:FuzzyFinderMode.MruCmd.on_complete(base)
1159
+ let patterns = self.make_pattern(a:base)
1160
+ let result = s:FilterMatching(self.cache, 'command', patterns.re, s:SuffixNumber(patterns.base), 0)
1161
+ return map(result, 's:FormatCompletionItem(v:val.command, v:val.index, v:val.command, self.trim_length, v:val.time, a:base, 0)')
1162
+ endfunction
1163
+
1164
+ function! g:FuzzyFinderMode.MruCmd.on_open(expr, mode)
1165
+ redraw
1166
+ " use feedkeys to remap <CR>
1167
+ return a:expr . [
1168
+ \ "\<C-r>=feedkeys(\"\\<CR>\", 'm')?'':''\<CR>",
1169
+ \ "",
1170
+ \ "",
1171
+ \ "",
1172
+ \ ][a:mode]
1173
+ endfunction
1174
+
1175
+ function! g:FuzzyFinderMode.MruCmd.on_mode_enter()
1176
+ let self.cache = s:ExtendIndexToEach(map(copy(self.info),
1177
+ \ '{ "command" : v:val.command, "time" : strftime(self.time_format, v:val.time) }'), 1)
1178
+ endfunction
1179
+
1180
+ function! g:FuzzyFinderMode.MruCmd.on_command_pre(cmd)
1181
+ call self.update_info(a:cmd)
1182
+ endfunction
1183
+
1184
+ function! g:FuzzyFinderMode.MruCmd.update_info(cmd)
1185
+ call s:InfoFileManager.load()
1186
+ let self.info = s:UpdateMruList(self.info, { 'command' : a:cmd, 'time' : localtime() },
1187
+ \ 'command', self.max_item, self.excluded_command)
1188
+ call s:InfoFileManager.save()
1189
+ endfunction
1190
+
1191
+ "-----------------------------------------------------------------------------
1192
+ let g:FuzzyFinderMode.FavFile = copy(g:FuzzyFinderMode.Base)
1193
+
1194
+ function! g:FuzzyFinderMode.FavFile.on_complete(base)
1195
+ let patterns = self.make_pattern(a:base)
1196
+ let result = s:FilterMatching(self.cache, 'path', patterns.re, s:SuffixNumber(patterns.base), 0)
1197
+ return map(result, 's:FormatCompletionItem(v:val.path, v:val.index, v:val.path, self.trim_length, v:val.time, a:base, 1)')
1198
+ endfunction
1199
+
1200
+ function! g:FuzzyFinderMode.FavFile.on_mode_enter()
1201
+ let self.cache = copy(self.info)
1202
+ let self.cache = filter(self.cache, 'bufnr("^" . v:val.path . "$") != self.prev_bufnr')
1203
+ let self.cache = map(self.cache, '{ "path" : fnamemodify(v:val.path, ":~:."), "time" : strftime(self.time_format, v:val.time) }')
1204
+ let self.cache = s:ExtendIndexToEach(self.cache, 1)
1205
+ endfunction
1206
+
1207
+ function! g:FuzzyFinderMode.FavFile.add(in_file, adds)
1208
+ call s:InfoFileManager.load()
1209
+
1210
+ let file = fnamemodify((empty(a:in_file) ? expand('%') : a:in_file), ':p:~')
1211
+
1212
+ call filter(self.info, 'v:val.path != file')
1213
+ if a:adds
1214
+ call add(self.info, { 'path' : file, 'time' : localtime() })
1215
+ endif
1216
+
1217
+ call s:InfoFileManager.save()
1218
+ endfunction
1219
+
1220
+ "-----------------------------------------------------------------------------
1221
+ let g:FuzzyFinderMode.Tag = copy(g:FuzzyFinderMode.Base)
1222
+
1223
+ function! g:FuzzyFinderMode.Tag.on_complete(base)
1224
+ let patterns = self.make_pattern(a:base)
1225
+ let result = self.find_tag(patterns.re, self.matching_limit)
1226
+ if len(result) >= self.matching_limit
1227
+ call s:HighlightError()
1228
+ endif
1229
+ return map(result, 's:FormatCompletionItem(v:val, -1, v:val, self.trim_length, "", a:base, 1)')
1230
+ endfunction
1231
+
1232
+ function! g:FuzzyFinderMode.Tag.on_open(expr, mode)
1233
+ return [
1234
+ \ ':tjump ',
1235
+ \ ':stjump ',
1236
+ \ ':vertical :stjump ',
1237
+ \ ':tab :stjump ',
1238
+ \ ][a:mode] . a:expr . "\<CR>"
1239
+ endfunction
1240
+
1241
+ function! g:FuzzyFinderMode.Tag.find_tag(pattern, matching_limit)
1242
+ if !len(self.tag_files)
1243
+ return []
1244
+ endif
1245
+
1246
+ let key = join(self.tag_files, "\n")
1247
+
1248
+ " cache not created or tags file updated?
1249
+ call extend(self, { 'cache' : {} }, 'keep')
1250
+ if !exists('self.cache[key]') || max(map(copy(self.tag_files), 'getftime(v:val) >= self.cache[key].time'))
1251
+ echo 'Caching tag list...'
1252
+ let self.cache[key] = {
1253
+ \ 'time' : localtime(),
1254
+ \ 'data' : s:Unique(s:Concat(map(copy(self.tag_files), 's:GetTagList(v:val)'))),
1255
+ \ }
1256
+ endif
1257
+
1258
+ echo 'Filtering tag list...'
1259
+ return s:FilterEx(self.cache[key].data, 'v:val =~ ' . string(a:pattern), a:matching_limit)
1260
+ endfunction
1261
+
1262
+ "-----------------------------------------------------------------------------
1263
+ let g:FuzzyFinderMode.TaggedFile = copy(g:FuzzyFinderMode.Base)
1264
+
1265
+ function! g:FuzzyFinderMode.TaggedFile.on_complete(base)
1266
+ let patterns = self.make_pattern(a:base)
1267
+ echo 'Making tagged file list...'
1268
+ let result = self.find_tagged_file(patterns.re, self.matching_limit)
1269
+ if len(result) >= self.matching_limit
1270
+ call s:HighlightError()
1271
+ endif
1272
+ return map(result, 's:FormatCompletionItem(v:val, -1, v:val, self.trim_length, "", a:base, 1)')
1273
+ endfunction
1274
+
1275
+ function! g:FuzzyFinderMode.TaggedFile.find_tagged_file(pattern, matching_limit)
1276
+ if !len(self.tag_files)
1277
+ return []
1278
+ endif
1279
+
1280
+ let key = join(self.tag_files, "\n")
1281
+
1282
+ " cache not created or tags file updated?
1283
+ call extend(self, { 'cache' : {} }, 'keep')
1284
+ if !exists('self.cache[key]') || max(map(copy(self.tag_files), 'getftime(v:val) >= self.cache[key].time'))
1285
+ echo 'Caching tagged-file list...'
1286
+ let self.cache[key] = {
1287
+ \ 'time' : localtime(),
1288
+ \ 'data' : s:Unique(s:Concat(map(copy(self.tag_files), 's:GetTaggedFileList(v:val)'))),
1289
+ \ }
1290
+ endif
1291
+
1292
+ echo 'Filtering tagged-file list...'
1293
+ return s:FilterEx(map(self.cache[key].data, 'fnamemodify(v:val, '':.'')'),
1294
+ \ 'v:val =~ ' . string(a:pattern),
1295
+ \ a:matching_limit)
1296
+
1297
+ endfunction
1298
+
1299
+ "-----------------------------------------------------------------------------
1300
+ " sets or restores temporary options
1301
+ let s:OptionManager = { 'originals' : {} }
1302
+
1303
+ function! s:OptionManager.set(name, value)
1304
+ call extend(self.originals, { a:name : eval('&' . a:name) }, 'keep')
1305
+ execute printf('let &%s = a:value', a:name)
1306
+ endfunction
1307
+
1308
+ function! s:OptionManager.restore_all()
1309
+ for [name, value] in items(self.originals)
1310
+ execute printf('let &%s = value', name)
1311
+ endfor
1312
+ let self.originals = {}
1313
+ endfunction
1314
+
1315
+ "-----------------------------------------------------------------------------
1316
+ " manages buffer/window for fuzzyfinder
1317
+ let s:WindowManager = { 'buf_nr' : -1 }
1318
+
1319
+ function! s:WindowManager.activate(complete_func)
1320
+ let self.prev_winnr = winnr()
1321
+ let cwd = getcwd()
1322
+
1323
+ if !bufexists(self.buf_nr)
1324
+ leftabove 1new
1325
+ file `='[Fuzzyfinder]'`
1326
+ let self.buf_nr = bufnr('%')
1327
+ elseif bufwinnr(self.buf_nr) == -1
1328
+ leftabove 1split
1329
+ execute self.buf_nr . 'buffer'
1330
+ delete _
1331
+ elseif bufwinnr(self.buf_nr) != bufwinnr('%')
1332
+ execute bufwinnr(self.buf_nr) . 'wincmd w'
1333
+ endif
1334
+
1335
+ " countermeasure for auto-cd script
1336
+ execute ':lcd ' . cwd
1337
+
1338
+ setlocal filetype=fuzzyfinder
1339
+ setlocal bufhidden=delete
1340
+ setlocal buftype=nofile
1341
+ setlocal noswapfile
1342
+ setlocal nobuflisted
1343
+ setlocal modifiable
1344
+ setlocal nocursorline " for highlighting
1345
+ setlocal nocursorcolumn " for highlighting
1346
+ let &l:completefunc = a:complete_func
1347
+
1348
+ redraw " for 'lazyredraw'
1349
+
1350
+ " suspend autocomplpop.vim
1351
+ if exists(':AutoComplPopLock')
1352
+ :AutoComplPopLock
1353
+ endif
1354
+ endfunction
1355
+
1356
+ function! s:WindowManager.deactivate()
1357
+ " resume autocomplpop.vim
1358
+ if exists(':AutoComplPopUnlock')
1359
+ :AutoComplPopUnlock
1360
+ endif
1361
+
1362
+ close
1363
+ execute self.prev_winnr . 'wincmd w'
1364
+ endfunction
1365
+
1366
+ "-----------------------------------------------------------------------------
1367
+ let s:InfoFileManager = { 'originals' : {} }
1368
+
1369
+ function! s:InfoFileManager.load()
1370
+ for m in s:GetAvailableModes()
1371
+ let m.info = []
1372
+ endfor
1373
+
1374
+ try
1375
+ let lines = readfile(expand(self.get_info_file()))
1376
+ catch /.*/
1377
+ return
1378
+ endtry
1379
+
1380
+ " compatibility check
1381
+ if !count(lines, self.get_info_version_line())
1382
+ call self.warn_old_info()
1383
+ let g:FuzzyFinderOptions.Base.info_file = ''
1384
+ return
1385
+ endif
1386
+
1387
+ for m in s:GetAvailableModes()
1388
+ call m.deserialize_info(lines)
1389
+ endfor
1390
+ endfunction
1391
+
1392
+ function! s:InfoFileManager.save()
1393
+ let lines = [ self.get_info_version_line() ]
1394
+ for m in s:GetAvailableModes()
1395
+ let lines += m.serialize_info()
1396
+ endfor
1397
+
1398
+ try
1399
+ call writefile(lines, expand(self.get_info_file()))
1400
+ catch /.*/
1401
+ endtry
1402
+ endfunction
1403
+
1404
+ function! s:InfoFileManager.edit()
1405
+
1406
+ new
1407
+ file `='[FuzzyfinderInfo]'`
1408
+ let self.bufnr = bufnr('%')
1409
+
1410
+ setlocal filetype=vim
1411
+ setlocal bufhidden=delete
1412
+ setlocal buftype=acwrite
1413
+ setlocal noswapfile
1414
+
1415
+ augroup FuzzyfinderInfo
1416
+ autocmd!
1417
+ autocmd BufWriteCmd <buffer> call s:InfoFileManager.on_buf_write_cmd()
1418
+ augroup END
1419
+
1420
+ execute '0read ' . expand(self.get_info_file())
1421
+ setlocal nomodified
1422
+
1423
+ endfunction
1424
+
1425
+ function! s:InfoFileManager.on_buf_write_cmd()
1426
+ for m in s:GetAvailableModes()
1427
+ call m.deserialize_info(getline(1, '$'))
1428
+ endfor
1429
+ call self.save()
1430
+ setlocal nomodified
1431
+ execute printf('%dbdelete! ', self.bufnr)
1432
+ echo "Information file updated"
1433
+ endfunction
1434
+
1435
+ function! s:InfoFileManager.get_info_version_line()
1436
+ return "VERSION\t206"
1437
+ endfunction
1438
+
1439
+ function! s:InfoFileManager.get_info_file()
1440
+ return g:FuzzyFinderOptions.Base.info_file
1441
+ endfunction
1442
+
1443
+ function! s:InfoFileManager.warn_old_info()
1444
+ echohl WarningMsg
1445
+ echo printf("==================================================\n" .
1446
+ \ " Your Fuzzyfinder information file is no longer \n" .
1447
+ \ " supported. Please remove \n" .
1448
+ \ " %-48s\n" .
1449
+ \ "==================================================\n" ,
1450
+ \ '"' . expand(self.get_info_file()) . '".')
1451
+ echohl None
1452
+ endfunction
1453
+
1454
+ " }}}1
1455
+ "=============================================================================
1456
+ " GLOBAL OPTIONS: {{{1
1457
+ " stores user-defined g:FuzzyFinderOptions ------------------------------ {{{2
1458
+ let user_options = (exists('g:FuzzyFinderOptions') ? g:FuzzyFinderOptions : {})
1459
+ " }}}2
1460
+
1461
+ " Initializes g:FuzzyFinderOptions.
1462
+ let g:FuzzyFinderOptions = { 'Base':{}, 'Buffer':{}, 'File':{}, 'Dir':{}, 'MruFile':{}, 'MruCmd':{}, 'FavFile':{}, 'Tag':{}, 'TaggedFile':{}}
1463
+ "-----------------------------------------------------------------------------
1464
+ " [All Mode] This is mapped to select completion item or finish input and
1465
+ " open a buffer/file in previous window.
1466
+ let g:FuzzyFinderOptions.Base.key_open = '<CR>'
1467
+ " [All Mode] This is mapped to select completion item or finish input and
1468
+ " open a buffer/file in split new window
1469
+ let g:FuzzyFinderOptions.Base.key_open_split = '<C-j>'
1470
+ " [All Mode] This is mapped to select completion item or finish input and
1471
+ " open a buffer/file in vertical-split new window.
1472
+ let g:FuzzyFinderOptions.Base.key_open_vsplit = '<C-k>'
1473
+ " [All Mode] This is mapped to select completion item or finish input and
1474
+ " open a buffer/file in a new tab page.
1475
+ let g:FuzzyFinderOptions.Base.key_open_tab = '<C-]>'
1476
+ " [All Mode] This is mapped to switch to the next mode.
1477
+ let g:FuzzyFinderOptions.Base.key_next_mode = '<C-l>'
1478
+ " [All Mode] This is mapped to switch to the previous mode.
1479
+ let g:FuzzyFinderOptions.Base.key_prev_mode = '<C-o>'
1480
+ " [All Mode] This is mapped to temporarily switch whether or not to ignore
1481
+ " case.
1482
+ let g:FuzzyFinderOptions.Base.key_ignore_case = '<C-t>'
1483
+ " [All Mode] This is the file name to write information of the MRU, etc. If
1484
+ " "" was set, Fuzzyfinder does not write to the file.
1485
+ let g:FuzzyFinderOptions.Base.info_file = '~/.vimfuzzyfinder'
1486
+ " [All Mode] Fuzzyfinder does not start a completion if a length of entered
1487
+ " text is less than this.
1488
+ let g:FuzzyFinderOptions.Base.min_length = 0
1489
+ " [All Mode] This is a dictionary. Each value must be a list. All matchs of a
1490
+ " key in entered text is expanded with the value.
1491
+ let g:FuzzyFinderOptions.Base.abbrev_map = {}
1492
+ " [All Mode] Fuzzyfinder ignores case in search patterns if non-zero is set.
1493
+ let g:FuzzyFinderOptions.Base.ignore_case = 1
1494
+ " [All Mode] This is a string to format time string. See :help strftime() for
1495
+ " details.
1496
+ let g:FuzzyFinderOptions.Base.time_format = '(%x %H:%M:%S)'
1497
+ " [All Mode] If a length of completion item is more than this, it is trimmed
1498
+ " when shown in completion menu.
1499
+ let g:FuzzyFinderOptions.Base.trim_length = 80
1500
+ " [All Mode] Fuzzyfinder does not remove caches of completion lists at the end
1501
+ " of explorer to reuse at the next time if non-zero was set.
1502
+ let g:FuzzyFinderOptions.Base.lasting_cache = 1
1503
+ " [All Mode] Fuzzyfinder uses Migemo if non-zero is set.
1504
+ let g:FuzzyFinderOptions.Base.migemo_support = 0
1505
+ "-----------------------------------------------------------------------------
1506
+ " [Buffer Mode] This disables all functions of this mode if zero was set.
1507
+ let g:FuzzyFinderOptions.Buffer.mode_available = 1
1508
+ " [Buffer Mode] The prompt string.
1509
+ let g:FuzzyFinderOptions.Buffer.prompt = '>Buffer>'
1510
+ " [Buffer Mode] The highlight group name for a prompt string.
1511
+ let g:FuzzyFinderOptions.Buffer.prompt_highlight = 'Question'
1512
+ " [Buffer Mode] Pressing <BS> after a path separator deletes one directory
1513
+ " name if non-zero is set.
1514
+ let g:FuzzyFinderOptions.Buffer.smart_bs = 1
1515
+ " [Buffer Mode] The completion items is sorted in the order of recently used
1516
+ " if non-zero is set.
1517
+ let g:FuzzyFinderOptions.Buffer.mru_order = 1
1518
+ " [Buffer Mode] This is used to sort modes for switching to the next/previous
1519
+ " mode.
1520
+ let g:FuzzyFinderOptions.Buffer.switch_order = 10
1521
+ "-----------------------------------------------------------------------------
1522
+ " [File Mode] This disables all functions of this mode if zero was set.
1523
+ let g:FuzzyFinderOptions.File.mode_available = 1
1524
+ " [File Mode] The prompt string.
1525
+ let g:FuzzyFinderOptions.File.prompt = '>File>'
1526
+ " [File Mode] The highlight group name for a prompt string.
1527
+ let g:FuzzyFinderOptions.File.prompt_highlight = 'Question'
1528
+ " [File Mode] Pressing <BS> after a path separator deletes one directory name
1529
+ " if non-zero is set.
1530
+ let g:FuzzyFinderOptions.File.smart_bs = 1
1531
+ " [File Mode] This is used to sort modes for switching to the next/previous
1532
+ " mode.
1533
+ let g:FuzzyFinderOptions.File.switch_order = 20
1534
+ " [File Mode] The items matching this are excluded from the completion list.
1535
+ let g:FuzzyFinderOptions.File.excluded_path = '\v\~$|\.o$|\.exe$|\.bak$|\.swp$|((^|[/\\])\.[/\\]$)'
1536
+ " [File Mode] If a number of matched items was over this, the completion
1537
+ " process is aborted.
1538
+ let g:FuzzyFinderOptions.File.matching_limit = 200
1539
+ "-----------------------------------------------------------------------------
1540
+ " [Directory Mode] This disables all functions of this mode if zero was set.
1541
+ let g:FuzzyFinderOptions.Dir.mode_available = 1
1542
+ " [Directory Mode] The prompt string.
1543
+ let g:FuzzyFinderOptions.Dir.prompt = '>Dir>'
1544
+ " [Directory Mode] The highlight group name for a prompt string.
1545
+ let g:FuzzyFinderOptions.Dir.prompt_highlight = 'Question'
1546
+ " [Directory Mode] Pressing <BS> after a path separator deletes one directory
1547
+ " name if non-zero is set.
1548
+ let g:FuzzyFinderOptions.Dir.smart_bs = 1
1549
+ " [Directory Mode] This is used to sort modes for switching to the
1550
+ " next/previous mode.
1551
+ let g:FuzzyFinderOptions.Dir.switch_order = 30
1552
+ " [Directory Mode] The items matching this are excluded from the completion
1553
+ " list.
1554
+ let g:FuzzyFinderOptions.Dir.excluded_path = '\v(^|[/\\])\.{1,2}[/\\]$'
1555
+ "-----------------------------------------------------------------------------
1556
+ " [Mru-File Mode] This disables all functions of this mode if zero was set.
1557
+ let g:FuzzyFinderOptions.MruFile.mode_available = 1
1558
+ " [Mru-File Mode] The prompt string.
1559
+ let g:FuzzyFinderOptions.MruFile.prompt = '>MruFile>'
1560
+ " [Mru-File Mode] The highlight group name for a prompt string.
1561
+ let g:FuzzyFinderOptions.MruFile.prompt_highlight = 'Question'
1562
+ " [Mru-File Mode] Pressing <BS> after a path separator deletes one directory
1563
+ " name if non-zero is set.
1564
+ let g:FuzzyFinderOptions.MruFile.smart_bs = 1
1565
+ " [Mru-File Mode] This is used to sort modes for switching to the
1566
+ " next/previous mode.
1567
+ let g:FuzzyFinderOptions.MruFile.switch_order = 40
1568
+ " [Mru-File Mode] The items matching this are excluded from the completion
1569
+ " list.
1570
+ let g:FuzzyFinderOptions.MruFile.excluded_path = '\v\~$|\.bak$|\.swp$'
1571
+ " [Mru-File Mode] This is an upper limit of MRU items to be stored.
1572
+ let g:FuzzyFinderOptions.MruFile.max_item = 99
1573
+ "-----------------------------------------------------------------------------
1574
+ " [Mru-Cmd Mode] This disables all functions of this mode if zero was set.
1575
+ let g:FuzzyFinderOptions.MruCmd.mode_available = 1
1576
+ " [Mru-Cmd Mode] The prompt string.
1577
+ let g:FuzzyFinderOptions.MruCmd.prompt = '>MruCmd>'
1578
+ " [Mru-Cmd Mode] The highlight group name for a prompt string.
1579
+ let g:FuzzyFinderOptions.MruCmd.prompt_highlight = 'Question'
1580
+ " [Mru-Cmd Mode] Pressing <BS> after a path separator deletes one directory
1581
+ " name if non-zero is set.
1582
+ let g:FuzzyFinderOptions.MruCmd.smart_bs = 0
1583
+ " [Mru-Cmd Mode] This is used to sort modes for switching to the next/previous
1584
+ " mode.
1585
+ let g:FuzzyFinderOptions.MruCmd.switch_order = 50
1586
+ " [Mru-Cmd Mode] The items matching this are excluded from the completion
1587
+ " list.
1588
+ let g:FuzzyFinderOptions.MruCmd.excluded_command = '^$'
1589
+ " [Mru-Cmd Mode] This is an upper limit of MRU items to be stored.
1590
+ let g:FuzzyFinderOptions.MruCmd.max_item = 99
1591
+ "-----------------------------------------------------------------------------
1592
+ " [Favorite-File Mode] This disables all functions of this mode if zero was
1593
+ " set.
1594
+ let g:FuzzyFinderOptions.FavFile.mode_available = 1
1595
+ " [Favorite-File Mode] The prompt string.
1596
+ let g:FuzzyFinderOptions.FavFile.prompt = '>FavFile>'
1597
+ " [Favorite-File Mode] The highlight group name for a prompt string.
1598
+ let g:FuzzyFinderOptions.FavFile.prompt_highlight = 'Question'
1599
+ " [Favorite-File Mode] Pressing <BS> after a path separator deletes one
1600
+ " directory name if non-zero is set.
1601
+ let g:FuzzyFinderOptions.FavFile.smart_bs = 1
1602
+ " [Favorite-File Mode] This is used to sort modes for switching to the
1603
+ " next/previous mode.
1604
+ let g:FuzzyFinderOptions.FavFile.switch_order = 60
1605
+ "-----------------------------------------------------------------------------
1606
+ " [Tag Mode] This disables all functions of this mode if zero was set.
1607
+ let g:FuzzyFinderOptions.Tag.mode_available = 1
1608
+ " [Tag Mode] The prompt string.
1609
+ let g:FuzzyFinderOptions.Tag.prompt = '>Tag>'
1610
+ " [Tag Mode] The highlight group name for a prompt string.
1611
+ let g:FuzzyFinderOptions.Tag.prompt_highlight = 'Question'
1612
+ " [Tag Mode] Pressing <BS> after a path separator deletes one directory name
1613
+ " if non-zero is set.
1614
+ let g:FuzzyFinderOptions.Tag.smart_bs = 0
1615
+ " [Tag Mode] This is used to sort modes for switching to the next/previous
1616
+ " mode.
1617
+ let g:FuzzyFinderOptions.Tag.switch_order = 70
1618
+ " [Tag Mode] The items matching this are excluded from the completion list.
1619
+ let g:FuzzyFinderOptions.Tag.excluded_path = '\v\~$|\.bak$|\.swp$'
1620
+ " [Tag Mode] If a number of matched items was over this, the completion
1621
+ " process is aborted.
1622
+ let g:FuzzyFinderOptions.Tag.matching_limit = 200
1623
+ "-----------------------------------------------------------------------------
1624
+ " [Tagged-File Mode] This disables all functions of this mode if zero was set.
1625
+ let g:FuzzyFinderOptions.TaggedFile.mode_available = 1
1626
+ " [Tagged-File Mode] The prompt string.
1627
+ let g:FuzzyFinderOptions.TaggedFile.prompt = '>TaggedFile>'
1628
+ " [Tagged-File Mode] The highlight group name for a prompt string.
1629
+ let g:FuzzyFinderOptions.TaggedFile.prompt_highlight = 'Question'
1630
+ " [Tagged-File Mode] Pressing <BS> after a path separator deletes one
1631
+ " directory name if non-zero is set.
1632
+ let g:FuzzyFinderOptions.TaggedFile.smart_bs = 0
1633
+ " [Tagged-File Mode] This is used to sort modes for switching to the
1634
+ " next/previous mode.
1635
+ let g:FuzzyFinderOptions.TaggedFile.switch_order = 80
1636
+ " [Tagged-File Mode] If a number of matched items was over this, the
1637
+ " completion process is aborted.
1638
+ let g:FuzzyFinderOptions.TaggedFile.matching_limit = 200
1639
+
1640
+ " overwrites default values of g:FuzzyFinderOptions with user-defined values - {{{2
1641
+ call map(user_options, 'extend(g:FuzzyFinderOptions[v:key], v:val, ''force'')')
1642
+ call map(copy(g:FuzzyFinderMode), 'v:val.extend_options()')
1643
+ " }}}2
1644
+
1645
+ " }}}1
1646
+ "=============================================================================
1647
+ " COMMANDS/AUTOCOMMANDS/MAPPINGS/ETC.: {{{1
1648
+
1649
+ let s:PATH_SEPARATOR = (has('win32') || has('win64') ? '\' : '/')
1650
+ let s:MATCHING_RATE_BASE = 10000000
1651
+ let s:ABBR_TRIM_MARK = '...'
1652
+
1653
+ augroup FuzzyfinderGlobal
1654
+ autocmd!
1655
+ autocmd BufEnter * for m in s:GetAvailableModes() | call m.extend_options() | call m.on_buf_enter() | endfor
1656
+ autocmd BufWritePost * for m in s:GetAvailableModes() | call m.extend_options() | call m.on_buf_write_post() | endfor
1657
+ augroup END
1658
+
1659
+ " cnoremap has a problem, which doesn't expand cabbrev.
1660
+ cmap <silent> <expr> <CR> <SID>OnCmdCR()
1661
+
1662
+ command! -bang -narg=? -complete=buffer FuzzyFinderBuffer call g:FuzzyFinderMode.Buffer.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1663
+ command! -bang -narg=? -complete=file FuzzyFinderFile call g:FuzzyFinderMode.File.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1664
+ command! -bang -narg=? -complete=dir FuzzyFinderDir call g:FuzzyFinderMode.Dir.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1665
+ command! -bang -narg=? -complete=file FuzzyFinderMruFile call g:FuzzyFinderMode.MruFile.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1666
+ command! -bang -narg=? -complete=file FuzzyFinderMruCmd call g:FuzzyFinderMode.MruCmd.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1667
+ command! -bang -narg=? -complete=file FuzzyFinderFavFile call g:FuzzyFinderMode.FavFile.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1668
+ command! -bang -narg=? -complete=tag FuzzyFinderTag call g:FuzzyFinderMode.Tag.launch (<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1669
+ command! -bang -narg=? -complete=file FuzzyFinderTaggedFile call g:FuzzyFinderMode.TaggedFile.launch(<q-args>, len(<q-bang>), bufnr('%'), s:GetCurrentTagFiles())
1670
+ command! -bang -narg=? -complete=file FuzzyFinderEditInfo call s:InfoFileManager.edit()
1671
+ command! -bang -narg=? -complete=file FuzzyFinderAddFavFile call g:FuzzyFinderMode.FavFile.add(<q-args>, 1)
1672
+ command! -bang -narg=0 FuzzyFinderRemoveCache for m in s:GetAvailableModes() | call m.empty_cache_if_existed(1) | endfor
1673
+
1674
+ " }}}1
1675
+ "=============================================================================
1676
+ " vim: set fdm=marker: