2

I am using the openwith package in emacs. I would like to open .fig files with xfig with some additional options, for example:

xfig -specialtext -latexfont -startlatexFont default file.fig

openwith is working for me with other file associations where I don't need to pass additional options. I tried the following in my .emacs file

(setq
 openwith-associations 
 '(("\\.fig\\'" "xfig" (file))))

which works, but

(setq
 openwith-associations 
 '(("\\.fig\\'" "xfig -specialtext -latexfont -startlatexFont default" (file))))

does not work (error: Wrong type argument: arrayp, nil), also

(setq
 openwith-associations 
 '(("\\.fig\\'" "xfig" (" -specialtext -latexfont -startlatexFont default " file))))

does not work, although here I don't get any error. It says "Opened file.fig in external program" but nothing happens. In this case, I notice that there is an xfig process running with all these options.

Could someone let me know how to fix this?

Thanks for the help.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
sanjshakun
  • 535
  • 4
  • 13

1 Answers1

2

I have no clue how this works, so I just document how one can figure it by reading the code:

The important code in openwith.el is the call to start-process in:

(dolist (oa openwith-associations)
  (let (match)
    (save-match-data
      (setq match (string-match (car oa) (car args))))
    (when match
      (let ((params (mapcar (lambda (x)
                  (if (eq x 'file)
                  (car args)
                  (format "%s" x))) (nth 2 oa))))
    (apply #'start-process "openwith-process" nil
           (cadr oa) params))
      (kill-buffer nil)
      (throw 'openwith-done t))))

The in your case oa would have the following structure, and the cadr is "xfig":

(cadr '("\.fig\'" "xfig" (file))) ;; expands to => xfig

This is the definition and doc of start-process:

Function: start-process name buffer-or-name program &rest args http://www.gnu.org/software/emacs/elisp/html_node/Asynchronous-Processes.html

 args, are strings that specify command line arguments for the program.

An example:

(start-process "my-process" "foo" "ls" "-l" "/user/lewis/bin")

Now we need to figure out how params is constructed. With your example the argument to the mapcar is:

(nth 2 '("\.fig\'" "xfig" (file))) ;=> (file)

By the way you can write such lines in the scratch buffer in emacs and run them with C-M-x.

The (car args) refers to the parameter you give to openwith-association, note how the occurance of 'file in (nth 2 oa) is replaced by that. I'll just replace it with "here.txt" for now:

(mapcar (lambda (x)
      (if (eq x 'file)
          "here.txt"
          (format "%s" x))) (nth 2 '("\.fig\'" "xfig" (file)))) ;=> ("here.txt")

Okay, now we see how the argument should be constructed:

(mapcar (lambda (x)
      (if (eq x 'file)
          "here.txt"
          (format "%s" x))) 
    (nth 2 '("\.fig\'" "xfig" 
         ("-specialtext" "-latexfont" "-startlatexFont" "default" file))))
; => ("-specialtext" "-latexfont" "-startlatexFont" "default" "here.txt")

Try this:

(setq openwith-associations 
 '(("\\.fig\\'" "xfig" ("-specialtext" "-latexfont" "-startlatexFont" "default" file))))

You have to supply each word as a single string in the list of parameters.

whoplisp
  • 2,508
  • 16
  • 19
  • Note that Noufal Ibrahim edited (correctly, as the strings in openwith.el always have two backslashes) the slashes in your question. The last example in my answer should be correct. – whoplisp Jul 30 '11 at 20:19