Favourite places in vim

2019-03-26 14:31发布

问题:

Is there a command in vim that can bookmark a place (path to the file, line number in that file), so that I can go to that place easily later?

It would be similar as NERDTree :Bookmark command. You can open your file with NERDTreeFromBookmark. I'm looking for the same functionality with the difference that bookmark is not only a file but file + line number.

Thank you

回答1:

The viminfo setting can contain the option !, which makes it store any global variables with uppercase letters in the viminfo file. Using this, you can define a variable called g:BOOKMARKS and store your bookmarks in there.

Here's some vimscript you could use to do that:

set viminfo+=!

if !exists('g:BOOKMARKS')
  let g:BOOKMARKS = {}
endif

" Add the current [filename, cursor position] in g:BOOKMARKS under the given
" name
command! -nargs=1 Bookmark call s:Bookmark(<f-args>)
function! s:Bookmark(name)
  let file   = expand('%:p')
  let cursor = getpos('.')

  if file != ''
    let g:BOOKMARKS[a:name] = [file, cursor]
  else
    echom "No file"
  endif

  wviminfo
endfunction

" Delete the user-chosen bookmark
command! -nargs=1 -complete=custom,s:BookmarkNames DelBookmark call s:DelBookmark(<f-args>)
function! s:DelBookmark(name)
  if !has_key(g:BOOKMARKS, a:name)
    return
  endif

  call remove(g:BOOKMARKS, a:name)
  wviminfo
endfunction

" Go to the user-chosen bookmark
command! -nargs=1 -complete=custom,s:BookmarkNames GotoBookmark call s:GotoBookmark(<f-args>)
function! s:GotoBookmark(name)
  if !has_key(g:BOOKMARKS, a:name)
    return
  endif

  let [filename, cursor] = g:BOOKMARKS[a:name]

  exe 'edit '.filename
  call setpos('.', cursor)
endfunction

" Completion function for choosing bookmarks
function! s:BookmarkNames(A, L, P)
  return join(sort(keys(g:BOOKMARKS)), "\n")
endfunction

I'm not sure how readable the code is, but basically, the Bookmark command accepts a single parameter to use as a name. It will store the current filename and cursor position to the g:BOOKMARKS dictionary. You can use the GotoBookmark command with a mark name to go to it. DelBookmark works in the same way, but deletes the given mark. Both functions are tab-completed.

Another way to jump through them is by using this command:

" Open all bookmarks in the quickfix window
command! CopenBookmarks call s:CopenBookmarks()
function! s:CopenBookmarks()
  let choices = []

  for [name, place] in items(g:BOOKMARKS)
    let [filename, cursor] = place

    call add(choices, {
          \ 'text':     name,
          \ 'filename': filename,
          \ 'lnum':     cursor[1],
          \ 'col':      cursor[2]
          \ })
  endfor

  call setqflist(choices)
  copen
endfunction

CopenBookmarks will load the bookmarks in the quickfix window, which seems like a nice interface to me.

This solution is similar to Eric's -- it uses the .viminfo file, so if something goes wrong with it, you'll probably lose your marks. And if you save your marks in one vim instance, they won't be immediately available in another.

I don't know how comfortable your are with vimscript, so just in case -- to use this, you can put the code in a file under your plugin vimfiles directory, for example plugin/bookmarks.vim. Should be completely enough. Here's the entire code in a gist as well: https://gist.github.com/1371174

EDIT: Changed the interface for the solution a bit. Original version can be found in the gist history.



回答2:

Yes you can do so with the 'mark' command. There are two types of bookmarks you can create, local and global. You are referring to a global bookmark.

You can type 'mP' to create a bookmark called P. Notice the case, uppercase indicates it is a global bookmark. To go to that bookmark, type `P.

Hope this helps

Source



回答3:

I have used this script (number marks). There might be better ones though. Wait for other answers!



回答4:

This doesn't solve your problem as stated, but you may find it helps.

MRU.vim - Most Recently Used files plugin

Type :MRU and you get a nice searchable list of your most recently used files. Pressing enter on one brings you to it.



回答5:

" When editing a file, always jump to the last known cursor position.
" And open enough folds to make the cursor is not folded
" Don't do it when the position is invalid or when inside an event handler
" (happens when dropping a file on gvim).
autocmd BufWinEnter *
            \ if line("'\"") <= line("$") |
            \   exe "normal! g`\"" | exe "normal! zv" |
            \ endif