Skip to content

Support passing column in synctex inverse search? #3005

@user202729

Description

@user202729

Is your feature request related to a problem? Please describe it.

Currently, VimtexInverseSearch only supports passing line and file. It would be nice if it support column as well.

That said, currently TeX itself does not output column information. But this is in theory possible, I have a preliminary patch to luatex that implements this. https://github.com/user202729/luatex/tree/synctex-column

Since it's a lot of hassle to recompile LuaTeX just for this, this is a TeX+PDF+synctex file which hopefully is testable. a.zip

Describe the solution you'd like
Maybe something like this? (I try to make the change backwards compatible. Not sure about other editors but the suggested command works for Zathura for me.)

diff --git a/autoload/vimtex/view.vim b/autoload/vimtex/view.vim
index 90265f14..5879d46b 100644
--- a/autoload/vimtex/view.vim
+++ b/autoload/vimtex/view.vim
@@ -67,7 +67,8 @@ endfunction
 
 " }}}1
 
-function! vimtex#view#inverse_search(line, filename) abort " {{{1
+function! vimtex#view#inverse_search(line, filename, column) abort " {{{1
+  echom "line=".a:line.", column=".a:column
   " Only activate in VimTeX buffers
   if !exists('b:vimtex') | return -1 | endif
 
@@ -114,7 +115,7 @@ function! vimtex#view#inverse_search(line, filename) abort " {{{1
     execute g:vimtex_view_reverse_search_edit_cmd l:file
   endtry
 
-  execute 'normal!' a:line . 'G'
+  execute 'normal!' a:line . 'G' . (a:column ? a:column . '|' : '')
   if b:vimtex.viewer.xdo_check()
     call b:vimtex.viewer.xdo_focus_vim()
   endif
@@ -126,17 +127,18 @@ function! vimtex#view#inverse_search(line, filename) abort " {{{1
 endfunction
 
 " }}}1
-function! vimtex#view#inverse_search_cmd(line, filename) abort " {{{1
+function! vimtex#view#inverse_search_cmd(line, filename, column = 0) abort " {{{1
   " One may call this function manually, but the main usage is to through the
   " command "VimtexInverseSearch". See ":help vimtex-synctex-inverse-search"
   " for more info.
+  echom "first: column=".a:column
 
   if a:line > 0 && !empty(a:filename)
     try
       if has('nvim')
-        call s:inverse_search_cmd_nvim(a:line, a:filename)
+        call s:inverse_search_cmd_nvim(a:line, a:filename, a:column)
       else
-        call s:inverse_search_cmd_vim(a:line, a:filename)
+        call s:inverse_search_cmd_vim(a:line, a:filename, a:column)
       endif
     catch
     endtry
@@ -147,7 +149,7 @@ endfunction
 
 " }}}1
 
-function! s:inverse_search_cmd_nvim(line, filename) abort " {{{1
+function! s:inverse_search_cmd_nvim(line, filename, column) abort " {{{1
   if !filereadable(s:nvim_servernames) | return | endif
 
   for l:server in readfile(s:nvim_servernames)
@@ -159,15 +161,15 @@ function! s:inverse_search_cmd_nvim(line, filename) abort " {{{1
     call rpcnotify(l:socket,
           \ 'nvim_call_function',
           \ 'vimtex#view#inverse_search',
-          \ [a:line, a:filename])
+          \ [a:line, a:filename, a:column])
     call chanclose(l:socket)
   endfor
 endfunction
 
-function! s:inverse_search_cmd_vim(line, filename) abort " {{{1
+function! s:inverse_search_cmd_vim(line, filename, column) abort " {{{1
   for l:server in split(serverlist(), "\n")
     call remote_expr(l:server,
-          \ printf("vimtex#view#inverse_search(%d, '%s')", a:line, a:filename))
+          \ printf("vimtex#view#inverse_search(%d, '%s', %d)", a:line, a:filename, a:column))
   endfor
 endfunction
 
diff --git a/doc/vimtex.txt b/doc/vimtex.txt
index e2f7c60d..459da544 100644
--- a/doc/vimtex.txt
+++ b/doc/vimtex.txt
@@ -6037,6 +6037,10 @@ interested in learning how inverse-search configuration works, in which case
 one should read |vimtex-synctex-inverse-search|. The interpolation variables
 for Zathura configuration are `%{line}` and `%{input}`, not `%l` and `%f`.
 
+Zathura also supports `%{column}`, so if your synctex somehow supports column,
+you can put the following in your `zathurarc`: >conf
+  set synctex-editor-command "vim -v --not-a-term -T dumb -c \"VimtexInverseSearch %{line}:%{column} '%{input}'\""
+
 The main variant uses `xdotool` to help avoid duplicate Zathura instances.
 However, in some environments, `xdotool` is not available. Here the simple
 variant should work well.
diff --git a/plugin/vimtex.vim b/plugin/vimtex.vim
index bcf40dce..340a7f63 100644
--- a/plugin/vimtex.vim
+++ b/plugin/vimtex.vim
@@ -14,12 +14,21 @@ command! -nargs=* VimtexInverseSearch
 
 
 function! s:parse_args(args) abort
-  let l:line = matchstr(a:args, '^\s*\zs\d\+')
+  " Example:
+  " parse_args("5 a.tex") = [5, "a.tex"]
+  " parse_args("5 \"a.tex\"") = [5, "a.tex"]
+  " parse_args("5:3 a.tex") = [5, "a.tex", 3]
+  let l:line = matchstr(a:args, '^\s*\zs\d\+\%(:\d\+\)\?')
   if empty(l:line) | return [-1, ''] | endif
 
-  let l:file = matchstr(a:args, '^\s*\d\+\s*\zs.*')
+  let l:file = matchstr(a:args, '^\s*\d\+\%(:\d\+\)\?\s*\zs.*')
   let l:file = substitute(l:file, '\v^([''"])(.*)\1\s*', '\2', '')
   if empty(l:file) | return [-1, ''] | endif
 
-  return [str2nr(l:line), l:file]
+  let l:parts = split(l:line, ':')
+  if len(l:parts) == 2
+    return [str2nr(l:parts[0]), l:file, str2nr(l:parts[1])]
+  else
+    return [str2nr(l:line), l:file]
+  endif
 endfunction

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions