exopen-suffix-cmdがnilのときにエラーになる不具合を回避
[exopen-mode.git] / exopen-mode.el
1 ;;; exopen-mode.el
2
3 ;; Copyright (C) 2013  j8takagi
4
5 ;; Author: j8takagi <j8takagi@nifty.com>
6 ;; Keywords: Emacs 外部プログラム
7
8 ;; This file is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12 ;;
13 ;; This file is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to the
20 ;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 ;; Boston, MA 02110-1301 USA
22
23 ;;; Commentary:
24
25 ;; Emacsからの外部プログラム呼び出しを支援するマイナーモードです。
26
27 ;; ■動作環境
28 ;; Linux、Mac OS X、WindowsのいずれかのWindowシステム上
29
30 ;; ■インストール方法
31 ;; 1. LOAD-PATHで指定されているディレクトリにこのファイルをコピーする
32 ;;
33 ;; 2. Emacsの設定ファイル(~/.emacs.d/init.el など)に以下の行を追加する
34 ;;
35 ;; (require 'exopen-mode)
36
37 ;; Windowシステム上でEmacsが動作している場合、exopen-mode は自動的に有効になります。
38 ;;
39 ;; ■使い方
40
41 ;; ■hook
42
43 ;; マイナーモードの定義
44  (easy-mmode-define-minor-mode exopen-mode
45    "minor mode for opening fle in external program."
46  ;; 初期値
47 (display-graphic-p)
48  ;; モード行の表示
49  ""
50  ;; マイナーモード用キーマップの初期値
51  '(("\C-x\C-\M-f" . exopen-find-file)))
52
53 ;; exopen-std-cmd: OSやWindowで設定された関連付けをもとに
54 ;; ファイルを開くプログラムコマンド
55 (defvar exopen-std-cmd nil)
56
57 ;; Window別にexopen-std-cmdを設定する
58 (setq exopen-std-cmd
59       (cond
60        ((eq window-system 'x) "xdg-open")
61        ((eq window-system 'ns) "open")
62        ((eq window-system 'w32) "cmd.exe /c start")))
63
64 ;; exopen-modeでの拡張子とプログラムの関連付けリスト
65 (defvar exopen-suffix-cmd nil)
66
67 ;;; ファイルを外部プログラムでオープン
68 ;;; exopen-std-cmdで指定されたプログラムを使用
69 (defun exopen-file (file)
70   "open file in external program"
71   (let ((process-connection-type nil) (cmd))
72     (if exopen-suffix-cmd
73         (setq cmd (cdr(assoc (file-name-extension file 1) exopen-suffix-cmd))))
74     (if (null cmd)
75         (setq cmd exopen-std-cmd))
76     (start-process "exopen" nil cmd file)
77     (message (concat "exopen: " cmd " " file " at " (format-time-string "%Y/%m/%d %H:%M:%S" (current-time))))))
78
79 ;;; バッファで開いているファイルを外部プログラムでオープン
80 (defun exopen-buffer-file ()
81   "open buffer file in external program"
82   (interactive)
83   (if buffer-file-name
84       (exopen-file buffer-file-name)
85     (error "This buffer is not visiting a file")))
86
87 ;;; 指定したファイルと同名で拡張子が異なるファイルを外部プログラムでオープン
88 (defun exopen-buffer-file-suffix (suffix)
89   "open buffer file of other extension in external program"
90   (let (afile)
91     (if (not buffer-file-name)
92         (error "This buffer is not visiting a file"))
93     (setq afile (concat (file-name-sans-extension (buffer-file-name)) suffix))
94     (if (file-exists-p afile)
95         (exopen-file afile)
96       (error (concat afile ": file not found")))))
97
98 ;;; 指定したファイルと同名のPDFファイルを外部プログラムでオープン
99 (defun exopen-buffer-pdffile ()
100   "open pdf file in external program"
101   (interactive)
102   (exopen-buffer-file-suffix ".pdf"))
103
104 ;;; バッファファイルと同名のDVIファイルを外部プログラムでオープン
105 (defun exopen-buffer-dvifile ()
106   "open dvi file in external program"
107   (interactive)
108   (exopen-buffer-file-suffix ".dvi"))
109
110 ;;; バッファファイルと同名のHTMLファイルを外部プログラムでオープン
111 (defun exopen-buffer-htmlfile ()
112   "open html file in external program"
113   (interactive)
114   (exopen-buffer-file-suffix ".html"))
115
116 ;;; find-or-bufferがnilの場合はプロンプトで指定したファイル、
117 ;;; nil以外の場合はバッファのファイルを外部プログラムでオープン
118 (defun exopen-find-file(&optional find-or-buffer)
119   "open buffer file or find-file in external program"
120   (interactive "P")
121   (let ((afile))
122     (if (null find-or-buffer)
123         (progn
124           (setq afile (expand-file-name
125                        (read-file-name "Find external open file: " buffer-file-name)))
126           (if afile
127               (exopen-file afile)
128             (error "file not found")))
129       (exopen-buffer-file)
130       )))
131
132 ;;; dired-modeからファイルやディレクトリーを開く
133 (require 'dired)
134 (add-hook 'dired-mode-hook
135           (function
136            (lambda ()
137              ;; カーソル下のファイルやディレクトリーを外部プログラムで開く
138              (defun dired-exopen-file ()
139                "Open file mentioned on this line in external program"
140                (interactive)
141                (exopen-file (dired-get-filename)))
142
143              ;; 現在のディレクトリーを外部プログラムで開く
144              (defun dired-exopen-curdir ()
145                "Open current directory in external program"
146                (interactive)
147                (exopen-file (expand-file-name dired-directory)))
148
149              ;; キーバインド
150              (define-key dired-mode-map "r" 'dired-exopen-file)
151              (define-key dired-mode-map "\C-cr" 'dired-exopen-file)
152              (define-key dired-mode-map "\C-c." 'dired-exopen-curdir))))
153
154 (provide 'exopen-mode)
155 ;;; exopen-mode.el ends here