John Lenz avatar John Lenz committed 2654652

Start working on next post

Comments (0)

Files changed (1)

posts/2013-05-08-latex-vim-plugins-part2.markdown

+---
+title: LaTeX and Vim Part 2
+author: John Lenz
+tags: latex, vim
+date: May 8, 2013
+---
+
+As I mentioned in the [last post](2013-04-05-latex-vim-plugins.html), I no longer use the Vim-LaTeX
+plugin but have replaced it with several single-purpose plugins.
+
+# Forward Search
+
+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
+"Vim Evince Forward Search") but all the results from that google search didn't work for me because
+they use the Evince dbus API and the dbus API has changed since those were posted, breaking the
+code.
+
+Instead, I wrote a very simple forward search that avoids the DBUS API and instead uses the command
+line.  It has a better chance of continuing to work in the future whereas the more complicated
+methods with the DBUS API will require effort to be kept up to date. Here is the code I wrote; it is
+located at ~/academic/tools/ftplugin/tex.vim.
+
+~~~ {.vim}
+"Load PDF to the page containing label
+function! LoadEvinceByLabel(l)
+	for f in split(glob("*.aux"))
+		let label = system('grep "^.newlabel{' . a:l . '" ' . f)
+		let page = matchstr(label, '.\{}{\zs.*\ze}}')
+		if ! empty(page)
+			call OpenPDF(substitute(f, "aux$", "pdf", ""), page)
+			return
+		endif
+	endfor
+endfunction
+com! -nargs=1 -complete=tag Pdf call LoadEvinceByLabel("<args>")
+
+"Load PDF to the page containing the nearest previous label to the cursor
+function! EvinceNearestLabel()
+	let line = search("\\label{", "bnW")
+	if line > 0
+		let m = matchstr(getline(line), '\\label{\zs[^}]*\ze}')
+		if empty(m)
+			echomsg "No label between here and start of file"
+		else
+			call LoadEvinceByLabel(m)
+		endif
+	endif
+endfunction
+map <buffer> <LocalLeader>e :call EvinceNearestLabel()<CR>
+
+function! OpenPDF(file,page)
+	exec 'silent ! evince --page-label=' . a:page . ' ' . a:file . ' > /dev/null 2>&1 &'
+endfunction
+~~~
+
+To use it, you can either use ":Pdf <label>" with tab completion if you have set up the tag
+generation, or you can use \e to have Vim search earlier in the file from the cursor for a label and
+open the PDF to the page containing that label.  I should perhaps add the ability to search up and
+down and pick the nearer label.  To quickly navigate around, I use Ctrl-P on tags so I can, with a
+few keystrokes, jump in Vim to the label and then open evince.
+
+There is code for the gedit forward search plugin
+[synctex](https://git.gnome.org/browse/gedit-plugins/tree/plugins/synctex) which seems to keep up to
+date with the changing evince dbus API, so perhaps it could be used as the basis for a forward
+search Vim plugin.
+
+# Snippets and Folding
+
+I didn't like the way the Vim-LaTeX suite plugin did folding nor any of the plugins I looked at.
+Instead, I decided to use marker folding (:help fold-marker).  For marker folding to work, we need
+to insert {{{ and }}} into the files which is easy to do with the right snippets.  For snippets, I
+use [ultisnips](https://launchpad.net/ultisnips) but I rewrote my own snippets instead of using the
+ones built in to ultisnips.  For example, my section and subsection snippets are
+
+~~~ {.text}
+snippet sec
+\section{${1:section name}} % {{{1
+\label{sec:${2:$1}}
+
+$0
+endsnippet
+snippet sub
+\subsection{${1:subsection name}} % {{{2
+\label{sub:${2:$1}}
+
+$0
+endsnippet
+~~~
+
+Note the presence of markers.  Similarly, I have markers for various begin/end snippets, some of
+them folded, some of them not.  For example,
+
+~~~ {.text}
+snippet proof
+\begin{proof} % {{{
+$0
+\end{proof} % }}}
+endsnippet
+~~~
+
+But the similar snippet I have for lemma is not folded.  I also have snippets for generic begin
+(without markers) and beginf (with markers).
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.