Vimtex: Backward search with terminal macvim and skim

Created on 23 Jan 2020  路  29Comments  路  Source: lervag/vimtex

I was able to get backward search work with GUI macvim with Skim using the settings described in vimtex-faq-skimviewer. But, I haven't been able to figure out how to do this with mvim in terminal, which requires /usr/local/bin/mvim -v. I tried to put /usr/local/bin/mvim -v under the Command of Skim but it didn't work.

bug

Most helpful comment

Instead of working around the issue of an outdated vim with mvim -v, it might be easier to install an up-to-date vim via homebrew.

For neovim, see :h vimtex-faq-neovim or https://github.com/lervag/vimtex/wiki/introduction#neovim;

TL;DR:

  1. Install the python modules pynvim and neovim-remote (e.g., pip3 install --user pynvim neovim-remote).
  2. Set let g:vimtex_compiler_progname = 'nvr' in your neovim init.vim
  3. Set Skim sync options to
  4. Preset: Custom
  5. Command: nvr
  6. Arguments: --remote +"%line" "%file"

Then backward search should work from both terminal neovim or the https://github.com/qvacua/vimr GUI (or any other GUI).

IMPORTANT: Skim _must_ be started by vimtex (either through compiler callback or explicitly via <leader>lv) for backward sync to work! (This is how Skim "knows" which neovim instance -- terminal or GUI -- to sync to.)

All 29 comments

I'm sorry, but I don't know much about Macs/OSX. Did you try to include the -v in the Args, that is:

     Command: /usr/local/bin/mvim
     Args:    -v --remote-silent +"%line" "%file"

Perhaps @clason has a better suggestion, he's been able to help with OSX related issues before.

No, that's the suggestion I would have made as well.

What is mvim? Is that the shim to launch the GUI MacVim from the command line? In this case, are you sure you need the -v? Skim has a built-in preset for MacVim (which doesn't use the -v), so if that no longer works, you should open an issue with the Skim developer. (If you want to open vim -- not mvim, there's no "mvim in a terminal" -- that's a different issue.)

In either case, this is not a vimtex issue but purely between Skim and MacVim -- there's nothing that vimtex can do here (apart from adapting the FAQ if it turns out to be wrong; maybe it's best to change this anyway to refer to the preset instead of a manual configuration?)

(I'm not using vim or MacVim anymore myself since switching to neovim.)

@clason Thanks, I'll consider updating the FAQ after settling the issue. And thanks for pitching in both here and at the other issue!

Both manual configuration and the built-in MacVim option works for me.

I thought mvim -v opens up MacVim within the terminal as I have been using it that way for a long time. I was hoping to somehow still use the MacVim in the terminal as the normal vim on Mac has some problems for other things I do.

Anyhow, the reverse search only works with the GUI MacVim for me after I tried vim, mvim -v(in terminal), mvim(GUI), and neovim. I'm making my way to neovim as well but haven't got any success for this issue as well.

Should I open another issue regarding neovim if I still can't get it work or should I keep it here?

Instead of working around the issue of an outdated vim with mvim -v, it might be easier to install an up-to-date vim via homebrew.

For neovim, see :h vimtex-faq-neovim or https://github.com/lervag/vimtex/wiki/introduction#neovim;

TL;DR:

  1. Install the python modules pynvim and neovim-remote (e.g., pip3 install --user pynvim neovim-remote).
  2. Set let g:vimtex_compiler_progname = 'nvr' in your neovim init.vim
  3. Set Skim sync options to
  4. Preset: Custom
  5. Command: nvr
  6. Arguments: --remote +"%line" "%file"

Then backward search should work from both terminal neovim or the https://github.com/qvacua/vimr GUI (or any other GUI).

IMPORTANT: Skim _must_ be started by vimtex (either through compiler callback or explicitly via <leader>lv) for backward sync to work! (This is how Skim "knows" which neovim instance -- terminal or GUI -- to sync to.)

I followed the instruction but it's still not working. nvim(0.4.3), Skim(1.5.2), iTerm(3.3.7).

Skim

Command: nvr
Arguments: --remote +"%line" "%file"

or

Command: nvr
Arguments: --servername /tmp/nvimsocket -c %line "%file"

as in #262

vimrc

if has('nvim')
  let g:vimtex_compiler_progname = 'nvr'
  let g:python3_host_prog = '/usr/local/bin/python3'
endif

then source vimrc in init.vim

I have multiple python installed and some with Anaconda.

$ where python3
/Users/zachariah/anaconda3/bin/python3
/usr/local/bin/python3
/usr/bin/python3

I manually import nvr pynvim and can confirm that both are installed for /usr/local/bin/python3

What does :checkhealth say? (The first config is working for me, so use that -- the issue is more than four years old.)

Screen Shot 2020-01-26 at 11 44 13
Screen Shot 2020-01-26 at 11 44 41

OK, I see that you are using coc. Could you you try (and post) a minimal init.vim (without sourcing a vimrc) that just loads vimtex and sets the viewer and progname options, and then compile a simple test.tex from vimtex and see if backward sync works with Skim? (Please document each step -- "it's not working" isn't much to go on.)

And if you could (temporarily) modify your environment such that anaconda is _not_ first (or in it at all), that would be helpful, too.

I started fresh as you suggest
init.vim

call plug#begin('~/.vim/plugged')
Plug 'lervag/vimtex'
call plug#end()
let g:vimtex_view_method = 'skim'
let g:tex_flavor = 'latex'
let g:vimtex_compiler_progname = 'nvr'
let g:python3_host_prog = '/usr/local/bin/python3'

skim

Command: nvr
Arguments: --remote +"%line" "%file"

Anaconda is not in PATH

$ where python3
/usr/local/bin/python3
/usr/bin/python3

with the minimal test.latex
\documentclass{article} \begin{document} \section{first} hello world \newpage \section{second} hello world second \end{document}
Compile: VimtexCompile successifully complied and opens a skim.
Forward Search: Change test.latex and save, updates appears in skim as well.
Reverse Search: cmd+shift-leftclick in skim has no response ( the source file in nvim doesn't move to the corresponding line)

Hmm, then I don't really see what you could be doing wrong. However, on rare occasions, I've had backward sync from Skim not working either; quitting Skim and re-opening from vimtex usually fixes this.

Thank you for your help. For now I can just use the GUI MacVim but it would be really nice if this can be sorted out.

For now I can just use the GUI MacVim but it would be really nice if this can be sorted out.

I'm sorry to say that if @clason is not able to help you, then neither am I. I have no idea why things are not working.

One thing you could try, though:

  1. Open test.tex with your choice of Vim flavor (neovim or mvim) in terminal.
  2. Check :echo v:servername.
  3. From a different terminal, do e.g. nvr --servername $SERVER --remote +5 test.tex, where $SERVER is the same as the output from step 2.

This should put the cursor to line 5 in your first instance (from step 1). Does it work?

  • Open ~/Desktop/latex/test.latex with Nvim
  • nvr --servername $SERVER --remote +5 test.latex create & open a new file ~/test.latex in Nvim

Second attempt with the file ~/test.tex does put the cursor to line 5. So it seems that nvr can't corretly locate the file name/path?

(Clicking in Skim still has no response for ~/test.tex even it worked for nvr)

@ZachariahPang Please take the time to write good updates. Both me and @clason are spending our spare time trying to help, and so far it is often asking you for more input. I am now confused: do you use .latex extensions? Is test.latex the same as test.tex? What do you mean with "Second attempt with ..."?

Although it may feel pedantic, please just give all the steps you use. So, I repeat:

  1. Open test.tex with your choice of Vim flavor (neovim or mvim) in terminal.
  2. Check :echo v:servername.
  3. From a different terminal, do e.g. nvr --servername $SERVER --remote +5 test.tex, where $SERVER is the same as the output from step 2.

This should put the cursor to line 5 in your first instance (from step 1). Does it work? It would help if you could write explicitly what you are doing and what output you get.

I'm sorry, this my first time doing this. Thank you all, @lervag @clason for your help.


test 1

  1. Open ~\Desktop\latex\test.latex with nvim in terminal 1. :heavy_check_mark:
  2. :echo v:servername :heavy_check_mark:
  3. From a new terminal, terminal 2, do nvr --servername $SERVER --remote +5 test.latex :heavy_multiplication_x:
    Result: Thiscreates and opens a new file~test.latex` in terminal 1
  4. cmd+shift-click in skim has no response :heavy_multiplication_x:

test 2

  1. Create and open another file directly in $HOME, ~\test.latex with nvim in terminal 1. :heavy_check_mark:
  2. (same as test 1):echo v:servername :heavy_check_mark:
  3. (same as test 1) From a new terminal, terminal 2, do nvr --servername $SERVER --remote +5 test.latex :heavy_check_mark:
    Result: Move the cursor in ~\test.latex in terminal 1 to line 5
  4. cmd+shift-click in skim has no response :heavy_multiplication_x:

test 3

  1. (same as test 1) Open another file ~\Desktop\latex\test.latex with nvim in terminal 1. :heavy_check_mark:
  2. (same as test 1) :echo v:servername :heavy_check_mark:
  3. (specify path) From a new terminal, terminal 2, do nvr --servername $SERVER --remote +5 ~\Desktop\latex\test.latex :heavy_check_mark:
    Result: Move the cursor in ~\Desktop\latex\test.latex in terminal 1 to line 5
  4. cmd+shift-click in skim has no response :heavy_multiplication_x:

I don't know if this is the problem, but it seems nvr assumes the file is in ~\ if the the full path is not given.


While testing for this, I found a very weird behavior and I think this might help.

  • Whenever I log out $USER and log in $USER, the first time opening the file ~\Desktop\latex\test.latex with nvim and VimtexCompile, the reverse search in Skim puts cursor in corresponding line. :heavy_check_mark:

  • Close the Skim, but keep the nvim open, and then VimtexCompile again works. :heavy_check_mark:

  • However, close and re-open the nvim, and then VimtexCompile would launch the skim but reverse search has no response. Any furthur trials have no response as well. :heavy_multiplication_x:

So it seems that only the first time (after log out and log in) launching nvim would work.

All above are done with minimial init.nvim and fully loaded init.nvim and both behave the same.

I just found that fully quit (click quit in the Dock or cmd-q) the skim before VimtexCompile would solve the reverse search problem. On my system, closing the skim window would not completely quit the application as it still shows in the cmd-tab app switcher. This explains the weird behavior I mentioned above. This may also explain the rare occasions you mentioned @clason

However, on rare occasions, I've had backward sync from Skim not working either; quitting Skim and re-opening from vimtex usually fixes this.

I just found that fully quit (click quit in the Dock or cmd-q) the skim before VimtexCompile would solve the reverse search problem. On my system, closing the skim window would not completely quit the application as it still shows in the cmd-tab app switcher. This explains the weird behavior I mentioned above. This may also explain the rare occasions you mentioned @clason

Ah, yes, this would explain the problem: When you open Skim from vimtex, it will be passed the correct v:servername. If you don't close Skim, but start a new instance of neovim, the v:servername will be out of sync.

As far as I can tell, this means that the present issue is resolved. Am I right? Or should we update the docs? If so, please suggest a first draft.

@ZachariahPang The behavior you describe for test1, test2 and test3 is the expected behavior (if any command from the terminal assumes a relative file path from the current directory -- not necessarily the home directory -- and backward sync will not work if Skim is not launched via vimtex. (And yes, I _did_ mean quit, not close, in my remark above; I think my issue is different still.)

@lervag If this could be fixed (vimtex always pushes a new v:servername even if Skim is already open), that would be even better. Is that possible? I can take a look at the Skim side tonight, but would appreciate a pointer on the vimtex side.

Also, maybe the FAQ on neovim (and/or Skim?) could be updated based on my comment above? It seems a bit more concise and explicit than the current version.

@lervag If this could be fixed (vimtex always pushes a new v:servername even if Skim is already open), that would be even better. Is that possible? I can take a look at the Skim side tonight, but would appreciate a pointer on the vimtex side.

I think everything should be possible from the Vim side of things. The question is if it is possible on the Skim side. Is it possible to use osascript to pass the current v:servername to Skim on every evocation of :VimtexView and store it in some variable, and then use this variable in the Args similar to how we use "%line"? If so, then I think this should be possible. Or, alternatively, we could change the entire Args setting on every invocation of :VimtexView?

Right now, the servername is not passed to Skim. The default is assumed. Thus, if you first open neovim, then open a second neovim and use this second one with Skim, I think Skim will try to communicate with the first neovim instance.

I've tried to update the docs. Let me know if you have further suggestions for the docs.

IMPORTANT: Skim must be started by vimtex (either through compiler callback or explicitly via lv) for backward sync to work! (This is how Skim "knows" which neovim instance -- terminal or GUI -- to sync to.)

I don't see how this is right. The osascript in skim.vim does not pass anything about the current Vim instance. Am I missing something?

Ah, I wasn't aware that vimtex (and Skim) relied on the default server name. Then you are right, there's nothing that can be done. But then how could vimtex and Skim ever go out of sync? They should always be using the same (default) server names.

The osascript in skim.vim does not pass anything about the current Vim instance. Am I missing something?

Yes, in this case this doesn't make sense. But I tend to have problems backward syncing without a running neovim instance that started the viewer, so I assumed that was the issue.

It seems that the intelligence is purely in neovim-remote; I'll have to grep through the source to understand what's happening. In any case, this is no longer a vimtex issue.

I've tried to update the docs. Let me know if you have further suggestions for the docs.

Skim has a built-in preset for MacVim, so I'd refer to that instead of the manual configuration. (And maybe mention pynvim in addition to nvr/neovim-remote for the sake of completeness?)

But then how could vimtex and Skim ever go out of sync? They should always be using the same (default) server names.

No. Skim assumes default servername, which is GVIM, VIM or similar, by default. On neovim, the default is a random temporary path, unless explicitly specified (see e.g. :help vimtex-faq-neovim). But, two instances of vim do not share the servername. So if there is a name clash, then a number is prepended. This can easily be seen with e.g. gvim: open two gvim sessions, first will have v:servername = 'GVIM', the next will be named GVIM1. Thus: They will _never_ use the same server names.

As I can't test things myself, it is difficult to write the docs. I'd be very happy to accept a PR with an updated text, though!

I was not aware of pynvim; feel free to suggest an update on this.


Regarding improvements: If it is possible to configure Skim through osascript, then it may be possible to set the correct servername as I mentioned above. Let me know if you find a way to do this. Else, it seems we are at ways end in this thread..?

I am specifically interested in neovim -- how does Skim know which neovim instance to backwards sync to? (From what you write, it _must_ be some neovim-remote magic that tries to guess the server name from the process list; not sure how.)

I checked the Skim website; it doesn't seem like it's possible to control the settings through AppleScript, so this is indeed the end of the line as far as vimtex is concerned.

For the docs, just two three small suggestions (and an almost fanatical devotion to the pope):

  1. Instead of "to configure ..." I would write "... go to Sync tab and set the options as follows:

    • for MacVim, select the MacVim preset from the drop-down list;
    • for neovim or VimR (neovim GUI), select the Custom preset from the drop-down list and set
      Command: nvr
      Args: --remote +"%line" "%file"
  2. For pynvim (which is the python module that allows controlling neovim through python; absolutely necessary for neovim-remote to work), I would just add that: "If you use neovim, please ensure that you have the nvr (neovim-remote) script and the pynvim Python module available, see vimtex-faq-neovim."

  3. Speaking of which, I'd massively simplify that FAQ to remove the explanations and just put the TL;DR:

    Q: Does vimtex work with neovim?
    A: Yes, but backward sync requires the neovim-remote script:

     1. Install the `pynvim` and `neovim-remote` modules for python3 (e.g., using `pip3 install --user pynvim neovim-remote`; if `python3 -c "import pynvim"` returns without error and `nvr` starts neovim from the command line, everything should be good to go).
    
     2. Add  `let g:vimtex_compiler_progname = 'nvr'` to your `init.vim`
    
     3. Configure your viewer to use `nvr --remote +"%line" "%file"` for backward sync (see viewer faq).
    

(I'd also remove the link to old issues; they are likely to contain outdated information.)

@clason Thanks for your input! I'm updating the docs based on your suggestions now.

I know I've read somewhere about how neovim-remote handles the servername. neovim-remote allows to list all servers with nvr --serverlist. I would guess that it makes a simple assumption that i) if only one instance is found, use that, or ii) if multiple servers exist, choose the oldest one. Perhaps nvr is even smarter, but you'd have to read the manual or source code; I don't know. :\

I checked the Skim website; it doesn't seem like it's possible to control the settings through AppleScript, so this is indeed the end of the line as far as vimtex is concerned.

Great, that settles it then.

I solved this using a little script.

First:

autocmd filetype tex nmap <buffer> <leader>ll :exe ":!echo " . v:servername . " > /tmp/curserver "<CR><plug>(vimtex-compile)

Second:

nvr --nostart --servername \`cat /tmp/curserver\`  --remote-send ":$1<CR>zOzz" 

Nice! I assume the vimscript part goes in your vimrc file and the second part is used in your Skim settings?

I think you could also do this with a callback:

let g:vimtex_compiler_callback_hooks = ['SetServerName']

function! SetServerName(status)
  call system('echo ' . v:servername . ' > /tmp/curserver')
endfunction

https://github.com/lervag/vimtex/issues/1576#issuecomment-578535928, updating pynvim to 0.4.1 with pip3 install --upgrade pynvim fixed backward-sync for me with the same skim settings (Command: nvr, Arguments: --remote +"%line" "%file") on nvim 0.5.0 and python 3.7.7

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adimanea picture adimanea  路  5Comments

lervag picture lervag  路  3Comments

itsShnik picture itsShnik  路  5Comments

benutzer193 picture benutzer193  路  4Comments

vsbuffalo picture vsbuffalo  路  3Comments