* term/xterm.el (xterm--query): Stop after first matching handler. (Bug#14615)
[bpt/emacs.git] / lisp / progmodes / executable.el
CommitLineData
778e1d17 1;;; executable.el --- base functionality for executable interpreter scripts -*- byte-compile-dynamic: t -*-
b578f267 2
ab422c4d 3;; Copyright (C) 1994-1996, 2000-2013 Free Software Foundation, Inc.
58a4ff04 4
3e910376 5;; Author: Daniel Pfeiffer <occitan@esperanto.org>
58a4ff04
KH
6;; Keywords: languages, unix
7
8;; This file is part of GNU Emacs.
9
b1fc2b50 10;; GNU Emacs is free software: you can redistribute it and/or modify
58a4ff04 11;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
58a4ff04
KH
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b1fc2b50 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
58a4ff04
KH
22
23;;; Commentary:
314001b5
RS
24
25;; executable.el is used by certain major modes to insert a suitable
26;; #! line at the beginning of the file, if the file does not already
27;; have one.
28
252ed276
RS
29;; Unless it has a magic number, a Unix file with executable mode is passed to
30;; a new instance of the running shell (or to a Bourne shell if a csh is
31;; running and the file starts with `:'). Only a shell can start such a file,
32;; exec() cannot, which is why it is important to have a magic number in every
33;; executable script. Such a magic number is made up by the characters `#!'
34;; the filename of an interpreter (in COFF, ELF or somesuch format) and one
35;; optional argument.
36
37;; This library is for certain major modes like sh-, awk-, perl-, tcl- or
38;; makefile-mode to insert or update a suitable #! line at the beginning of
39;; the file, if the file does not already have one and the file is not a
40;; default file of that interpreter (like .profile or makefile). It also
41;; makes the file executable if it wasn't, as soon as it's saved.
42
43;; It also allows debugging scripts, with an adaptation of compile, as far
44;; as interpreters give out meaningful error messages.
45
46;; Modes that use this should nconc `executable-map' to the end of their own
47;; keymap and `executable-font-lock-keywords' to the end of their own font
48;; lock keywords. Their mode-setting commands should call
49;; `executable-set-magic'.
4a789a51 50
58a4ff04
KH
51;;; Code:
52
bbf5eb28 53(defgroup executable nil
67da3b40 54 "Base functionality for executable interpreter scripts."
bbf5eb28
RS
55 :group 'processes)
56
778e1d17
DL
57;; This used to default to `other', but that doesn't seem to have any
58;; significance. fx 2000-02-11.
59(defcustom executable-insert t ; 'other
fb7ada5f 60 "Non-nil means offer to add a magic number to a file.
8d4e82b5
RS
61This takes effect when you switch to certain major modes,
62including Shell-script mode (`sh-mode').
63When you type \\[executable-set-magic], it always offers to add or
bbf5eb28 64update the magic number."
778e1d17
DL
65;;; :type '(choice (const :tag "off" nil)
66;;; (const :tag "on" t)
67;;; symbol)
68 :type 'boolean
bbf5eb28 69 :group 'executable)
58a4ff04 70
58a4ff04 71
bbf5eb28 72(defcustom executable-query 'function
fb7ada5f 73 "If non-nil, ask user before changing an existing magic number.
bbf5eb28
RS
74When this is `function', only ask when called non-interactively."
75 :type '(choice (const :tag "Don't Ask" nil)
0c3ba9b2
AS
76 (const :tag "Ask when non-interactive" function)
77 (other :tag "Ask" t))
bbf5eb28 78 :group 'executable)
58a4ff04 79
58a4ff04 80
bbf5eb28 81(defcustom executable-magicless-file-regexp "/[Mm]akefile$\\|/\\.\\(z?profile\\|bash_profile\\|z?login\\|bash_login\\|z?logout\\|bash_logout\\|.+shrc\\|esrc\\|rcrc\\|[kz]shenv\\)$"
fb7ada5f 82 "On files with this kind of name no magic is inserted or changed."
bbf5eb28
RS
83 :type 'regexp
84 :group 'executable)
58a4ff04 85
58a4ff04 86
0fcd3d9f 87(defcustom executable-prefix "#!"
fb7ada5f 88 "Interpreter magic number prefix inserted when there was no magic number."
1d0f71d3 89 :version "24.3" ; "#! " -> "#!"
bbf5eb28
RS
90 :type 'string
91 :group 'executable)
58a4ff04
KH
92
93
bbf5eb28 94(defcustom executable-chmod 73
fb7ada5f 95 "After saving, if the file is not executable, set this mode.
58a4ff04
KH
96This mode passed to `set-file-modes' is taken absolutely when negative, or
97relative to the files existing modes. Do nothing if this is nil.
bbf5eb28 98Typical values are 73 (+x) or -493 (rwxr-xr-x)."
9cbf5df2
RS
99 :type '(choice integer
100 (const nil))
bbf5eb28 101 :group 'executable)
58a4ff04
KH
102
103
104(defvar executable-command nil)
105
bbf5eb28 106(defcustom executable-self-display "tail"
fb7ada5f 107 "Command you use with argument `+2' to make text files self-display.
778e1d17 108Note that the like of `more' doesn't work too well under Emacs \\[shell]."
bbf5eb28
RS
109 :type 'string
110 :group 'executable)
58a4ff04
KH
111
112
113(defvar executable-font-lock-keywords
114 '(("\\`#!.*/\\([^ \t\n]+\\)" 1 font-lock-keyword-face t))
fb7ada5f 115 "Rules for highlighting executable scripts' magic number.
58a4ff04
KH
116This can be included in `font-lock-keywords' by modes that call `executable'.")
117
118
119(defvar executable-error-regexp-alist
120 '(;; /bin/xyz: syntax error at line 14: `(' unexpected
121 ;; /bin/xyz[5]: syntax error at line 8 : ``' unmatched
122 ("^\\(.*[^[/]\\)\\(\\[[0-9]+\\]\\)?: .* error .* line \\([0-9]+\\)" 1 3)
123 ;; /bin/xyz[27]: ehco: not found
124 ("^\\(.*[^/]\\)\\[\\([0-9]+\\)\\]: .*: " 1 2)
125 ;; /bin/xyz: syntax error near unexpected token `)'
126 ;; /bin/xyz: /bin/xyz: line 2: `)'
127 ("^\\(.*[^/]\\): [^0-9\n]+\n\\1: \\1: line \\([0-9]+\\):" 1 2)
128 ;; /usr/bin/awk: syntax error at line 5 of file /bin/xyz
129 (" error .* line \\([0-9]+\\) of file \\(.+\\)$" 2 1)
130 ;; /usr/bin/awk: calling undefined function toto
131 ;; input record number 3, file awktestdata
132 ;; source line 4 of file /bin/xyz
133 ("^[^ ].+\n\\( .+\n\\)* line \\([0-9]+\\) of file \\(.+\\)$" 3 2)
134 ;; makefile:1: *** target pattern contains no `%'. Stop.
135 ("^\\(.+\\):\\([0-9]+\\): " 1 2))
136 "Alist of regexps used to match script errors.
137See `compilation-error-regexp-alist'.")
138
291c92b7 139;; The C function openp slightly modified would do the trick fine
2d08a2d4 140(defvaralias 'executable-binary-suffixes 'exec-suffixes)
778e1d17 141
14768716
RS
142;;;###autoload
143(defun executable-command-find-posix-p (&optional program)
144 "Check if PROGRAM handles arguments Posix-style.
679be517 145If PROGRAM is non-nil, use that instead of \"find\"."
14768716 146 ;; Pick file to search from location we know
c6190ba0
MR
147 (let* ((dir (file-truename data-directory))
148 (file (car (directory-files dir nil "^[^.]"))))
14768716
RS
149 (with-temp-buffer
150 (call-process (or program "find")
151 nil
152 (current-buffer)
153 nil
154 dir
155 "-name"
156 file
157 "-maxdepth"
158 "1")
159 (goto-char (point-min))
160 (if (search-forward file nil t)
161 t))))
162
58a4ff04
KH
163(defun executable-chmod ()
164 "This gets called after saving a file to assure that it be executable.
165You can set the absolute or relative mode in variable `executable-chmod' for
166non-executable files."
167 (and executable-chmod
168 buffer-file-name
169 (or (file-executable-p buffer-file-name)
170 (set-file-modes buffer-file-name
171 (if (< executable-chmod 0)
172 (- executable-chmod)
173 (logior executable-chmod
174 (file-modes buffer-file-name)))))))
175
176
e02f48d7
JB
177(defvar compilation-error-regexp-alist) ; from compile.el
178
78f617dd 179;;;###autoload
58a4ff04
KH
180(defun executable-interpret (command)
181 "Run script with user-specified args, and collect output in a buffer.
78f617dd
DP
182While script runs asynchronously, you can use the \\[next-error]
183command to find the next error. The buffer is also in `comint-mode' and
184`compilation-shell-minor-mode', so that you can answer any prompts."
58a4ff04
KH
185 (interactive (list (read-string "Run script: "
186 (or executable-command
187 buffer-file-name))))
188 (require 'compile)
189 (save-some-buffers (not compilation-ask-about-save))
78f617dd
DP
190 (set (make-local-variable 'executable-command) command)
191 (let ((compilation-error-regexp-alist executable-error-regexp-alist))
e02f48d7 192 (compilation-start command t (lambda (_x) "*interpretation*"))))
58a4ff04
KH
193
194
195
196;;;###autoload
291c92b7
KH
197(defun executable-set-magic (interpreter &optional argument
198 no-query-flag insert-flag)
58a4ff04
KH
199 "Set this buffer's interpreter to INTERPRETER with optional ARGUMENT.
200The variables `executable-magicless-file-regexp', `executable-prefix',
201`executable-insert', `executable-query' and `executable-chmod' control
202when and how magic numbers are inserted or replaced and scripts made
203executable."
291c92b7
KH
204 (interactive
205 (let* ((name (read-string "Name or file name of interpreter: "))
206 (arg (read-string (format "Argument for %s: " name))))
207 (list name arg (eq executable-query 'function) t)))
6c233cc0 208
58a4ff04
KH
209 (setq interpreter (if (file-name-absolute-p interpreter)
210 interpreter
291c92b7 211 (or (executable-find interpreter)
6c233cc0
GM
212 (error "Interpreter %s not recognized"
213 interpreter))))
214
215 (setq argument (concat (if (string-match "\\`/:" interpreter)
216 (replace-match "" nil nil interpreter)
217 interpreter)
58a4ff04
KH
218 (and argument (string< "" argument) " ")
219 argument))
6c233cc0 220
58a4ff04
KH
221 (or buffer-read-only
222 (if buffer-file-name
223 (string-match executable-magicless-file-regexp
224 buffer-file-name))
291c92b7 225 (not (or insert-flag executable-insert))
58a4ff04 226 (> (point-min) 1)
291c92b7 227 (save-excursion
1d88c1b3
SM
228 (goto-char (point-min))
229 (add-hook 'after-save-hook 'executable-chmod nil t)
230 (if (looking-at "#![ \t]*\\(.*\\)$")
231 (and (goto-char (match-beginning 1))
232 ;; If the line ends in a space,
233 ;; don't offer to change it.
67da3b40 234 (not (= (char-after (1- (match-end 1))) ?\s))
1d88c1b3
SM
235 (not (string= argument
236 (buffer-substring (point) (match-end 1))))
237 (if (or (not executable-query) no-query-flag
238 (save-window-excursion
239 ;; Make buffer visible before question.
240 (switch-to-buffer (current-buffer))
241 (y-or-n-p (concat "Replace magic number by `"
242 executable-prefix argument "'? "))))
243 (progn
244 (replace-match argument t t nil 1)
245 (message "Magic number changed to `%s'"
246 (concat executable-prefix argument)))))
247 (insert executable-prefix argument ?\n)
248 (message "Magic number changed to `%s'"
249 (concat executable-prefix argument)))))
6c233cc0 250 interpreter)
58a4ff04
KH
251
252
253
254;;;###autoload
255(defun executable-self-display ()
256 "Turn a text file into a self-displaying Un*x command.
257The magic number of such a command displays all lines but itself."
258 (interactive)
259 (if (eq this-command 'executable-self-display)
260 (setq this-command 'executable-set-magic))
261 (executable-set-magic executable-self-display "+2"))
262
778e1d17 263;;;###autoload
cc7e1d18 264(defun executable-make-buffer-file-executable-if-script-p ()
778e1d17
DL
265 "Make file executable according to umask if not already executable.
266If file already has any execute bits set at all, do not change existing
267file modes."
fd5f61d3
GM
268 (and (>= (buffer-size) 2)
269 (save-restriction
cc7e1d18 270 (widen)
1d88c1b3 271 (string= "#!" (buffer-substring (point-min) (+ 2 (point-min)))))
56632ce4
GM
272 (condition-case nil
273 (let* ((current-mode (file-modes (buffer-file-name)))
274 (add-mode (logand ?\111 (default-file-modes))))
275 (or (/= (logand ?\111 current-mode) 0)
276 (zerop add-mode)
277 (set-file-modes (buffer-file-name)
278 (logior current-mode add-mode))))
279 ;; Eg file-modes can return nil (bug#9879). It should not,
280 ;; in this context, but we should handle it all the same.
281 (error (message "Unable to make file executable")))))
58a4ff04
KH
282
283(provide 'executable)
284
e8af40ee 285;;; executable.el ends here