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.

365 lines
12 KiB

10 years ago
  1. " File: mru.vim
  2. " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
  3. " Version: 1.5
  4. " Last Modified: May 19, 2003
  5. "
  6. " Overview
  7. " --------
  8. " The Most Recently Used (MRU) plugin provides an easy access to a list of
  9. " recently opened/used files in Vim. This plugin automatically stores the file
  10. " names as you open/use 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 plugin will work only if
  14. " the 'compatible' option is not set. As this plugin relies on the 'viminfo'
  15. " feature, make sure Vim is built with this feature (+viminfo) enabled (use
  16. " the ":version" command)
  17. "
  18. " The MRU filenames are stored in a global variable which retains the stored
  19. " value across Vim sessions using the 'viminfo' feature. For this to work, the
  20. " 'viminfo' option should have the '!' flag set. This plugin will
  21. " automatically add this flag to the 'viminfo' option.
  22. "
  23. " When you are using multiple instances of Vim at the same time, as you quit
  24. " every instance of Vim, the MRU list from that instance will override the
  25. " list from other instances of Vim. This is similar to how Vim handles the
  26. " buffer list across Vim sessions.
  27. "
  28. " Installation
  29. " ------------
  30. " 1. Copy the mru.vim script to the $HOME/.vim/plugin directory. Refer to
  31. " ':help add-plugin', ':help add-global-plugin' and ':help runtimepath' for
  32. " more details about Vim plugins.
  33. " 2. Restart Vim.
  34. " 3. You can use the ":MRU" command to list and edit the recently used files.
  35. "
  36. " Usage
  37. " -----
  38. " You can use the ":MRU" command to list all the most recently used file
  39. " names. The file names will be listed in a temporary Vim window. If the MRU
  40. " list window is already opened, then the MRU list displayed in the window
  41. " will be refreshed.
  42. "
  43. " You can use the normal Vim commands to move around the window. You cannot
  44. " make changes in the window.
  45. "
  46. " You can select a file name to edit by pressing the <Enter> key or by double
  47. " clicking the left mouse button on a file name. The selected file will be
  48. " opened.
  49. "
  50. " You can press the 'o' key to open the file name under the cursor in the
  51. " MRU window in a new window.
  52. "
  53. " You can press the 'u' key in the MRU window to update the file list. This is
  54. " useful if you keep the MRU window open.
  55. "
  56. " You can close the MRU window by pressing the 'q' key or using one of the Vim
  57. " window commands.
  58. "
  59. " Configuration
  60. " -------------
  61. " By changing the following variables you can configure the behavior of this
  62. " plugin. Set the following variables in your .vimrc file using the 'let'
  63. " command.
  64. "
  65. " By default, the plugin will remember the names of the last 10 used files.
  66. " As you edit more files, old file names will be removed from the MRU list.
  67. " You can set the 'MRU_Max_Entries' variable to remember more file names. For
  68. " example, to remember 50 most recently used file names, you can use
  69. "
  70. " let MRU_Max_Entries = 50
  71. "
  72. " By default, all the edited file names will be added to the MRU list. If you
  73. " want to exclude file names matching a list of patterns, you can set the
  74. " MRU_Exclude_Files variable to a list of Vim regular expressions. By default,
  75. " this variable is set to an empty string. For example, to not include files
  76. " in the temporary (/tmp, /var/tmp and d:\temp) directories, you can set the
  77. " MRU_Exclude_Files variable to
  78. "
  79. " let MRU_Exclude_Files = '^/tmp/.*\|^/var/tmp/.*' " For Unix
  80. " let MRU_Exclude_Files = '^c:\\temp\\.*' " For MS-Windows
  81. "
  82. " The specified pattern should be a Vim regular expression pattern.
  83. "
  84. " The default height of the MRU window is 8. You can set the MRU_Window_Height
  85. " variable to change the window height.
  86. "
  87. " let MRU_Window_Height = 15
  88. "
  89. " By default, when the :MRU command is invoked, the MRU list will be displayed
  90. " in a new window. Instead, if you want the MRU plugin to reuse the current
  91. " window, then you can set the 'MRU_Use_Current_Window' variable to one.
  92. "
  93. " let MRU_Use_Current_Window = 1
  94. "
  95. " The MRU plugin will reuse the current window. When a file name is selected,
  96. " the file is also opened in the current window.
  97. "
  98. " When you select a file from the MRU window, the MRU window will be
  99. " automatically closed and the selected file will be opened in the previous
  100. " window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU
  101. " window open.
  102. "
  103. " let MRU_Auto_Close = 0
  104. "
  105. " ****************** Do not modify after this line ************************
  106. if exists('loaded_mru') || &cp || !has('viminfo')
  107. finish
  108. endif
  109. let loaded_mru=1
  110. " Maximum number of entries allowed in the MRU list
  111. if !exists('MRU_Max_Entries')
  112. let MRU_Max_Entries = 10
  113. endif
  114. " Files to exclude from the MRU list
  115. if !exists('MRU_Exclude_Files')
  116. let MRU_Exclude_Files = ''
  117. endif
  118. " Height of the MRU window
  119. " Default height is 8
  120. if !exists('MRU_Window_Height')
  121. let MRU_Window_Height = 8
  122. endif
  123. if !exists('MRU_Use_Current_Window')
  124. let MRU_Use_Current_Window = 0
  125. endif
  126. if !exists('MRU_Auto_Close')
  127. let MRU_Auto_Close = 1
  128. endif
  129. " The MRU plugin relies on the 'viminfo' feature to store and restore the MRU
  130. " list.
  131. " If the 'viminfo' option is not set then set it to the Vim default value
  132. if &viminfo == ''
  133. set viminfo&vim
  134. endif
  135. " Add (prepend) the ! flag to remember global variables names across Vim
  136. " sessions
  137. set viminfo^=!
  138. if !exists('MRU_LIST')
  139. let MRU_LIST = ''
  140. endif
  141. " MRU_AddFile
  142. " Add a file to the MRU file list
  143. function! s:MRU_AddFile()
  144. " Get the full path to the filename
  145. let fname = fnamemodify(expand('<afile>'), ':p')
  146. if fname == ''
  147. return
  148. endif
  149. " Skip temporary buffer with buftype set
  150. if &buftype != ''
  151. return
  152. endif
  153. if g:MRU_Exclude_Files != ''
  154. " Do not add files matching the pattern specified in the
  155. " MRU_Exclude_Files to the MRU list
  156. if fname =~? g:MRU_Exclude_Files
  157. return
  158. endif
  159. endif
  160. let already_present = 0
  161. " If the filename is already present in the MRU list, then move
  162. " it to the beginning of the list
  163. let idx = stridx(g:MRU_LIST, fname)
  164. if idx != -1
  165. let already_present = 1
  166. " Remove the entry from the list by extracting the text before it
  167. " and then the text after it and then concatenate them
  168. let text_before = strpart(g:MRU_LIST, 0, idx)
  169. let rem_text = strpart(g:MRU_LIST, idx)
  170. let next_idx = stridx(rem_text, "\n")
  171. let text_after = strpart(rem_text, next_idx + 1)
  172. let g:MRU_LIST = text_before . text_after
  173. endif
  174. " If the file is not present in the system and was not already present in
  175. " the MRU list, then skip it
  176. if !already_present && !filereadable(fname)
  177. return
  178. endif
  179. " Allow (retain) only MRU_Max_Entries in the MRU list. Remove/discard
  180. " the remaining entries. As we are adding a one entry to the list,
  181. " the list should have only MRU_Max_Entries - 1 in it.
  182. let cnt = g:MRU_Max_Entries - 1
  183. let mru_list = g:MRU_LIST
  184. let g:MRU_LIST = ''
  185. while cnt > 0 && mru_list != ''
  186. " Extract one filename from the list
  187. let one_line = strpart(mru_list, 0, stridx(mru_list, "\n"))
  188. " Remove the extracted line from the list
  189. let mru_list = strpart(mru_list, stridx(mru_list, "\n") + 1)
  190. " Add it to the global MRU list
  191. let g:MRU_LIST = g:MRU_LIST . one_line . "\n"
  192. " One more entry used up
  193. let cnt = cnt - 1
  194. endwhile
  195. " Add the new filename to the beginning of the MRU list
  196. let g:MRU_LIST = fname . "\n" . g:MRU_LIST
  197. " If the MRU window is open, update the displayed MRU list
  198. let bname = '__MRU_Files__'
  199. let winnum = bufwinnr(bname)
  200. if winnum != -1
  201. let cur_winnr = winnr()
  202. call s:MRU_Display()
  203. if winnr() != cur_winnr
  204. exe cur_winnr . 'wincmd w'
  205. endif
  206. endif
  207. endfunction
  208. " MRU_EditFile
  209. " Open a file selected from the MRU window
  210. function! s:MRU_EditFile(new_window)
  211. let fname = getline('.')
  212. if fname == ''
  213. return
  214. endif
  215. if a:new_window
  216. exe 'leftabove new ' . fname
  217. else
  218. " If the selected file is already open in one of the windows,
  219. " jump to it
  220. let winnum = bufwinnr(fname)
  221. if winnum != -1
  222. exe winnum . 'wincmd w'
  223. else
  224. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  225. " Automatically close the window if the file window is
  226. " not used to display the MRU list.
  227. silent! close
  228. " Jump to the window from which the MRU window was opened
  229. if exists('s:MRU_last_buffer')
  230. exe 'let last_winnr = bufwinnr(' . s:MRU_last_buffer ')'
  231. if last_winnr != -1 && last_winnr != winnr()
  232. exe last_winnr . 'wincmd w'
  233. endif
  234. endif
  235. else
  236. if g:MRU_Use_Current_Window == 0
  237. " Goto the previous window
  238. " If MRU_Use_Current_Window is set to one, then the
  239. " current window is used to open the file
  240. wincmd p
  241. endif
  242. endif
  243. " Edit the file
  244. let bno = bufnr(fname)
  245. if bno != -1
  246. exe 'buffer ' . bno
  247. else
  248. exe 'edit ' . fname
  249. endif
  250. endif
  251. endif
  252. endfunction
  253. " MRU_Display
  254. " Display the Most Recently Used file list in a temporary window.
  255. function! s:MRU_Display()
  256. " Empty MRU list
  257. if g:MRU_LIST == ''
  258. echohl WarningMsg | echo 'MRU List is empty' | echohl None
  259. return
  260. endif
  261. " Save the current buffer number. This is used later to open a file when a
  262. " entry is selected from the MRU window. The window number is not saved,
  263. " as the window number will change when new windows are opened.
  264. let s:MRU_last_buffer = bufnr('%')
  265. let bname = '__MRU_Files__'
  266. " If the window is already open, jump to it
  267. let winnum = bufwinnr(bname)
  268. if winnum != -1
  269. if winnr() != winnum
  270. " If not already in the window, jump to it
  271. exe winnum . 'wincmd w'
  272. endif
  273. setlocal modifiable
  274. " Delete the contents of the buffer to the black-hole register
  275. silent! %delete _
  276. else
  277. if g:MRU_Use_Current_Window
  278. " Reuse the current window
  279. "
  280. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  281. " a new buffer
  282. let bufnum = bufnr(bname)
  283. if bufnum == -1
  284. let wcmd = bname
  285. else
  286. let wcmd = '+buffer' . bufnum
  287. endif
  288. exe 'silent! edit ' . wcmd
  289. else
  290. " Open a new window at the bottom
  291. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  292. " a new buffer
  293. let bufnum = bufnr(bname)
  294. if bufnum == -1
  295. let wcmd = bname
  296. else
  297. let wcmd = '+buffer' . bufnum
  298. endif
  299. exe 'silent! botright ' . g:MRU_Window_Height . 'split ' . wcmd
  300. endif
  301. endif
  302. " Mark the buffer as scratch
  303. setlocal buftype=nofile
  304. setlocal bufhidden=delete
  305. setlocal noswapfile
  306. setlocal nowrap
  307. setlocal nobuflisted
  308. " Create a mapping to jump to the file
  309. nnoremap <buffer> <silent> <CR> :call <SID>MRU_EditFile(0)<CR>
  310. nnoremap <buffer> <silent> o :call <SID>MRU_EditFile(1)<CR>
  311. nnoremap <buffer> <silent> u :MRU<CR>
  312. nnoremap <buffer> <silent> <2-LeftMouse> :call <SID>MRU_EditFile(0)<CR>
  313. nnoremap <buffer> <silent> q :close<CR>
  314. " Display the MRU list
  315. silent! 0put =g:MRU_LIST
  316. setlocal nomodifiable
  317. endfunction
  318. " Autocommands to detect the most recently used files
  319. autocmd BufRead * call s:MRU_AddFile()
  320. autocmd BufNewFile * call s:MRU_AddFile()
  321. autocmd BufWritePost * call s:MRU_AddFile()
  322. " Command to open the MRU window
  323. command! -nargs=0 MRU call s:MRU_Display()