Commits

John Lenz committed 4738d60

Add post on forward search

  • Participants
  • Parent commits 0a01f58

Comments (0)

Files changed (3)

File posts/2013-04-05-latex-vim-plugins.markdown

 Vim-LaTeX plugin was the way it handled compilation and error messages, I didn't like the way it
 handled folding, I wanted more control over snippets, and there was quite a bit of the package I did
 not use.  Don't get me wrong, Vim-LaTeX is a great plugin and I was happy with it for a long time,
-but just small little things led me to investigate alternatives.  The companion post is
-[here](2013-05-09-latex-vim-plugins-part2.html).
+but just small little things led me to investigate alternatives.  See also [part
+2](2013-05-09-latex-vim-plugins-part2.html) and [part 3](2013-05-11-vim-latex-forward-search.html).
 
 # Managing Plugins
 

File posts/2013-05-09-latex-vim-plugins-part2.markdown

 
 # Forward Search
 
+**Update: After writing this post, I enhanced the forward search and describe it in [this
+post](2013-05-11-vim-latex-forward-search.html).**
+
 Forward search is the ability to open/change the page of the PDF editor to match the current cursor
 location inside Vim.  At the moment, my forward search is limited to opening the PDF viewer to the
 page containing a specific LaTeX label.  A more detailed forward search is possible (google search

File posts/2013-05-11-vim-latex-forward-search.markdown

+---
+title: Vim, LaTeX, Evince, and Forward Search
+author: John Lenz
+tags: latex, vim
+date: May 11, 2013
+---
+
+After writing the [previous post](2013-05-09-latex-vim-plugins-part2.html) (see also [part
+1](2013-04-05-latex-vim-plugins.html)), I started looking into a better forward search for LaTeX and
+Vim, specifically controlling evince via the dbus API.  These instructions work with GNOME 3.8
+(specifically evince 3.8.0 and gedit-plugins-3.8.1) and should work for future versions.  I am
+unsure if they will work for GNOME 3.6 and earlier.
+
+# SyncTex
+
+The way SyncTex works is that when compiling with pdflatex, you specify "-synctex=1" on the command
+line and a \<filename\>.synctex.gz file is then generated.  This synctex.gz file contains
+information about the input files and how the lines of the input file map to items in the pdf.
+Evince has code to parse these .synctex.gz files, so we just need to tell evince the pdf file, the
+input file, and the line number via a dbus method.
+
+I use rubber (see [the first post](2013-04-05-latex-vim-plugins.html)) to compile.  There is a [bug
+report](https://bugs.launchpad.net/ubuntu/+source/rubber/+bug/414431) for adding synctex support to
+rubber.  For now, I took the approach suggested by Smeuuh in the bug report.  In ~/bin, I added a
+file called pdflatex with the contents:
+
+~~~ {.bash}
+#!/bin/sh
+exec /usr/bin/pdflatex -synctex=1 "$@"
+~~~
+
+I also added *.synctex.gz to "make clean" in my generic makefile.
+
+# Evince DBUS Call
+
+Evince has a dbus method called SyncTex which takes the pdf filename, the input filename, a
+line number, and a timestamp.  We could make this dbus call directly from Vim using python, execute
+dbus-send from the command line, or run some external python script.  The main issue is in the
+future evince might change the dbus API.  Thankfully, the gedit synctex plugin contains a python
+script called
+[evince_dbus.py](https://git.gnome.org/browse/gedit-plugins/tree/plugins/synctex/synctex/evince_dbus.py)
+which makes the dbus call and can be called on the command line.  Presumably this script will be
+kept up to date since it is part of gedit, and so we can just directly call the latest version of
+the script from Vim.  I did make one minor change to the script.  The current version (as of May 11)
+hangs after sending the message when run from the command line.  The following minor change fixes
+this.
+
+~~~ {.diff}
+--- /usr/lib/gedit/plugins/synctex/evince_dbus.py	2013-04-15 13:42:37.000000000 -0500
++++ evince_dbus.py	2013-05-11 15:35:31.991411344 -0500
+@@ -178,10 +178,12 @@
+     logger.addHandler(ch)    
+     a = EvinceWindowProxy('file://' + path_output, True,logger=logger)
+     
++    loop = GObject.MainLoop()
++
+     def sync_view(ev_window, path_input, line_number):
+         ev_window.SyncView (path_input, (line_number, 1),0)
++        loop.quit()
+ 
+     GObject.timeout_add(400, sync_view, a, path_input, line_number)
+-    loop = GObject.MainLoop()
+     loop.run() 
+ # ex:ts=4:et:
+~~~
+
+I just installed the gedit-plugins Arch Linux package and made the above small change, but you could
+also download the evince_dbus.py file directly from git, it has no other dependencies on other files
+within gedit-plugins.
+
+# Vim
+
+To wire up Vim, I added the following to tex ftplugin script (located for me at
+~/academic/tools/ftplugin/tex.vim).
+
+~~~ {.vimscript}
+function! SyncTex()
+	let filename = bufname("%")
+	let lineno = line(".")
+	for syncfile in split(system('zgrep -l "' . filename . '" *.synctex.gz'), "\n")
+		let pdffile = substitute(syncfile, ".synctex.gz$", ".pdf", "")
+		exec 'silent ! python /usr/lib/gedit/plugins/synctex/evince_dbus.py ' .
+			\ '"' . pdffile . '" ' . lineno . ' "' . filename . '"'
+	endfor
+endfunction
+map <buffer> <LocalLeader>e :call SyncTex()<CR>
+~~~
+
+Almost all my papers are made up of multiple tex files which I \\input into one main file which is
+then compiled using rubber and make, so I needed a way to find the pdf given the currently open
+file.  The \<filename\>.synctex.gz contains all the filenames that went into building the
+corresponding pdf, so I use zgrep to find the synctex.gz file containing the current file.  I even
+have one project where the same source file is imported into two different compilations (the full
+paper and an executive summary), so the vimscript above will open both pdfs because it loops through
+all the lines returned by zgrep.
+
+# Backward Search
+
+I do not use backward search (clicking in evince to change vim to the cooresponding line) because
+[CtrlP](https://github.com/kien/ctrlp.vim) on tags (which the makefile generates from LaTeX labels)
+plus normal Vim movement commands like forward/back paragraph is very fast to navigate anywhere in
+my input, even for my 50+ page papers where the input is spread over 12-15 files.  Therefore I keep
+my fingers on the keyboard and use Vim forward search to scroll evince.  If I want to scroll evince
+down or move evince to a different section, I use vim movement commands like page down, paragraph
+down, and/or CtrlP, and then \\e to update the evince position. This way I keep my fingers on the
+keyboard and moving around large pdfs is very fast, faster even than scrolling with the mouse.  Also
+focus never leaves the vim window so at any time I can just type a vim command.  It feels a little
+strange at first to scroll evince by moving in Vim, but I quickly got the hang of it. Having said
+that, evince does support backward search and the evince_dbus.py script has some code for it which
+could be the basis for a vim plugin, perhaps importing evince_dbus.py from python vimscript.
+