Lion icon Inverse Search with Xdvi(k) and (X)Emacs without AUCTeX

SourceForge.net Logo
Sourceforge Xdvik Project Page
Documentation

SourceForge Links


Introduction  |  (X)Emacs + gnuclient  |  Emacs + emacsclient  | 

Please send corrections and suggestions to Stefan Ulrich.

Introduction

This page contains instructions for using inverse search with xdvi(k) and (X)Emacs if you don't have AUCTeX available. If you are using AUCTeX (which is strongly recommended since it contains many useful features for creating (La)TeX documents), please use the instructions on this page instead. There you will also find instructions to set up inverse search with other editors.

Inverse search means that

  • A mouse click (Ctrl-Button1 by default) in the xdvi window can open an editor with the corresponding place in the (La)TeX source (also called `reverse search'), and
  • xdvi can jump to (and visually highlight) a position in the DVI file that corresponds to a certain line number in the (La)TeX source file (`forward search').

This functionality is supported by xdvi(k) versions 22.38 and upwards. It uses so-called `source specials' in the DVI file, which can be inserted via a macro package or a command-line option to the (La)TeX program (executable).

The macro packages are available as srctex.sty (for plain TeX) or srcltx.sty (for LaTeX) from CTAN:macros/latex/contrib/srcltx/.

The (La)TeX version that comes with teTeX-2.0 provides a command line option `-src' to insert these specials automatically. While the macro version might interact badly with other macro packages, the option for the (La)TeX executable should be more robust. However, both versions may affect the line breaks of your document, so it's generally a good idea to disable source specials for the final version of the document.

Xdvi setup

You'll need to tell xdvi which editor it should use for reverse search. This can be done in one of the following ways (assuming that you're using gnuclient - examples for emacsclient are given below):
  1. As a command-line option for xdvi(k). With most shells, the option string needs to be enclosed into double quotes if it contains spaces, e.g.:
              xdvi -editor "gnuclient -q +%l %f" file.dvi
              
  2. As an X resource setting. E.g. add the following line to the file ~/.Xdefaults:
              xdvi.editor: gnuclient -q +%l %f
              
    (note: no quotes in this case), and activate it with the following command:
              xrdb -merge ~/.Xdefaults
              
    See the xrdb(1) and X(1) man pages for more information.

  3. By using one of the environment variables XEDITOR, VISUAL or EDITOR, e.g. for (ba)sh:
    	  export XEDITOR="gnuclient -q"
    	  
    or for (t)csh:
    	  setenv XEDITOR "gnuclient -q"
    	  
    It's not recommended to use the `+%l %f' format strings for these variables, since they would confuse other programs that also use these variables. Xdvi will append them automatically. (Unfortunately, versions <= xdvik-22.40v will also show a warning popup message in this case; this warning has been disabled in later versions.)

(X)Emacs and gnuclient

Note: Most recent versions of GNU Emacs don't come with gnuclient; in that case, use the instructions for emacsclient below.
  1. Reverse search:

    • As `editor' option/X resource for xdvi(k), use:
                gnuclient -q +%l %f
                
    • With With Emacs >= 19.34 and <= 20.3, it might be neccessary to use:
                   (autoload 'gnuserv-start "gnuserv-comp")
                
    • Put the following line into your .(x)emacs file:
                (gnuserv-start)
                
    • If you don't want (X)Emacs to open a new frame for each editor call, and want the frame to be auto-raised, set "Gnuserv Frame" to "Use selected frame", and add the "raise-frame" function to "Visit Hook". To make these settings, invoke
                M-x customize-group RET gnuserv
                
      The resulting entries in your .(x)emacs should look like this:
           (custom-set-variables
              ;;; ... other stuff ...
      	'(gnuserv-frame t)
              '(gnuserv-visit-hook (lambda () (raise-frame) (recenter))))
                
  2. Forward Search

    Use xdvi-search.el (also contained in the texk/xdvik/ subdirectory of the xdvik distribution. Note: for versions of xdvik older than 22.74.2 and non-k xdvi, you should use this version of xdvi-search.el instead.)

Emacs and emacsclient

  1. Reverse search

    • With Emacs >= 20.3:
      • As `editor' option/X resource for xdvi(k), use:
                  emacsclient --no-wait +%l %f
                  
      • Add the line "(server-start)" to your .emacs file.
      • If you want the frame to be auto-raised, add the raise-frame function to server-switch-hook (do
        M-x customize-variable RET server-switch-hook
        and enter the function name into the text field.)
    • With Emacs 19.34:
      • The emacsclient version built with this Emacs version doesn't have the --no-wait feature, so the `editor' option/X resource for xdvi(k) should be:
                  emacsclient +%l %f
                  
        Unfortunately this means that xdvi will `freeze' after every reverse search until you type C-x # in Emacs to quit editing the buffer. The only way I know of to fix this is to remove the waiting loop before the call to `return' in emacsclient.c -- it's a simple change, but it requires recompiling emacsclient.
    • WARNING: An annoying behaviour of emacsclient is that if you changed the buffer since your last save (i.e. between the last save and the reverse search), Emacs will ask you:
                Revert buffer from file xyz? (yes or no)
                
      You will almost always want to answer no to that, since reverting the buffer would mean that the file's last saved status is reread from disk, causing all your changes since the last save to be lost!

      In my view, gnuclient's behaviour of just revisiting the buffer is preferable. The following piece of advice for the server-visit-files function emulates this behaviour for emacsclient, with the restriction that it only works for visiting one buffer with emacsclient at a time:

      (defadvice server-visit-files (around save-buffers last activate)
          "Try to emulate gnuclient behaviour with emacsclient.
      Works only for visiting one buffer at a time."
          (let* ((filen (car (car (ad-get-arg 0))))
                 (buf (get-file-buffer filen))
                 (this-buf-modified-p nil))
            ;;; the following is copied from server-visit-files, with
            ;;; a modification for the `verify-visited-file-modtime' test
            (if (and buf (set-buffer buf))
                (if (file-exists-p filen)
                    ;;; if the file has changed on disk, reload it
                    ;;; using `find-file-noselect'
                    (if (not (verify-visited-file-modtime buf))
                        (progn
                          (find-file-noselect filen)
                          ;;; if user answered `no', reset modtime anyway
                          ;;; so that server-visit-files doesn't realize
                          ;;; the difference:
                          (set-visited-file-modtime)))
                  ;;; if file exists no longer, we let server-visit-files
                  ;;; deal with that
                  t)
              (setq buf (find-file-noselect filen)))
            (setq this-buf-modified-p (buffer-modified-p buf))
            (set-buffer buf)
            (set-buffer-modified-p nil)
            ad-do-it
            (set-buffer-modified-p this-buf-modified-p)))
                

      Another tip, from Piotr Zielinski: If you want Emacs to open a new frame for a new buffer only, put the following into your ~/.emacs file:

      (defun local-gnuserv-open (filename lineno)
        (let ((buffer (find-file-noselect (file-truename filename)))
      	(pop-up-frames t)
      	(display-buffer-reuse-frames t))
          (set-buffer buffer)
          (select-window (display-buffer buffer nil 0))
          (goto-line lineno)))
                
      and use the following in your ~/.Xdefaults:
      xdvi.editor: gnuclient -q -batch -eval "(local-gnuserv-open \"%f\" %l)"
            
  2. Forward search

    Use xdvi-search.el (also contained in the texk/xdvik/ subdirectory of the xdvik distribution. Note: for versions of xdvik older than 22.74.2 and non-k xdvi, you should use this version of xdvi-search.el instead.)

    You can customize the variable xdvi-bin to include the command-line options needed for reverse search as follows:

    M-x customize-variable xdvi-bin 
              
    Toggle its value to `File' and enter the following into the text field:
    xdvi -editor 'emacsclient +%l %f' 
              
Last updated on Sun, 10 May 2009 22:15:34 +0200 by Stefan Ulrich Valid HTML 4.01!