7

Using gF I can jump to a file with the format foobar.py:27:6 to open foobar.py on line 27. My question is how I can make this jump in vimscript?

For example, this won't work:

execute "normal gF " . foobar.py:27:6

because gF doesn't take an argument - it uses the word under the cursor - but hopefully this gives an impression of what I'm trying to do.

2 Answers 2

7

If you don't care about the column, and as an example you have the linenumber and filename in variables, you could do this:

execute "edit +" . linenumber . " " . filename

Or, as from your example

execute "edit +27 foobar.py"

To expand the colon separation and then edit would look like this:

let fileLine="foobar.py:27"
let filename=split(fileLine,":")[0]
let linenumber=split(fileLine,":")[1]
execute "edit +" . linenumber . " " . filename

I'm hard coding the value of fileLine there, but you could obtain it however you like. I'm ignoring the column for simplicity and because you only mentioned jumping to the line in your question.

0

I had the same need, because I run make from a split terminal below the code - so I often put the cursor on an error in the compiler's output and want to jump there with the split above.

The following functions and mappings will make gf do a find of the file, then go to the line and column (if present), in the split above. If you want it to use the same buffer, delete the wincmd k line.

It does not change any registers, and only adds a single jump to the :jumplist, even though there are two jumps in the implementation when a column is included.

" Open file at position from compiler error on the terminal
" e.g. foobar.adb:27:2: "X" not declared in "Y"
" results in opening foobar.adb in the top buffer (not the terminal), and issuing '27G2|'
" Default vim comes close with 'vt:<C-W>gf' - but:
" 1) including the [colon][linenumber] suffix does not work as intended in NeoVim
" 2) this does not include the column, 
" 3) you cannot reuse the top window.

fu! OpenfileInTopBuffer(selection)
  let elements=split(a:selection, ':')
  let elementlen=len(elements)
  let filename=elements[0]
  if elementlen > 1
    let line=elements[1]
    if elementlen > 2
      let column=elements[2]
    endif
  endif
  " switch to top buffer
  silent execute 'wincmd k'
  try
    " find the file 
    if elementlen > 1
      " keepjumps ensures the top of the file is not added to the jumplist
      silent execute 'keepjumps find ' . filename
    else
      silent execute 'find ' . filename
      return
    endif
    if elementlen >= 3
      " go to the indicated line and column
      silent execute 'normal! ' . line . 'G' . column . '|'
    else " elementlen == 2
      " go to the indicated line
      silent execute 'normal! ' . line . 'G'
    endif
  endtry
endfunction

augroup Terminal_gf_mapping
  autocmd!
  autocmd TermOpen * nnoremap <silent> <buffer> gf :call OpenfileInTopBuffer( expand('<cWORD>') )<CR>
augroup END
3
  • If youre using make, you might as well run :make and use the quickfix commands to navigate.
    – D. Ben Knoble
    Oct 27, 2019 at 15:10
  • tried that; :make does not execute make for me. I don't know why. The quickfix window is also not persistent. Oct 27, 2019 at 15:29
  • Odd—never had any issue with it myself. The default for 'makeprg' is make, afaik. Not sure what you mean by persistent though
    – D. Ben Knoble
    Oct 27, 2019 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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