tomkersten-vixploder 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: