4

I am working on an omni-completion script where I use taglist() to search for the existence of a certain word. After obtaining that tag I now need to quickly jump to where the tag is defined and analyze the code around it.

How can I do this in a VimScript? Because I need to do this within an omni-completion script, I cannot change the window context and would prefer to keep the jump list intact.

4

You can obtain the filename and the line number (/search command) from the selected tag.

let tag = taglist()[42]
exe 'e '. (tag.filename)
exe ':'.(tag.cmd)

However, this won't push your 'open-and-go-to-the-right-place' into the tag stack as :tag would have. I've been able to trick vim into doing it in my lh-tags plugin. The current version of the (GPLv3) code that do so is the following:

" # Tag push/pop {{{2
" internal tmp tags file {{{3
if !exists('s:tags_jump')
  let s:tags_jump = tempname()
  let &tags .= ','.s:tags_jump
  let s:lines = []
endif

let s:lines = []

" lh#tags#jump {{{3
let s:k_tag_name__ = '__jump_tag__'
let s:k_nb_digits  = 5 " works with ~1 million jumps. Should be enough
function! lh#tags#jump(tagentry)
  let last = len(s:lines)+1
  " Assert s:tagentry.filename == expand('%:p')
  let filename = expand('%:p')

  let tag_name = s:k_tag_name__.repeat('0', s:k_nb_digits-strlen(last)).last
  let l = tag_name
    \ . "\t" . (filename)
    \ . "\t" . (a:tagentry.cmd)


  " test whether a new digit is used. In that case renumber every tags to have
  " a lexical order
  call add(s:lines, l)
  call writefile(s:lines, s:tags_jump)
  if exists('&l:tags')
    exe 'setlocal tags+='.s:tags_jump
  endif
  exe 'tag '.tag_name
endfunction

The plugin is maintained there: https://github.com/LucHermitte/lh-tags


Update since the clarifications in the question: You can use readfile() (IIRC) to load the file associated to the selected tag, without moving the cursor or anything. Then, if the tags file uses line numbers, finding the context will be trivial. If the command is a search command, use filter(), or better match() to get the context you are interesting in.

  • Thanks for sharing this @LucHermitte. I've just updated the question to explain that I need to do this within an omni-completion script. Since I cannot change the context of the window, I don't think that this will work, right? Even trying to restore the window context through pop seems to fail. – Vitor Mar 5 '15 at 21:51
  • OK. I've updated my answer. – Luc Hermitte Mar 5 '15 at 21:57
  • in my opinion the code you copied is not very helpful for the answer when compared to everything else and occupies much more area. Maybe you could keep only the link and leave the code out? – Vitor Mar 6 '15 at 11:11
  • 1
    That what I do usually, but SE policies don't appear as very tolerant towards link... – Luc Hermitte Mar 6 '15 at 12:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.