Open files in external applications
Emacs has a cool learning curve, but the further you go, the more you want to do everything you can and cannot do in it. In particular, it has a large number of tools for navigating the file system.
For example, I use Dired mode, ido, Org mode and bookmarks. But there is a problem with opening files in external applications: pdf in evince, avi in mplayer, etc. And I want to ask these connections in one place. Emacs wouldn’t be Emacs if it didn’t allow us to do some dirty hack for this =)
We define associations of applications with file types as a list of pairs in which the first element is a string separated by a space of extensions, and the second is a command to run the application: From the extension line, we’ll do a regular season: Write a function that gets the file path,
Now we need to get Emacs to run our function when trying to open the file. The documentation tells us that functions like find-file use find-file-noselect.
Therefore, we will keep the system function and redefine it so that she was trying to open the file in an external program, for Org mode will write a small function, so that when you open links jump to another window was only for files opened from within Emacs and will use it for all file types While There were no special problems with this, although, for example, running external applications via tramp does not work, but it seems to be necessary. Download code. Any criticism and advice, as they say, to Wellcome.
For example, I use Dired mode, ido, Org mode and bookmarks. But there is a problem with opening files in external applications: pdf in evince, avi in mplayer, etc. And I want to ask these connections in one place. Emacs wouldn’t be Emacs if it didn’t allow us to do some dirty hack for this =)
We define associations of applications with file types as a list of pairs in which the first element is a string separated by a space of extensions, and the second is a command to run the application: From the extension line, we’ll do a regular season: Write a function that gets the file path,
(defvar command-list
'(("jpg jpeg png bmp" .
"gqview")
("pdf djvu ps" .
"evince")
("html htm" .
"firefox -new-tab")
("ogv mpg mpeg avi flv
VOB wmv mp4 mov mkv divx
ogm m4v asf rmvb" .
"mplayer -fs")
("doc odf odt rtf" .
"ooffice")))
(defun build-re (str)
(let ((re "\\.\\(")
(ext-list (split-string str)))
(dotimes (n (- (length ext-list) 1))
(setq re (concat re (nth n ext-list) "$\\|")))
(setq re (concat re (car (last ext-list)) "$\\)$"))
re))
(defun try-open-external (filename)
(let ((success nil))
;; проходит по списку команд,
(dolist (command command-list)
(let ((cmd (cdr command))
;; делает ругулярное выражение из расширений,
(re (build-re (car command))))
;; пытается сопоставить с ним путь.
(when (string-match re filename)
;; В случае успеха запускает программу,
(shell-command-to-string (concat cmd
" "
(shell-quote-argument filename)
" &> /dev/null &"))
(setq success t))))
;; и говорит нашла ли она ассоциацию с файлом.
success))
Now we need to get Emacs to run our function when trying to open the file. The documentation tells us that functions like find-file use find-file-noselect.
Therefore, we will keep the system function and redefine it so that she was trying to open the file in an external program, for Org mode will write a small function, so that when you open links jump to another window was only for files opened from within Emacs and will use it for all file types While There were no special problems with this, although, for example, running external applications via tramp does not work, but it seems to be necessary. Download code. Any criticism and advice, as they say, to Wellcome.
(fset 'old-find-file-noselect (symbol-function 'find-file-noselect))
(defun find-file-noselect (filename &optional nowarn rawfile wildcards)
(if (try-open-external filename)
nil
;; а в случае неудачи вызывала системную функцию.
(old-find-file-noselect filename nowarn rawfile wildcards)))
(defun my-org-find-file (file)
(when (not (try-open-external file))
(find-file-other-window file)))
(org-file-apps (quote ((".*" my-org-find-file file))))