mru.vim 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. " File: mru.vim
  2. " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
  3. " Version: 1.6
  4. " Last Modified: July 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 . "\n")
  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. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  223. " Automatically close the window if the file window is
  224. " not used to display the MRU list.
  225. silent! close
  226. endif
  227. " As the window numbers will change after closing a window,
  228. " get the window number again and jump to it, if the cursor
  229. " is not already in that window
  230. let winnum = bufwinnr(fname)
  231. if winnum != winnr()
  232. exe winnum . 'wincmd w'
  233. endif
  234. else
  235. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  236. " Automatically close the window if the file window is
  237. " not used to display the MRU list.
  238. silent! close
  239. " Jump to the window from which the MRU window was opened
  240. if exists('s:MRU_last_buffer')
  241. exe 'let last_winnr = bufwinnr(' . s:MRU_last_buffer ')'
  242. if last_winnr != -1 && last_winnr != winnr()
  243. exe last_winnr . 'wincmd w'
  244. endif
  245. endif
  246. else
  247. if g:MRU_Use_Current_Window == 0
  248. " Goto the previous window
  249. " If MRU_Use_Current_Window is set to one, then the
  250. " current window is used to open the file
  251. wincmd p
  252. endif
  253. endif
  254. " Edit the file
  255. let bno = bufnr(fname)
  256. if bno != -1
  257. exe 'buffer ' . bno
  258. else
  259. exe 'edit ' . fname
  260. endif
  261. endif
  262. endif
  263. endfunction
  264. " MRU_Display
  265. " Display the Most Recently Used file list in a temporary window.
  266. function! s:MRU_Display()
  267. " Empty MRU list
  268. if g:MRU_LIST == ''
  269. echohl WarningMsg | echo 'MRU List is empty' | echohl None
  270. return
  271. endif
  272. " Save the current buffer number. This is used later to open a file when a
  273. " entry is selected from the MRU window. The window number is not saved,
  274. " as the window number will change when new windows are opened.
  275. let s:MRU_last_buffer = bufnr('%')
  276. let bname = '__MRU_Files__'
  277. " If the window is already open, jump to it
  278. let winnum = bufwinnr(bname)
  279. if winnum != -1
  280. if winnr() != winnum
  281. " If not already in the window, jump to it
  282. exe winnum . 'wincmd w'
  283. endif
  284. setlocal modifiable
  285. " Delete the contents of the buffer to the black-hole register
  286. silent! %delete _
  287. else
  288. if g:MRU_Use_Current_Window
  289. " Reuse the current window
  290. "
  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! edit ' . wcmd
  300. else
  301. " Open a new window at the bottom
  302. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  303. " a new buffer
  304. let bufnum = bufnr(bname)
  305. if bufnum == -1
  306. let wcmd = bname
  307. else
  308. let wcmd = '+buffer' . bufnum
  309. endif
  310. exe 'silent! botright ' . g:MRU_Window_Height . 'split ' . wcmd
  311. endif
  312. endif
  313. " Mark the buffer as scratch
  314. setlocal buftype=nofile
  315. setlocal bufhidden=delete
  316. setlocal noswapfile
  317. setlocal nowrap
  318. setlocal nobuflisted
  319. " Create a mapping to jump to the file
  320. nnoremap <buffer> <silent> <CR> :call <SID>MRU_EditFile(0)<CR>
  321. nnoremap <buffer> <silent> o :call <SID>MRU_EditFile(1)<CR>
  322. nnoremap <buffer> <silent> u :MRU<CR>
  323. nnoremap <buffer> <silent> <2-LeftMouse> :call <SID>MRU_EditFile(0)<CR>
  324. nnoremap <buffer> <silent> q :close<CR>
  325. " Display the MRU list
  326. silent! 0put =g:MRU_LIST
  327. setlocal nomodifiable
  328. endfunction
  329. " Autocommands to detect the most recently used files
  330. autocmd BufRead * call s:MRU_AddFile()
  331. autocmd BufNewFile * call s:MRU_AddFile()
  332. autocmd BufWritePost * call s:MRU_AddFile()
  333. " Command to open the MRU window
  334. command! -nargs=0 MRU call s:MRU_Display()