Most Recently Used (MRU) Vim Plugin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

787 lines
25 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. " File: mru.vim
  2. " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
  3. " Version: 3.2
  4. " Last Modified: September 22, 2008
  5. "
  6. " Overview
  7. " --------
  8. " The Most Recently Used (MRU) plugin provides an easy access to a list of
  9. " recently opened/edited files in Vim. This plugin automatically stores the
  10. " file names as you open/edit them in Vim.
  11. "
  12. " This plugin will work on all the platforms where Vim is supported. This
  13. " plugin will work in both console and GUI Vim. This version of the MRU
  14. " plugin needs Vim 7.0 and above. If you are using an earlier version of
  15. " Vim, then you should use an older version of the MRU plugin.
  16. "
  17. " The recently used filenames are stored in a file specified by the Vim
  18. " MRU_File variable.
  19. "
  20. " Installation
  21. " ------------
  22. " 1. Copy the mru.vim file to one of the following directories:
  23. "
  24. " $HOME/.vim/plugin - Unix like systems
  25. " $HOME/vimfiles/plugin - MS-Windows
  26. " $VIM:vimfiles:plugin - Macintosh
  27. " $VIM/vimfiles/plugin - All
  28. "
  29. " Refer to the following Vim help topics for more information about Vim
  30. " plugins:
  31. "
  32. " :help add-plugin
  33. " :help add-global-plugin
  34. " :help runtimepath
  35. "
  36. " 2. Set the MRU_File Vim variable in the .vimrc file to the location of a
  37. " file to store the most recently edited file names. This step is needed
  38. " only if you want to change the default MRU filename.
  39. " 3. Restart Vim.
  40. " 4. You can use the ":MRU" command to list and edit the recently used files.
  41. " In GUI Vim, you can use the 'File->Recent Files' menu to access the
  42. " recently used files.
  43. "
  44. " To uninstall this plugin, remove this file (mru.vim) from the
  45. " $HOME/.vim/plugin or $HOME/vimfiles/plugin or the $VIM/vimfile/plugin
  46. " directory.
  47. "
  48. " Usage
  49. " -----
  50. " To list and edit files from the MRU list, you have to use the ":MRU"
  51. " command. The ":MRU" command displays the MRU file list in a temporary Vim
  52. " window. If the MRU window is already opened, then the MRU list displayed in
  53. " the window is refreshed.
  54. "
  55. " If you are using GUI Vim, then the names of the recently edited files are
  56. " added to the "File->Recent Files" menu. You can select the name of a file
  57. " from this sub-menu to edit the file.
  58. "
  59. " You can use the normal Vim commands to move around in the MRU window. You
  60. " cannot make changes in the MRU window.
  61. "
  62. " You can select a file name to edit by pressing the <Enter> key or by double
  63. " clicking the left mouse button on a file name. The selected file will be
  64. " opened. If the file is already opened in a window, the cursor will be moved
  65. " to that window. Otherwise, the file is opened in the previous window. If the
  66. " previous window has a modified buffer or is the preview window or is used by
  67. " some other plugin, then the file is opened in a new window.
  68. "
  69. " You can press the 'o' key to open the file name under the cursor in the
  70. " MRU window in a new window.
  71. "
  72. " To open a file from the MRU window in a new tab, press the 't' key. If the
  73. " file is already opened in a window in the current or in another tab, then
  74. " the cursor is moved to that tab. Otherwise, a new tab is opened.
  75. "
  76. " You can press the 'u' key in the MRU window to update the file list. This is
  77. " useful if you keep the MRU window open always.
  78. "
  79. " You can close the MRU window by pressing the 'q' key or using one of the Vim
  80. " window commands.
  81. "
  82. " To display only files matching a pattern from the MRU list in the MRU
  83. " window, you can specify a pattern to the ":MRU" command. For example, to
  84. " display only file names containing "vim" in them, you can use the following
  85. " command ":MRU vim". When you specify a partial file name and only one
  86. " matching filename is found, then the ":MRU" command will edit that file.
  87. "
  88. " The ":MRU" command supports command-line completion of file names from
  89. " the MRU list. You can enter a partial file name and then press <Tab>
  90. " or <Ctrl-D> to complete or list all the matching file names.
  91. "
  92. " Whenever the MRU list changes, the MRU file is updated with the latest MRU
  93. " list. When you have multiple instances of Vim running at the same time, the
  94. " latest MRU list will show up in all the instances of Vim.
  95. "
  96. " Configuration
  97. " -------------
  98. " By changing the following variables you can configure the behavior of this
  99. " plugin. Set the following variables in your .vimrc file using the 'let'
  100. " command.
  101. "
  102. " The list of recently edited file names is stored in the file specified by the
  103. " MRU_File variable. The default setting for this variable is
  104. " $HOME/.vim_mru_files for Unix-like systems and $USERPROFILE/_vim_mru_files
  105. " for MS-Windows systems. You can change this variable to point to a file by
  106. " adding the following line to the .vimrc file:
  107. "
  108. " let MRU_File = 'd:\myhome\_vim_mru_files'
  109. "
  110. " By default, the plugin will remember the names of the last 10 used files.
  111. " As you edit more files, old file names will be removed from the MRU list.
  112. " You can set the 'MRU_Max_Entries' variable to remember more file names. For
  113. " example, to remember 20 most recently used file names, you can use
  114. "
  115. " let MRU_Max_Entries = 20
  116. "
  117. " By default, all the edited file names will be added to the MRU list. If you
  118. " want to exclude file names matching a list of patterns, you can set the
  119. " MRU_Exclude_Files variable to a list of Vim regular expressions. By default,
  120. " this variable is set to an empty string. For example, to not include files
  121. " in the temporary (/tmp, /var/tmp and d:\temp) directories, you can set the
  122. " MRU_Exclude_Files variable to
  123. "
  124. " let MRU_Exclude_Files = '^/tmp/.*\|^/var/tmp/.*' " For Unix
  125. " let MRU_Exclude_Files = '^c:\\temp\\.*' " For MS-Windows
  126. "
  127. " The specified pattern should be a Vim regular expression pattern.
  128. "
  129. " If you want to add only file names matching a set of patterns to the MRU
  130. " list, then you can set the MRU_Include_Files variable. This variable should
  131. " be set to a Vim regular expression pattern. For example, to add only .c and
  132. " .h files to the MRU list, you can set this variable as below:
  133. "
  134. " let MRU_Include_Files = '\.c$\|\.h$'
  135. "
  136. " By default, MRU_Include_Files is set to an empty string and all the edited
  137. " filenames are added to the MRU list.
  138. "
  139. " The default height of the MRU window is 8. You can set the MRU_Window_Height
  140. " variable to change the window height.
  141. "
  142. " let MRU_Window_Height = 15
  143. "
  144. " By default, when the :MRU command is invoked, the MRU list will be displayed
  145. " in a new window. Instead, if you want the MRU plugin to reuse the current
  146. " window, then you can set the 'MRU_Use_Current_Window' variable to one.
  147. "
  148. " let MRU_Use_Current_Window = 1
  149. "
  150. " The MRU plugin will reuse the current window. When a file name is selected,
  151. " the file is also opened in the current window.
  152. "
  153. " When you select a file from the MRU window, the MRU window will be
  154. " automatically closed and the selected file will be opened in the previous
  155. " window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU
  156. " window open.
  157. "
  158. " let MRU_Auto_Close = 0
  159. "
  160. " If you don't use the "File->Recent Files" menu and want to disable it,
  161. " then you can set the 'MRU_Add_Menu' variable to zero. By default, the
  162. " menu is enabled.
  163. "
  164. " let MRU_Add_Menu = 0
  165. "
  166. " ****************** Do not modify after this line ************************
  167. if exists('loaded_mru')
  168. finish
  169. endif
  170. let loaded_mru=1
  171. if v:version < 700
  172. finish
  173. endif
  174. " Line continuation used here
  175. let s:cpo_save = &cpo
  176. set cpo&vim
  177. " Maximum number of entries allowed in the MRU list
  178. if !exists('MRU_Max_Entries')
  179. let MRU_Max_Entries = 10
  180. endif
  181. " Files to exclude from the MRU list
  182. if !exists('MRU_Exclude_Files')
  183. let MRU_Exclude_Files = ''
  184. endif
  185. " Files to include in the MRU list
  186. if !exists('MRU_Include_Files')
  187. let MRU_Include_Files = ''
  188. endif
  189. " Height of the MRU window
  190. " Default height is 8
  191. if !exists('MRU_Window_Height')
  192. let MRU_Window_Height = 8
  193. endif
  194. if !exists('MRU_Use_Current_Window')
  195. let MRU_Use_Current_Window = 0
  196. endif
  197. if !exists('MRU_Auto_Close')
  198. let MRU_Auto_Close = 1
  199. endif
  200. if !exists('MRU_File')
  201. if has('unix') || has('macunix')
  202. let MRU_File = $HOME . '/.vim_mru_files'
  203. else
  204. let MRU_File = $VIM . '/_vim_mru_files'
  205. if has('win32')
  206. " MS-Windows
  207. if $USERPROFILE != ''
  208. let MRU_File = $USERPROFILE . '\_vim_mru_files'
  209. endif
  210. endif
  211. endif
  212. endif
  213. " Option for enabling or disabling the MRU menu
  214. if !exists('MRU_Add_Menu')
  215. let MRU_Add_Menu = 1
  216. endif
  217. " Control to temporarily lock the MRU list. Used to prevent files from
  218. " getting added to the MRU list when the ':vimgrep' command is executed.
  219. let s:mru_list_locked = 0
  220. " MRU_LoadList
  221. " Load the latest MRU file list from the MRU file
  222. function! s:MRU_LoadList()
  223. " Read the list from the MRU file.
  224. if filereadable(g:MRU_File)
  225. let s:MRU_files = readfile(g:MRU_File)
  226. if s:MRU_files[0] =~# '^\s*" Most recently edited files in Vim'
  227. " Generated by the previous version of the MRU plugin.
  228. " Discard the list.
  229. let s:MRU_files = []
  230. elseif s:MRU_files[0] =~# '^#'
  231. " Remove the comment line
  232. call remove(s:MRU_files, 0)
  233. else
  234. " Unsupported format
  235. let s:MRU_files = []
  236. endif
  237. else
  238. let s:MRU_files = []
  239. endif
  240. " Refresh the MRU menu
  241. call s:MRU_Refresh_Menu()
  242. endfunction
  243. " MRU_SaveList
  244. " Save the MRU list to the file
  245. function! s:MRU_SaveList()
  246. let l = []
  247. call add(l, '# Most recently edited files in Vim (version 3.0)')
  248. call extend(l, s:MRU_files)
  249. call writefile(l, g:MRU_File)
  250. endfunction
  251. " MRU_AddFile
  252. " Add a file to the MRU file list
  253. function! s:MRU_AddFile(acmd_bufnr)
  254. if s:mru_list_locked
  255. " MRU list is currently locked
  256. return
  257. endif
  258. " Get the full path to the filename
  259. let fname = fnamemodify(bufname(a:acmd_bufnr + 0), ':p')
  260. if fname == ''
  261. return
  262. endif
  263. " Skip temporary buffer with buftype set
  264. if &buftype != ''
  265. return
  266. endif
  267. if g:MRU_Include_Files != ''
  268. " If MRU_Include_Files is set, include only files matching the
  269. " specified pattern
  270. if fname !~# g:MRU_Include_Files
  271. return
  272. endif
  273. endif
  274. if g:MRU_Exclude_Files != ''
  275. " Do not add files matching the pattern specified in the
  276. " MRU_Exclude_Files to the MRU list
  277. if fname =~# g:MRU_Exclude_Files
  278. return
  279. endif
  280. endif
  281. " If the filename is not already present in the MRU list and is not
  282. " readable then ignore it
  283. let idx = index(s:MRU_files, fname)
  284. if idx == -1
  285. if !filereadable(fname)
  286. " File is not readable and is not in the MRU list
  287. return
  288. endif
  289. endif
  290. " Load the latest MRU file list
  291. call s:MRU_LoadList()
  292. " Remove the new file name from the existing MRU list (if already present)
  293. call filter(s:MRU_files, 'v:val !=# fname')
  294. " Add the new file list to the beginning of the updated old file list
  295. call insert(s:MRU_files, fname, 0)
  296. " Trim the list
  297. if len(s:MRU_files) > g:MRU_Max_Entries
  298. call remove(s:MRU_files, g:MRU_Max_Entries, -1)
  299. endif
  300. " Save the updated MRU list
  301. call s:MRU_SaveList()
  302. " Refresh the MRU menu
  303. call s:MRU_Refresh_Menu()
  304. " If the MRU window is open, update the displayed MRU list
  305. let bname = '__MRU_Files__'
  306. let winnum = bufwinnr(bname)
  307. if winnum != -1
  308. let cur_winnr = winnr()
  309. call s:MRU_Open_Window()
  310. if winnr() != cur_winnr
  311. exe cur_winnr . 'wincmd w'
  312. endif
  313. endif
  314. endfunction
  315. " Special characters in file names that should be escaped (for security
  316. " reasons)
  317. let s:esc_filename_chars = ' *?[{`$%#"|!<>();&' . "'\t\n"
  318. function! s:MRU_escape_filename(fname)
  319. return escape(a:fname, s:esc_filename_chars)
  320. endfunction
  321. " MRU_Edit_File
  322. " Edit the specified file
  323. function! s:MRU_Edit_File(filename, sanitized)
  324. if !a:sanitized
  325. let esc_fname = s:MRU_escape_filename(a:filename)
  326. else
  327. let esc_fname = a:filename
  328. endif
  329. " If the file is already open in one of the windows, jump to it
  330. let winnum = bufwinnr('^' . a:filename . '$')
  331. if winnum != -1
  332. if winnum != winnr()
  333. exe winnum . 'wincmd w'
  334. endif
  335. else
  336. if &modified || &buftype != '' || &previewwindow
  337. " Current buffer has unsaved changes or is a special buffer or is
  338. " the preview window. So open the file in a new window
  339. exe 'split ' . esc_fname
  340. else
  341. exe 'edit ' . esc_fname
  342. endif
  343. endif
  344. endfunction
  345. " MRU_Window_Edit_File
  346. " Open a file selected from the MRU window
  347. " win_opt == useopen, open file in previous window
  348. " win_opt == newwin, open file in new window
  349. " win_opt == newtab, open file in new tab
  350. function! s:MRU_Window_Edit_File(win_opt)
  351. let fname = getline('.')
  352. if fname == ''
  353. return
  354. endif
  355. let esc_fname = s:MRU_escape_filename(fname)
  356. if a:win_opt == 'newwin'
  357. " Edit the file in a new window
  358. exe 'leftabove new ' . esc_fname
  359. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  360. " Go back to the MRU window and close it
  361. let cur_winnr = winnr()
  362. wincmd p
  363. silent! close
  364. if winnr() != cur_winnr
  365. exe cur_winnr . 'wincmd w'
  366. endif
  367. endif
  368. elseif a:win_opt == 'newtab'
  369. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  370. " Automatically close the window if the file window is
  371. " not used to display the MRU list.
  372. silent! close
  373. endif
  374. " If the selected file is already open in the current tab or in
  375. " another tab, jump to it. Otherwise open it in a new tab
  376. if bufwinnr('^' . fname . '$') == -1
  377. let tabnum = -1
  378. let i = 1
  379. let bnum = bufnr('^' . fname . '$')
  380. while i <= tabpagenr('$')
  381. if index(tabpagebuflist(i), bnum) != -1
  382. let tabnum = i
  383. break
  384. endif
  385. let i += 1
  386. endwhile
  387. if tabnum != -1
  388. " Goto the tab containing the file
  389. exe 'tabnext ' . i
  390. else
  391. " Open a new tab as the last tab page
  392. exe '999tabnew ' . esc_fname
  393. endif
  394. endif
  395. " Jump to the window containing the file
  396. let winnum = bufwinnr('^' . fname . '$')
  397. if winnum != winnr()
  398. exe winnum . 'wincmd w'
  399. endif
  400. else
  401. " If the selected file is already open in one of the windows,
  402. " jump to it
  403. let winnum = bufwinnr('^' . fname . '$')
  404. if winnum != -1
  405. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  406. " Automatically close the window if the file window is
  407. " not used to display the MRU list.
  408. silent! close
  409. endif
  410. " As the window numbers will change after closing a window,
  411. " get the window number again and jump to it, if the cursor
  412. " is not already in that window
  413. let winnum = bufwinnr('^' . fname . '$')
  414. if winnum != winnr()
  415. exe winnum . 'wincmd w'
  416. endif
  417. else
  418. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  419. " Automatically close the window if the file window is
  420. " not used to display the MRU list.
  421. silent! close
  422. " Jump to the window from which the MRU window was opened
  423. if exists('s:MRU_last_buffer')
  424. let last_winnr = bufwinnr(s:MRU_last_buffer)
  425. if last_winnr != -1 && last_winnr != winnr()
  426. exe last_winnr . 'wincmd w'
  427. endif
  428. endif
  429. else
  430. if g:MRU_Use_Current_Window == 0
  431. " Goto the previous window
  432. " If MRU_Use_Current_Window is set to one, then the
  433. " current window is used to open the file
  434. wincmd p
  435. endif
  436. endif
  437. " Edit the file
  438. if &modified || &buftype != '' || &previewwindow
  439. " Current buffer has unsaved changes or is a special buffer or
  440. " is the preview window. So open the file in a new window
  441. exe 'split ' . esc_fname
  442. else
  443. exe 'edit ' . esc_fname
  444. endif
  445. endif
  446. endif
  447. endfunction
  448. " MRU_Warn_Msg
  449. " Display a warning message
  450. function! s:MRU_Warn_Msg(msg)
  451. echohl WarningMsg
  452. echo a:msg
  453. echohl None
  454. endfunction
  455. " MRU_Open_Window
  456. " Display the Most Recently Used file list in a temporary window.
  457. function! s:MRU_Open_Window(...)
  458. " Load the latest MRU file list
  459. call s:MRU_LoadList()
  460. " Empty MRU list
  461. if empty(s:MRU_files)
  462. call s:MRU_Warn_Msg('MRU file list is empty')
  463. return
  464. endif
  465. " Save the current buffer number. This is used later to open a file when a
  466. " entry is selected from the MRU window. The window number is not saved,
  467. " as the window number will change when new windows are opened.
  468. let s:MRU_last_buffer = bufnr('%')
  469. let bname = '__MRU_Files__'
  470. " If the window is already open, jump to it
  471. let winnum = bufwinnr(bname)
  472. if winnum != -1
  473. if winnr() != winnum
  474. " If not already in the window, jump to it
  475. exe winnum . 'wincmd w'
  476. endif
  477. setlocal modifiable
  478. " Delete the contents of the buffer to the black-hole register
  479. silent! %delete _
  480. else
  481. if g:MRU_Use_Current_Window
  482. " Reuse the current window
  483. "
  484. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  485. " a new buffer
  486. let bufnum = bufnr(bname)
  487. if bufnum == -1
  488. let cmd = 'edit ' . bname
  489. else
  490. let cmd = 'buffer ' . bufnum
  491. endif
  492. exe cmd
  493. if bufnr('%') != bufnr(bname)
  494. " Failed to edit the MRU buffer
  495. return
  496. endif
  497. else
  498. " Open a new window at the bottom
  499. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  500. " a new buffer
  501. let bufnum = bufnr(bname)
  502. if bufnum == -1
  503. let wcmd = bname
  504. else
  505. let wcmd = '+buffer' . bufnum
  506. endif
  507. exe 'silent! botright ' . g:MRU_Window_Height . 'split ' . wcmd
  508. endif
  509. endif
  510. " Mark the buffer as scratch
  511. setlocal buftype=nofile
  512. setlocal bufhidden=delete
  513. setlocal noswapfile
  514. setlocal nowrap
  515. setlocal nobuflisted
  516. " Use fixed height for the MRU window
  517. if v:version >= 602
  518. setlocal winfixheight
  519. endif
  520. " Setup the cpoptions properly for the maps to work
  521. let old_cpoptions = &cpoptions
  522. set cpoptions&vim
  523. " Create a mapping to jump to the file
  524. nnoremap <buffer> <silent> <CR>
  525. \ :call <SID>MRU_Window_Edit_File('useopen')<CR>
  526. nnoremap <buffer> <silent> o
  527. \ :call <SID>MRU_Window_Edit_File('newwin')<CR>
  528. nnoremap <buffer> <silent> t
  529. \ :call <SID>MRU_Window_Edit_File('newtab')<CR>
  530. nnoremap <buffer> <silent> u :MRU<CR>
  531. nnoremap <buffer> <silent> <2-LeftMouse>
  532. \ :call <SID>MRU_Window_Edit_File('useopen')<CR>
  533. nnoremap <buffer> <silent> q :close<CR>
  534. " Restore the previous cpoptions settings
  535. let &cpoptions = old_cpoptions
  536. " Display the MRU list
  537. if a:0 == 0
  538. " No search pattern specified. Display the complete list
  539. silent! 0put =s:MRU_files
  540. else
  541. " Display only the entries matching the specified pattern
  542. " First try using it as a literal pattern
  543. let m = filter(copy(s:MRU_files), 'stridx(v:val, a:1) != -1')
  544. if len(m) == 0
  545. " No match. Try using it as a regular expression
  546. let m = filter(copy(s:MRU_files), 'v:val =~# a:1')
  547. endif
  548. silent! 0put =m
  549. endif
  550. " Move the cursor to the beginning of the file
  551. normal! gg
  552. setlocal nomodifiable
  553. endfunction
  554. " MRU_Complete
  555. " Command-line completion function used by :MRU command
  556. function! s:MRU_Complete(ArgLead, CmdLine, CursorPos)
  557. if a:ArgLead == ''
  558. " Return the list of MRU files
  559. return s:MRU_files
  560. else
  561. return filter(copy(s:MRU_files), 'v:val =~? a:ArgLead')
  562. endif
  563. endfunction
  564. " MRU_Cmd
  565. " Function to handle the MRU command
  566. function! s:MRU_Cmd(pat)
  567. if a:pat == ''
  568. " No arguments specified. Open the MRU window
  569. call s:MRU_Open_Window()
  570. return
  571. endif
  572. " Load the latest MRU file
  573. call s:MRU_LoadList()
  574. " Empty MRU list
  575. if empty(s:MRU_files)
  576. call s:MRU_Warn_Msg('MRU file list is empty')
  577. return
  578. endif
  579. " First use the specified string as a literal string and search for
  580. " filenames containing the string. If only one filename is found,
  581. " then edit it.
  582. let m = filter(copy(s:MRU_files), 'stridx(v:val, a:pat) != -1')
  583. if len(m) > 0
  584. if len(m) == 1
  585. call s:MRU_Edit_File(m[0], 0)
  586. return
  587. endif
  588. " More than one file matches. Try find an accurate match
  589. let new_m = filter(m, 'v:val ==# a:pat')
  590. if len(new_m) == 1
  591. call s:MRU_Edit_File(new_m[0], 0)
  592. return
  593. endif
  594. " Couldn't find an exact match, open the MRU window
  595. call s:MRU_Open_Window(a:pat)
  596. return
  597. endif
  598. " Use the specified string as a regular expression pattern and search
  599. " for filenames matching the pattern
  600. let m = filter(copy(s:MRU_files), 'v:val =~? a:pat')
  601. if len(m) == 0
  602. " No filenames matching the specified pattern are found
  603. call s:MRU_Warn_Msg("MRU file list doesn't contain " .
  604. \ "files containing " . a:pat)
  605. return
  606. endif
  607. if len(m) == 1
  608. call s:MRU_Edit_File(m[0], 0)
  609. return
  610. endif
  611. call s:MRU_Open_Window(a:pat)
  612. endfunction
  613. function! s:MRU_add_files_to_menu(prefix, file_list)
  614. for fname in a:file_list
  615. " Escape special characters in the filename
  616. let esc_fname = escape(fnamemodify(fname, ':t'), ".\\" .
  617. \ s:esc_filename_chars)
  618. let esc_fname = substitute(esc_fname, '&', '&&', 'g')
  619. " Truncate the directory name if it is long
  620. let dir_name = fnamemodify(fname, ':h')
  621. let len = strlen(dir_name)
  622. " Shorten long file names by adding only few characters from
  623. " the beginning and end.
  624. if len > 30
  625. let dir_name = strpart(dir_name, 0, 10) .
  626. \ '...' .
  627. \ strpart(dir_name, len - 20)
  628. endif
  629. let esc_dir_name = escape(dir_name, ".\\" . s:esc_filename_chars)
  630. let esc_dir_name = substitute(esc_dir_name, '&', '&&', 'g')
  631. let menu_path = '&File.Recent\ Files.' . a:prefix . esc_fname .
  632. \ '\ (' . esc_dir_name . ')'
  633. let esc_mfname = s:MRU_escape_filename(fname)
  634. exe 'anoremenu <silent> ' . menu_path .
  635. \ " :call <SID>MRU_Edit_File('" . esc_mfname . "', 1)<CR>"
  636. exe 'tmenu ' . menu_path . ' Edit file ' . esc_mfname
  637. endfor
  638. endfunction
  639. " MRU_Refresh_Menu()
  640. " Refresh the MRU menu
  641. function! s:MRU_Refresh_Menu()
  642. if !has('menu') || !g:MRU_Add_Menu
  643. " No support for menus
  644. return
  645. endif
  646. " Setup the cpoptions properly for the maps to work
  647. let old_cpoptions = &cpoptions
  648. set cpoptions&vim
  649. " Remove the MRU menu
  650. " To retain the teared-off MRU menu, we need to add a dummy entry
  651. silent! unmenu &File.Recent\ Files
  652. " The menu priority of the File menu is 10. If the MRU plugin runs
  653. " first before menu.vim, the File menu order may not be correct.
  654. " So specify the priority of the File menu here.
  655. 10noremenu &File.Recent\ Files.Dummy <Nop>
  656. silent! unmenu! &File.Recent\ Files
  657. anoremenu <silent> &File.Recent\ Files.Refresh\ list
  658. \ :call <SID>MRU_LoadList()<CR>
  659. exe 'tmenu File.Recent\ Files.Refresh\ list Reload the MRU file list from '
  660. \ . s:MRU_escape_filename(g:MRU_File)
  661. anoremenu File.Recent\ Files.-SEP1- :
  662. " Add the filenames in the MRU list to the menu
  663. let entry_cnt = len(s:MRU_files)
  664. if entry_cnt > 10
  665. " Split the MRU menu into sub-menus
  666. for start_idx in range(0, entry_cnt, 10)
  667. let last_idx = start_idx + 9
  668. if last_idx >= entry_cnt
  669. let last_idx = entry_cnt - 1
  670. endif
  671. let prefix = 'Files\ (' . (start_idx + 1) . '\.\.\.' .
  672. \ (last_idx + 1) . ').'
  673. call s:MRU_add_files_to_menu(prefix,
  674. \ s:MRU_files[start_idx : last_idx])
  675. endfor
  676. else
  677. call s:MRU_add_files_to_menu('', s:MRU_files)
  678. endif
  679. " Remove the dummy menu entry
  680. unmenu &File.Recent\ Files.Dummy
  681. " Restore the previous cpoptions settings
  682. let &cpoptions = old_cpoptions
  683. endfunction
  684. " Load the MRU list on plugin startup
  685. call s:MRU_LoadList()
  686. " Autocommands to detect the most recently used files
  687. autocmd BufRead * call s:MRU_AddFile(expand('<abuf>'))
  688. autocmd BufNewFile * call s:MRU_AddFile(expand('<abuf>'))
  689. autocmd BufWritePost * call s:MRU_AddFile(expand('<abuf>'))
  690. " The ':vimgrep' command adds all the files searched to the buffer list.
  691. " This also modifies the MRU list, even though the user didn't edit the
  692. " files. Use the following autocmds to prevent this.
  693. autocmd QuickFixCmdPre *vimgrep* let s:mru_list_locked = 1
  694. autocmd QuickFixCmdPost *vimgrep* let s:mru_list_locked = 0
  695. " Command to open the MRU window
  696. command! -nargs=? -complete=customlist,s:MRU_Complete MRU
  697. \ call s:MRU_Cmd(<q-args>)
  698. " restore 'cpo'
  699. let &cpo = s:cpo_save
  700. unlet s:cpo_save