Я понятия не имею, как это работает, поэтому я просто документирую, как можно это понять, прочитав код:
Важный код в openwith.el - это вызов start-process в:
(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))))
В вашем случае oa будет иметь следующую структуру, а cadr будет "xfig":
(cadr '("\.fig\'" "xfig" (file))) ;; expands to => xfig
Это определение и документ процесса запуска:
Функция: start-process имя буфера или имя программы и аргументы rest http://www.gnu.org/software/emacs/elisp/html_node/Asynchronous-Processes.html
args, are strings that specify command line arguments for the program.
Пример:
(start-process "my-process" "foo" "ls" "-l" "/user/lewis/bin")
Теперь нам нужно вычислитьиз того, как params построен.В вашем примере аргумент для mapcar:
(nth 2 '("\.fig\'" "xfig" (file))) ;=> (file)
Кстати, вы можете написать такие строки в буфере scratch в emacs и запустить их с CMx.
(Car args) относится к параметру, который вы задаете для openwith-association, обратите внимание, как этим заменяется вхождение файла в (nth 2 oa).Сейчас я просто заменю его здесь "here.txt":
(mapcar (lambda (x)
(if (eq x 'file)
"here.txt"
(format "%s" x))) (nth 2 '("\.fig\'" "xfig" (file)))) ;=> ("here.txt")
Хорошо, теперь мы видим, как должен быть построен аргумент:
(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")
Попробуйте это:
(setq openwith-associations
'(("\\.fig\\'" "xfig" ("-specialtext" "-latexfont" "-startlatexFont" "default" file))))
Вы должны указать каждое слово в списке параметров как одну строку.