├── after └── syntax │ └── qf.vim ├── plugin └── oldfiles.vim ├── LICENSE ├── doc └── oldfiles.txt ├── autoload └── oldfiles.vim └── README.md /after/syntax/qf.vim: -------------------------------------------------------------------------------- 1 | syntax match oldfilesNumber "^\d\+: " nextgroup=oldfilesFileName 2 | syntax match oldfilesFileName ".*" contained 3 | 4 | hi def link oldfilesNumber Normal 5 | hi def link oldfilesFileName Directory 6 | -------------------------------------------------------------------------------- /plugin/oldfiles.vim: -------------------------------------------------------------------------------- 1 | " oldfiles.vim 2 | " Populate the output of :oldfiles into the quickfix list 3 | " Author: Gregory Anders 4 | " License: Same as Vim itself 5 | 6 | if exists('g:loaded_oldfiles') 7 | finish 8 | endif 9 | let g:loaded_oldfiles = 1 10 | 11 | augroup oldfiles.vim 12 | autocmd! 13 | autocmd BufWinEnter ?* call oldfiles#add() 14 | autocmd BufDelete ?* call oldfiles#remove() 15 | augroup END 16 | 17 | nnoremap (Oldfiles) :call oldfiles#open(0, '') 18 | command! -nargs=? -bang Oldfiles call oldfiles#open(0, , ) 19 | 20 | if !hasmapto('(Oldfiles)', 'n') && mapcheck('g', 'n') ==# '' 21 | nmap g (Oldfiles) 22 | endif 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Gregory Anders 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /doc/oldfiles.txt: -------------------------------------------------------------------------------- 1 | *oldfiles.txt* Read :oldfiles into quickfix list 2 | 3 | Author: Gregory Anders 4 | Repo: https://github.com/gpanders/vim-oldfiles 5 | License: Same terms as Vim itself (see |license|) 6 | 7 | INTRODUCTION *Oldfiles* 8 | 9 | Vim provides a built-in method for viewing your recent file history with the 10 | |:oldfiles| command. This plugin seeks to complement and improve the built-in 11 | command by listing recent files in the quickfix list and keeping the oldfiles 12 | list up-to-date during your Vim session. 13 | 14 | *:Oldfiles* 15 | :Oldfiles 16 | Populate the oldfiles list into the quickfix list. The 17 | number that appears next to the filename in the 18 | quickfix list is the index of that file in the 19 | original |:oldfiles| command, allowing you to open the 20 | given file with |c_#<|. 21 | 22 | :Oldfiles[!] {pattern} 23 | Show oldfiles matching {pattern}. With [!] invert 24 | the match, showing only oldfiles that DO NOT match 25 | {pattern}. 26 | 'ignorecase' applies. To overrule it put |/\c| in the 27 | pattern to ignore case or |/\C| to match case. 28 | 'smartcase' is not used. 29 | 30 | ============================================================================== 31 | MAPPINGS *oldfiles-mappings* 32 | 33 | (Oldfiles) 34 | g Equivalent to |:Oldfiles| 35 | 36 | ============================================================================== 37 | OPTIONS *oldfiles-options* 38 | 39 | g:oldfiles_blacklist = [] *g:oldfiles_blacklist* 40 | List of patterns |pattern| that will always be omitted from the output of 41 | the |:Oldfiles| command. 42 | 43 | Example: > 44 | 45 | let g:oldfiles_blacklist = ['vim/runtime/doc'] 46 | < 47 | 48 | vim:tw=78:ts=8:noet:ft=help:norl: 49 | -------------------------------------------------------------------------------- /autoload/oldfiles.vim: -------------------------------------------------------------------------------- 1 | function! s:filter(val) abort 2 | if !filereadable(a:val) 3 | return 0 4 | endif 5 | 6 | if !exists('g:oldfiles_blacklist') || type(g:oldfiles_blacklist) != type([]) 7 | return 1 8 | endif 9 | 10 | for pat in g:oldfiles_blacklist 11 | if a:val =~# pat 12 | return 0 13 | endif 14 | endfor 15 | 16 | return 1 17 | endfunction 18 | 19 | function! oldfiles#textfunc(d) abort 20 | let items = getqflist({'id': a:d.id, 'items': v:true}).items 21 | let l = [] 22 | for i in range(a:d.start_idx - 1, a:d.end_idx - 1) 23 | let item = items[i] 24 | let fname = fnamemodify(bufname(item.bufnr), ':p') 25 | call add(l, item.nr . ': ' . fname) 26 | endfor 27 | return l 28 | endfunction 29 | 30 | function! oldfiles#add() abort 31 | " Add file to oldfiles when opened 32 | let fname = expand(':p') 33 | if empty(fname) || !filereadable(fname) || !&buflisted 34 | return 35 | endif 36 | 37 | let v:oldfiles = [fname] + filter(v:oldfiles, {_, f -> f !=# fname}) 38 | endfunction 39 | 40 | function! oldfiles#remove() abort 41 | " Remove file from oldfiles if it is no longer valid 42 | let fname = expand(':p') 43 | if empty(fname) || filereadable(fname) 44 | return 45 | endif 46 | 47 | call filter(v:oldfiles, {_, f -> f !=# fname}) 48 | endfunction 49 | 50 | function! oldfiles#open(bang, mods, ...) abort 51 | silent doautocmd QuickFixCmdPre Oldfiles 52 | let pat = a:0 ? a:1 : '//' 53 | let cmd = 'filter' . (a:bang ? '! ' : ' ') . pat . ' oldfiles' 54 | let oldfiles = split(execute(cmd), '\n') 55 | call filter(oldfiles, 's:filter(expand(split(v:val, ''^\d\+\zs:\s\+'')[1]))') 56 | call setqflist([], ' ', {'lines': oldfiles, 'efm': '%n: %f', 'title': ':Oldfiles', 'quickfixtextfunc': 'oldfiles#textfunc'}) 57 | silent doautocmd QuickFixCmdPost Oldfiles 58 | exe a:mods 'copen' 59 | endfunction 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vim-oldfiles 2 | ============ 3 | 4 | Improve Vim's native recent file history. 5 | 6 | Motivation 7 | ---------- 8 | 9 | Vim natively keeps a list of your file history in the `v:oldfiles` variable 10 | which you can see with the `:oldfiles` command or, even better, with `:browse 11 | oldfiles`. Unfortunately, `:oldfiles` has two significant drawbacks: 12 | 13 | 1. The output of the command takes up the entire screen and uses Vim's 14 | inelegant "more prompt". 15 | 2. The list of recent files is not updated as you use Vim, and is only 16 | re-written when you close Vim. One can get around this with the use of the 17 | `:wviminfo` and `:rviminfo` commands, but this is cumbersome and not very 18 | intuitive. 19 | 20 | This plugin enhances Vim's native capability by addressing these two problems. 21 | The command `:Oldfiles` uses `:oldfiles` under the hood, but presents a list of 22 | your recently visited files in the quickfix list. Once in the quickfix list, 23 | you can use all of the standard tools to navigate and search through your list 24 | of recent files (e.g. `:clist`, `:cc`, `:Cfilter`, and so on). **vim-oldfiles** 25 | will also automatically filter non-existent and unreadable files from the list, 26 | something vanilla `:oldfiles` does not do. 27 | 28 | Further, while you can natively filter the output of `:oldfiles` using the 29 | `:filter` command, this is a bit clunky. Instead, `:Oldfiles` (capital `O`) 30 | lets you pass a search pattern as an optional second argument to allow easy 31 | filtering. 32 | 33 | Before: 34 | 35 | ```vim 36 | :filter /pattern/ oldfiles 37 | ``` 38 | 39 | With **vim-oldfiles**: 40 | 41 | ```vim 42 | :Oldfiles /pattern/ 43 | ``` 44 | 45 | If you don't have any other conflicting user commands, this can be shortened 46 | even further to simply `:Old` or even `:Ol`. 47 | 48 | Most importantly, **vim-oldfiles** keeps the `v:oldfiles` variable up to date 49 | as you use Vim, so when you open a new buffer you will see it at the top of the 50 | `:Oldfiles` list. 51 | 52 | Usage 53 | ----- 54 | 55 | Use `:Oldfiles` to view your recent files in the quickfix list. You can also 56 | use `:Oldfiles {pattern}` to only show files matching that pattern, or 57 | `:Oldfiles! {pattern}` to only show files that do not match that pattern. 58 | 59 | This plugin provides a `(Oldfiles)` mapping which you can use to map the 60 | `:Oldfiles` command like so 61 | 62 | ```vim 63 | nmap (Oldfiles) 64 | ``` 65 | 66 | By default, this is mapped to `g`. 67 | 68 | See `:h Oldfiles` for more information. 69 | 70 | Installation 71 | ------------ 72 | 73 | ### Manual 74 | 75 | If your version of Vim supports packages (`has('packages')` returns `1`), 76 | simply clone this repository to `~/.vim/pack/gpanders/start/vim-oldfiles`. 77 | 78 | Otherwise, copy the `plugin` and `doc` directories into your Vim runtime folder 79 | (`$HOME/.vim` on macOS/Unix, `$HOME/vimfiles` on Windows) and run `:helptags 80 | ALL` to generate help tags. Use `:help Oldfiles` to view the help docs. 81 | 82 | ### Pathogen 83 | 84 | ```console 85 | cd ~/.vim/bundle 86 | git clone https://github.com/gpanders/vim-oldfiles.git 87 | ``` 88 | 89 | ### vim-plug 90 | 91 | ```vim 92 | Plug 'gpanders/vim-oldfiles' 93 | ``` 94 | 95 | FAQ 96 | --- 97 | 98 | **Q:** How can I make the oldfiles list automatically close after I select an 99 | entry? 100 | 101 | **A:** Add the following snippet to `~/.vim/after/ftplugin/qf.vim`: 102 | 103 | ```vim 104 | if get(w:, 'quickfix_title') =~# 'Oldfiles' 105 | nnoremap :cclose 106 | endif 107 | ``` 108 | 109 | or if you prefer to keep everything in your `~/.vim/vimrc` file, use: 110 | 111 | ```vim 112 | augroup oldfiles 113 | autocmd! 114 | autocmd FileType qf if get(w:, 'quickfix_title') =~# 'Oldfiles' | nnoremap :cclose | endif 115 | augroup END 116 | ``` 117 | 118 | See [here][explanation] for more information. 119 | 120 | [explanation]: https://github.com/gpanders/vim-oldfiles/issues/2#issuecomment-776442884 121 | --------------------------------------------------------------------------------