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.

658 lines
21 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
  1. " File: mru.vim
  2. " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
  3. " Version: 3.0
  4. " Last Modified: January 12, 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 script to the $HOME/.vim/plugin or the
  23. " $HOME/vimfiles/plugin or the $VIM/vimfiles directory. Refer to the
  24. " ':help add-plugin', ':help add-global-plugin' and ':help runtimepath'
  25. " topics for more details about Vim plugins.
  26. " 2. Set the MRU_File Vim variable in the .vimrc file to the location of a
  27. " file to store the most recently edited file names. This step is needed
  28. " only if you want to change the default MRU filename.
  29. " 3. Restart Vim.
  30. " 4. You can use the ":MRU" command to list and edit the recently used files.
  31. " In GUI Vim, you can use the 'File->Recent Files' menu to access the
  32. " recently used files.
  33. "
  34. " Usage
  35. " -----
  36. " You can use the ":MRU" command to list all the most recently edited file
  37. " names. The file names will be listed in a temporary Vim window. If the MRU
  38. " window is already opened, then the MRU list displayed in the window will be
  39. " refreshed.
  40. "
  41. " If you are using GUI Vim, then the names of the recently edited files are
  42. " added to the "File->Recent Files" menu. You can select the name of a file
  43. " from this sub-menu to edit the file.
  44. "
  45. " You can use the normal Vim commands to move around in the MRU window. You
  46. " cannot make changes in the MRU window.
  47. "
  48. " You can select a file name to edit by pressing the <Enter> key or by double
  49. " clicking the left mouse button on a file name. The selected file will be
  50. " opened. If the file is already opened in a window, the cursor will be moved
  51. " to that window. Otherwise, the file is opened in the previous window. If the
  52. " previous window has a modified buffer or is the preview window or is used by
  53. " some other plugin, then the file is opened in a new window.
  54. "
  55. " You can press the 'o' key to open the file name under the cursor in the
  56. " MRU window in a new window.
  57. "
  58. " To open a file from the MRU window in a new tab, press the 't' key. If the
  59. " file is already opened in a window in the current or in another tab, then
  60. " the cursor is moved to that tab. Othewrise, a new tab is opened.
  61. "
  62. " You can press the 'u' key in the MRU window to update the file list. This is
  63. " useful if you keep the MRU window open always.
  64. "
  65. " You can close the MRU window by pressing the 'q' key or using one of the Vim
  66. " window commands.
  67. "
  68. " To display only files matching a pattern from the MRU list in the MRU
  69. " window, you can specify a pattern to the ":MRU" command. For example, to
  70. " display only file names containing "vim" in them, you can use the following
  71. " command ":MRU vim"
  72. "
  73. " You can use the ":MRUedit" command to edit files from the MRU list. This
  74. " command supports completion of file names from the MRU list. You can specify
  75. " a file either by the name or by the location in the MRU list.
  76. "
  77. " Whenever the MRU list changes, the MRU file is updated with the latest MRU
  78. " list. When you have multiple instances of Vim running at the same time, the
  79. " latest MRU list will show up in all the instances of Vim.
  80. "
  81. " Configuration
  82. " -------------
  83. " By changing the following variables you can configure the behavior of this
  84. " plugin. Set the following variables in your .vimrc file using the 'let'
  85. " command.
  86. "
  87. " The list of recently edit file names is stored in the file specified by the
  88. " MRU_File variable. The default setting for this variable is
  89. " $HOME/.vim_mru_files for Unix systems and $VIM/_vim_mru_files for non-Unix
  90. " systems. You can change this variable to point to a file by adding the
  91. " following line to the .vimrc file:
  92. "
  93. " let MRU_File = 'd:\myhome\_vim_mru_files'
  94. "
  95. " By default, the plugin will remember the names of the last 10 used files.
  96. " As you edit more files, old file names will be removed from the MRU list.
  97. " You can set the 'MRU_Max_Entries' variable to remember more file names. For
  98. " example, to remember 20 most recently used file names, you can use
  99. "
  100. " let MRU_Max_Entries = 20
  101. "
  102. " By default, all the edited file names will be added to the MRU list. If you
  103. " want to exclude file names matching a list of patterns, you can set the
  104. " MRU_Exclude_Files variable to a list of Vim regular expressions. By default,
  105. " this variable is set to an empty string. For example, to not include files
  106. " in the temporary (/tmp, /var/tmp and d:\temp) directories, you can set the
  107. " MRU_Exclude_Files variable to
  108. "
  109. " let MRU_Exclude_Files = '^/tmp/.*\|^/var/tmp/.*' " For Unix
  110. " let MRU_Exclude_Files = '^c:\\temp\\.*' " For MS-Windows
  111. "
  112. " The specified pattern should be a Vim regular expression pattern.
  113. "
  114. " The default height of the MRU window is 8. You can set the MRU_Window_Height
  115. " variable to change the window height.
  116. "
  117. " let MRU_Window_Height = 15
  118. "
  119. " By default, when the :MRU command is invoked, the MRU list will be displayed
  120. " in a new window. Instead, if you want the MRU plugin to reuse the current
  121. " window, then you can set the 'MRU_Use_Current_Window' variable to one.
  122. "
  123. " let MRU_Use_Current_Window = 1
  124. "
  125. " The MRU plugin will reuse the current window. When a file name is selected,
  126. " the file is also opened in the current window.
  127. "
  128. " When you select a file from the MRU window, the MRU window will be
  129. " automatically closed and the selected file will be opened in the previous
  130. " window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU
  131. " window open.
  132. "
  133. " let MRU_Auto_Close = 0
  134. "
  135. " ****************** Do not modify after this line ************************
  136. if exists('loaded_mru_autoload')
  137. finish
  138. endif
  139. let loaded_mru_autoload=1
  140. if v:version < 700
  141. finish
  142. endif
  143. " Line continuation used here
  144. let s:cpo_save = &cpo
  145. set cpo&vim
  146. " Maximum number of entries allowed in the MRU list
  147. if !exists('MRU_Max_Entries')
  148. let MRU_Max_Entries = 10
  149. endif
  150. " Files to exclude from the MRU list
  151. if !exists('MRU_Exclude_Files')
  152. let MRU_Exclude_Files = ''
  153. endif
  154. " Height of the MRU window
  155. " Default height is 8
  156. if !exists('MRU_Window_Height')
  157. let MRU_Window_Height = 8
  158. endif
  159. if !exists('MRU_Use_Current_Window')
  160. let MRU_Use_Current_Window = 0
  161. endif
  162. if !exists('MRU_Auto_Close')
  163. let MRU_Auto_Close = 1
  164. endif
  165. if !exists('MRU_File')
  166. if has('unix')
  167. let MRU_File = $HOME . "/.vim_mru_files"
  168. else
  169. let MRU_File = $VIM . "/_vim_mru_files"
  170. endif
  171. endif
  172. " MRU_LoadList
  173. " Load the latest MRU file list from the MRU file
  174. function! s:MRU_LoadList()
  175. " Read the list from the MRU file.
  176. if filereadable(g:MRU_File)
  177. let s:MRU_files = readfile(g:MRU_File)
  178. if s:MRU_files[0] =~# '^" Most recently edited files in Vim'
  179. " Generated by the previous version of the MRU plugin. Ignore the
  180. " list
  181. let s:MRU_files = []
  182. elseif s:MRU_files[0] =~# '^#'
  183. " Remove the comment line
  184. call remove(s:MRU_files, 0)
  185. endif
  186. else
  187. let s:MRU_files = []
  188. endif
  189. " Refresh the MRU menu
  190. call s:MRU_Refresh_Menu()
  191. endfunction
  192. " MRU_SaveList
  193. " Save the MRU list to the file
  194. function! s:MRU_SaveList()
  195. let l = []
  196. call add(l, '# Most recently edited files in Vim (version 3.0)')
  197. call extend(l, s:MRU_files)
  198. call writefile(l, g:MRU_File)
  199. endfunction
  200. " MRU_AddFile
  201. " Add a file to the MRU file list
  202. function! s:MRU_AddFile(acmd_bufnr)
  203. " Get the full path to the filename
  204. let fname = fnamemodify(bufname(a:acmd_bufnr + 0), ':p')
  205. if fname == ''
  206. return
  207. endif
  208. " Skip temporary buffer with buftype set
  209. if &buftype != ''
  210. return
  211. endif
  212. if g:MRU_Exclude_Files != ''
  213. " Do not add files matching the pattern specified in the
  214. " MRU_Exclude_Files to the MRU list
  215. if fname =~? g:MRU_Exclude_Files
  216. return
  217. endif
  218. endif
  219. " If the filename is already present in the MRU list, then move
  220. " it to the beginning of the list
  221. let idx = index(s:MRU_files, fname)
  222. if idx == -1
  223. if !filereadable(fname)
  224. " File is not readable and is not in the MRU list
  225. return
  226. endif
  227. endif
  228. " Load the latest MRU file list
  229. call s:MRU_LoadList()
  230. " Remove the new file name from the existing MRU list (if already present)
  231. call filter(s:MRU_files, 'v:val !=# fname')
  232. " Add the new file list to the beginning of the updated old file list
  233. call insert(s:MRU_files, fname, 0)
  234. " Return the trimmed list
  235. if len(s:MRU_files) > g:MRU_Max_Entries
  236. call remove(s:MRU_files, g:MRU_Max_Entries, -1)
  237. endif
  238. " Save the updated MRU list
  239. call s:MRU_SaveList()
  240. " Refresh the MRU menu
  241. call s:MRU_Refresh_Menu()
  242. " If the MRU window is open, update the displayed MRU list
  243. let bname = '__MRU_Files__'
  244. let winnum = bufwinnr(bname)
  245. if winnum != -1
  246. let cur_winnr = winnr()
  247. call s:MRU_Open_Window()
  248. if winnr() != cur_winnr
  249. exe cur_winnr . 'wincmd w'
  250. endif
  251. endif
  252. endfunction
  253. " MRU_Edit_File
  254. " Edit the specified file
  255. function! s:MRU_Edit_File(filename)
  256. let fname = escape(a:filename, ' %#')
  257. " If the file is already open in one of the windows, jump to it
  258. let winnum = bufwinnr('^' . fname . '$')
  259. if winnum != -1
  260. if winnum != winnr()
  261. exe winnum . 'wincmd w'
  262. endif
  263. else
  264. if &modified || &buftype != '' || &previewwindow
  265. " Current buffer has unsaved changes or is a special buffer or is
  266. " the preview window. So open the file in a new window
  267. exe 'split ' . fname
  268. else
  269. exe 'edit ' . fname
  270. endif
  271. endif
  272. endfunction
  273. " MRU_Window_Edit_File
  274. " Open a file selected from the MRU window
  275. " win_opt == useopen, open file in previous window
  276. " win_opt == newwin, open file in new window
  277. " win_opt == newtab, open file in new tab
  278. function! s:MRU_Window_Edit_File(win_opt)
  279. let fname = getline('.')
  280. if fname == ''
  281. return
  282. endif
  283. let fname = escape(fname, ' %#')
  284. if a:win_opt == 'newwin'
  285. " Edit the file in a new window
  286. exe 'leftabove new ' . fname
  287. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  288. " Go back to the MRU window and close it
  289. let cur_winnr = winnr()
  290. wincmd p
  291. silent! close
  292. if winnr() != cur_winnr
  293. exe cur_winnr . 'wincmd w'
  294. endif
  295. endif
  296. elseif a:win_opt == 'newtab'
  297. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  298. " Automatically close the window if the file window is
  299. " not used to display the MRU list.
  300. silent! close
  301. endif
  302. " If the selected file is already open in the current tab or in
  303. " another tab, jump to it. Otherwise open it in a new tab
  304. if bufwinnr('^' . fname . '$') == -1
  305. let tabnum = -1
  306. let i = 1
  307. let bnum = bufnr('^' . fname . '$')
  308. while i <= tabpagenr('$')
  309. if index(tabpagebuflist(i), bnum) != -1
  310. let tabnum = i
  311. break
  312. endif
  313. let i += 1
  314. endwhile
  315. if tabnum != -1
  316. " Goto the tab containing the file
  317. exe 'tabnext ' . i
  318. else
  319. " Open a new tab as the last tab page
  320. exe '999tabnew ' . escape(fname, ' ')
  321. endif
  322. endif
  323. " Jump to the window containing the file
  324. let winnum = bufwinnr('^' . fname . '$')
  325. if winnum != winnr()
  326. exe winnum . 'wincmd w'
  327. endif
  328. else
  329. " If the selected file is already open in one of the windows,
  330. " jump to it
  331. let winnum = bufwinnr('^' . fname . '$')
  332. if winnum != -1
  333. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  334. " Automatically close the window if the file window is
  335. " not used to display the MRU list.
  336. silent! close
  337. endif
  338. " As the window numbers will change after closing a window,
  339. " get the window number again and jump to it, if the cursor
  340. " is not already in that window
  341. let winnum = bufwinnr('^' . fname . '$')
  342. if winnum != winnr()
  343. exe winnum . 'wincmd w'
  344. endif
  345. else
  346. if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0
  347. " Automatically close the window if the file window is
  348. " not used to display the MRU list.
  349. silent! close
  350. " Jump to the window from which the MRU window was opened
  351. if exists('s:MRU_last_buffer')
  352. let last_winnr = bufwinnr(s:MRU_last_buffer)
  353. if last_winnr != -1 && last_winnr != winnr()
  354. exe last_winnr . 'wincmd w'
  355. endif
  356. endif
  357. else
  358. if g:MRU_Use_Current_Window == 0
  359. " Goto the previous window
  360. " If MRU_Use_Current_Window is set to one, then the
  361. " current window is used to open the file
  362. wincmd p
  363. endif
  364. endif
  365. " Edit the file
  366. if &modified || &buftype != '' || &previewwindow
  367. " Current buffer has unsaved changes or is a special buffer or
  368. " is the preview window. So open the file in a new window
  369. exe 'split ' . fname
  370. else
  371. exe 'edit ' . fname
  372. endif
  373. endif
  374. endif
  375. endfunction
  376. " MRU_Open_Window
  377. " Display the Most Recently Used file list in a temporary window.
  378. function! s:MRU_Open_Window(...)
  379. " Load the latest MRU file list
  380. call s:MRU_LoadList()
  381. " Empty MRU list
  382. if empty(s:MRU_files)
  383. echohl WarningMsg | echo 'MRU file list is empty' | echohl None
  384. return
  385. endif
  386. " Save the current buffer number. This is used later to open a file when a
  387. " entry is selected from the MRU window. The window number is not saved,
  388. " as the window number will change when new windows are opened.
  389. let s:MRU_last_buffer = bufnr('%')
  390. let bname = '__MRU_Files__'
  391. " If the window is already open, jump to it
  392. let winnum = bufwinnr(bname)
  393. if winnum != -1
  394. if winnr() != winnum
  395. " If not already in the window, jump to it
  396. exe winnum . 'wincmd w'
  397. endif
  398. setlocal modifiable
  399. " Delete the contents of the buffer to the black-hole register
  400. silent! %delete _
  401. else
  402. if g:MRU_Use_Current_Window
  403. " Reuse the current window
  404. "
  405. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  406. " a new buffer
  407. let bufnum = bufnr(bname)
  408. if bufnum == -1
  409. let cmd = 'edit ' . bname
  410. else
  411. let cmd = 'buffer ' . bufnum
  412. endif
  413. exe cmd
  414. if bufnr('%') != bufnr(bname)
  415. " Failed to edit the MRU buffer
  416. return
  417. endif
  418. else
  419. " Open a new window at the bottom
  420. " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open
  421. " a new buffer
  422. let bufnum = bufnr(bname)
  423. if bufnum == -1
  424. let wcmd = bname
  425. else
  426. let wcmd = '+buffer' . bufnum
  427. endif
  428. exe 'silent! botright ' . g:MRU_Window_Height . 'split ' . wcmd
  429. endif
  430. endif
  431. " Mark the buffer as scratch
  432. setlocal buftype=nofile
  433. setlocal bufhidden=delete
  434. setlocal noswapfile
  435. setlocal nowrap
  436. setlocal nobuflisted
  437. " Use fixed height for the MRU window
  438. if v:version >= 602
  439. setlocal winfixheight
  440. endif
  441. " Setup the cpoptions properly for the maps to work
  442. let old_cpoptions = &cpoptions
  443. set cpoptions&vim
  444. " Create a mapping to jump to the file
  445. nnoremap <buffer> <silent> <CR>
  446. \ :call <SID>MRU_Window_Edit_File('useopen')<CR>
  447. nnoremap <buffer> <silent> o
  448. \ :call <SID>MRU_Window_Edit_File('newwin')<CR>
  449. nnoremap <buffer> <silent> t
  450. \ :call <SID>MRU_Window_Edit_File('newtab')<CR>
  451. nnoremap <buffer> <silent> u :MRU<CR>
  452. nnoremap <buffer> <silent> <2-LeftMouse>
  453. \ :call <SID>MRU_Window_Edit_File('useopen')<CR>
  454. nnoremap <buffer> <silent> q :close<CR>
  455. " Restore the previous cpoptions settings
  456. let &cpoptions = old_cpoptions
  457. " Display the MRU list
  458. if a:0 == 0
  459. " No search pattern specified. Display the complete list
  460. silent! 0put =s:MRU_files
  461. else
  462. " Display only the entries matching the specified pattern
  463. silent! 0put =filter(copy(s:MRU_files), 'v:val =~? a:1')
  464. endif
  465. " Move the cursor to the beginning of the file
  466. exe 1
  467. setlocal nomodifiable
  468. endfunction
  469. " MRU_Edit_Complete
  470. " Command-line completion function used by :MRUedit command
  471. function! s:MRU_Edit_Complete(ArgLead, CmdLine, CursorPos)
  472. if a:ArgLead == ''
  473. " Return the list of MRU files
  474. return s:MRU_files
  475. else
  476. return filter(copy(s:MRU_files), 'v:val =~? a:ArgLead')
  477. endif
  478. endfunction
  479. " MRU_Edit_File_Cmd
  480. " Function to handle the MRUedit command
  481. function! s:MRU_Edit_File_Cmd(fspec)
  482. if a:fspec == ''
  483. return
  484. endif
  485. " Load the latest MRU file
  486. call s:MRU_LoadList()
  487. " User can specify either a number or a partial file name to
  488. " edit a file from the MRU list
  489. if a:fspec =~ '^\d\+$'
  490. " A number is specified
  491. let fnum = a:fspec
  492. if fnum <= 0 || fnum > len(s:MRU_files)
  493. echohl WarningMsg
  494. echo 'Error: valid range of values is 1 - ' . len(s:MRU_files)
  495. echohl None
  496. return
  497. endif
  498. " User index is 1 based, but the internal index is 0 based
  499. let fnum -= 1
  500. let fname = s:MRU_files[fnum]
  501. if fname != ''
  502. call s:MRU_Edit_File(fname)
  503. endif
  504. else
  505. " Locate the file name matching the supplied partial name
  506. " Escape backslash in the partial filename, otherwise regexp
  507. " comparison will fail
  508. let fpat = escape(a:fspec, '\')
  509. let l = filter(copy(s:MRU_files), 'v:val =~ fpat')
  510. if len(l) == 0
  511. echohl WarningMsg
  512. echo 'Error: No matching file for ' . a:fspec
  513. echohl None
  514. return
  515. endif
  516. if len(l) > 1
  517. echohl WarningMsg
  518. echo 'Error: More than one match for ' . a:fspec
  519. echohl None
  520. return
  521. endif
  522. let fname = l[0]
  523. call s:MRU_Edit_File(fname)
  524. endif
  525. endfunction
  526. " MRU_Refresh_Menu()
  527. " Refresh the MRU menu
  528. function! s:MRU_Refresh_Menu()
  529. if !has('menu')
  530. " No support for menus
  531. return
  532. endif
  533. " Setup the cpoptions properly for the maps to work
  534. let old_cpoptions = &cpoptions
  535. set cpoptions&vim
  536. " Remove the MRU menu
  537. " To retain the teared-off MRU menu, we need to add a dummy entry
  538. silent! unmenu &File.Recent\ Files
  539. noremenu &File.Recent\ Files.Dummy <Nop>
  540. silent! unmenu! &File.Recent\ Files
  541. anoremenu <silent> &File.Recent\ Files.Refresh\ list
  542. \ :call <SID>MRU_LoadList()<CR>
  543. anoremenu File.Recent\ Files.-SEP1- :
  544. " Add the filenames in the MRU list to the menu
  545. for fname in s:MRU_files
  546. " Escape special characters in the filename
  547. let esc_fname = escape(fnamemodify(fname, ':t'), ". \\|\t%#")
  548. " Truncate the directory name if it is long
  549. let dir_name = fnamemodify(fname, ':h')
  550. let len = strlen(dir_name)
  551. " Shorten long file names by adding only few characters from
  552. " the beginning and end.
  553. if len > 30
  554. let dir_name = strpart(dir_name, 0, 10) .
  555. \ '...' .
  556. \ strpart(dir_name, len - 20)
  557. endif
  558. let esc_dir_name = escape(dir_name, ". \\|\t")
  559. exe 'anoremenu <silent> &File.Recent\ Files.' . esc_fname .
  560. \ '\ (' . esc_dir_name . ')' .
  561. \ " :call <SID>MRU_Edit_File('" . fname . "')<CR>"
  562. endfor
  563. " Remove the dummy menu entry
  564. unmenu &File.Recent\ Files.Dummy
  565. " Restore the previous cpoptions settings
  566. let &cpoptions = old_cpoptions
  567. endfunction
  568. " Load the MRU list on plugin startup
  569. call s:MRU_LoadList()
  570. " Autocommands to detect the most recently used files
  571. autocmd BufRead * call s:MRU_AddFile(expand('<abuf>'))
  572. autocmd BufNewFile * call s:MRU_AddFile(expand('<abuf>'))
  573. autocmd BufWritePost * call s:MRU_AddFile(expand('<abuf>'))
  574. " Command to open the MRU window
  575. command! -nargs=? MRU call s:MRU_Open_Window(<q-args>)
  576. command! -nargs=1 -complete=customlist,s:MRU_Edit_Complete MRUedit
  577. \ call s:MRU_Edit_File_Cmd(<q-args>)
  578. " restore 'cpo'
  579. let &cpo = s:cpo_save
  580. unlet s:cpo_save