comparison lisp/progmodes/executable.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 89f6eeae2af3
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; executable.el --- base functionality for executable interpreter scripts -*- byte-compile-dynamic: t -*- 1 ;;; executable.el --- base functionality for executable interpreter scripts -*- byte-compile-dynamic: t -*-
2 2
3 ;; Copyright (C) 1994, 1995, 1996, 2000 by Free Software Foundation, Inc. 3 ;; Copyright (C) 1994, 1995, 1996, 2000, 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
4 5
5 ;; Author: Daniel Pfeiffer <occitan@esperanto.org> 6 ;; Author: Daniel Pfeiffer <occitan@esperanto.org>
6 ;; Keywords: languages, unix 7 ;; Keywords: languages, unix
7 8
8 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details. 19 ;; GNU General Public License for more details.
19 20
20 ;; You should have received a copy of the GNU General Public License 21 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02111-1307, USA. 24 ;; Boston, MA 02110-1301, USA.
24 25
25 ;;; Commentary: 26 ;;; Commentary:
26 27
27 ;; executable.el is used by certain major modes to insert a suitable 28 ;; executable.el is used by certain major modes to insert a suitable
28 ;; #! line at the beginning of the file, if the file does not already 29 ;; #! line at the beginning of the file, if the file does not already
51 ;; `executable-set-magic'. 52 ;; `executable-set-magic'.
52 53
53 ;;; Code: 54 ;;; Code:
54 55
55 (defgroup executable nil 56 (defgroup executable nil
56 "Base functionality for executable interpreter scripts" 57 "Base functionality for executable interpreter scripts."
57 :group 'processes) 58 :group 'processes)
58 59
59 ;; This used to default to `other', but that doesn't seem to have any 60 ;; This used to default to `other', but that doesn't seem to have any
60 ;; significance. fx 2000-02-11. 61 ;; significance. fx 2000-02-11.
61 (defcustom executable-insert t ; 'other 62 (defcustom executable-insert t ; 'other
139 140
140 ;; The C function openp slightly modified would do the trick fine 141 ;; The C function openp slightly modified would do the trick fine
141 (defvaralias 'executable-binary-suffixes 'exec-suffixes) 142 (defvaralias 'executable-binary-suffixes 'exec-suffixes)
142 143
143 ;;;###autoload 144 ;;;###autoload
144 (defun executable-find (command) 145 (defun executable-command-find-posix-p (&optional program)
145 "Search for COMMAND in `exec-path' and return the absolute file name. 146 "Check if PROGRAM handles arguments Posix-style.
146 Return nil if COMMAND is not found anywhere in `exec-path'." 147 If PROGRAM is non-nil, use that instead of \"find\"."
147 (let ((list exec-path) 148 ;; Pick file to search from location we know
148 file) 149 (let* ((dir (file-truename data-directory))
149 (while list 150 (file (car (directory-files dir nil "^[^.]"))))
150 (setq list 151 (with-temp-buffer
151 (if (and (setq file (expand-file-name command (car list))) 152 (call-process (or program "find")
152 (let ((suffixes exec-suffixes) 153 nil
153 candidate) 154 (current-buffer)
154 (while suffixes 155 nil
155 (setq candidate (concat file (car suffixes))) 156 dir
156 (if (and (file-executable-p candidate) 157 "-name"
157 (not (file-directory-p candidate))) 158 file
158 (setq suffixes nil) 159 "-maxdepth"
159 (setq suffixes (cdr suffixes)) 160 "1")
160 (setq candidate nil))) 161 (goto-char (point-min))
161 (setq file candidate))) 162 (if (search-forward file nil t)
162 nil 163 t))))
163 (setq file nil)
164 (cdr list))))
165 file))
166 164
167 (defun executable-chmod () 165 (defun executable-chmod ()
168 "This gets called after saving a file to assure that it be executable. 166 "This gets called after saving a file to assure that it be executable.
169 You can set the absolute or relative mode in variable `executable-chmod' for 167 You can set the absolute or relative mode in variable `executable-chmod' for
170 non-executable files." 168 non-executable files."
176 (- executable-chmod) 174 (- executable-chmod)
177 (logior executable-chmod 175 (logior executable-chmod
178 (file-modes buffer-file-name))))))) 176 (file-modes buffer-file-name)))))))
179 177
180 178
179 ;;;###autoload
181 (defun executable-interpret (command) 180 (defun executable-interpret (command)
182 "Run script with user-specified args, and collect output in a buffer. 181 "Run script with user-specified args, and collect output in a buffer.
183 While script runs asynchronously, you can use the \\[next-error] command 182 While script runs asynchronously, you can use the \\[next-error]
184 to find the next error." 183 command 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."
185 (interactive (list (read-string "Run script: " 185 (interactive (list (read-string "Run script: "
186 (or executable-command 186 (or executable-command
187 buffer-file-name)))) 187 buffer-file-name))))
188 (require 'compile) 188 (require 'compile)
189 (save-some-buffers (not compilation-ask-about-save)) 189 (save-some-buffers (not compilation-ask-about-save))
190 (make-local-variable 'executable-command) 190 (set (make-local-variable 'executable-command) command)
191 (compile-internal (setq executable-command command) 191 (let ((compilation-error-regexp-alist executable-error-regexp-alist))
192 "No more errors." "Interpretation" 192 (compilation-start command t (lambda (x) "*interpretation*"))))
193 ;; Give it a simpler regexp to match.
194 nil executable-error-regexp-alist))
195 193
196 194
197 195
198 ;;;###autoload 196 ;;;###autoload
199 (defun executable-set-magic (interpreter &optional argument 197 (defun executable-set-magic (interpreter &optional argument
225 (string-match executable-magicless-file-regexp 223 (string-match executable-magicless-file-regexp
226 buffer-file-name)) 224 buffer-file-name))
227 (not (or insert-flag executable-insert)) 225 (not (or insert-flag executable-insert))
228 (> (point-min) 1) 226 (> (point-min) 1)
229 (save-excursion 227 (save-excursion
230 (let ((point (point-marker)) 228 (goto-char (point-min))
231 (buffer-modified-p (buffer-modified-p))) 229 (add-hook 'after-save-hook 'executable-chmod nil t)
232 (goto-char (point-min)) 230 (if (looking-at "#![ \t]*\\(.*\\)$")
233 (add-hook 'after-save-hook 'executable-chmod nil t) 231 (and (goto-char (match-beginning 1))
234 (if (looking-at "#![ \t]*\\(.*\\)$") 232 ;; If the line ends in a space,
235 (and (goto-char (match-beginning 1)) 233 ;; don't offer to change it.
236 ;; If the line ends in a space, 234 (not (= (char-after (1- (match-end 1))) ?\s))
237 ;; don't offer to change it. 235 (not (string= argument
238 (not (= (char-after (1- (match-end 1))) ?\ )) 236 (buffer-substring (point) (match-end 1))))
239 (not (string= argument 237 (if (or (not executable-query) no-query-flag
240 (buffer-substring (point) (match-end 1)))) 238 (save-window-excursion
241 (if (or (not executable-query) no-query-flag 239 ;; Make buffer visible before question.
242 (save-window-excursion 240 (switch-to-buffer (current-buffer))
243 ;; Make buffer visible before question. 241 (y-or-n-p (concat "Replace magic number by `"
244 (switch-to-buffer (current-buffer)) 242 executable-prefix argument "'? "))))
245 (y-or-n-p (concat "Replace magic number by `" 243 (progn
246 executable-prefix argument "'? ")))) 244 (replace-match argument t t nil 1)
247 (progn 245 (message "Magic number changed to `%s'"
248 (replace-match argument t t nil 1) 246 (concat executable-prefix argument)))))
249 (message "Magic number changed to `%s'" 247 (insert executable-prefix argument ?\n)
250 (concat executable-prefix argument))))) 248 (message "Magic number changed to `%s'"
251 (insert executable-prefix argument ?\n) 249 (concat executable-prefix argument)))))
252 (message "Magic number changed to `%s'"
253 (concat executable-prefix argument)))
254 ;;; (or insert-flag
255 ;;; (eq executable-insert t)
256 ;;; (set-buffer-modified-p buffer-modified-p))
257 )))
258 interpreter) 250 interpreter)
259 251
260 252
261 253
262 ;;;###autoload 254 ;;;###autoload
274 If file already has any execute bits set at all, do not change existing 266 If file already has any execute bits set at all, do not change existing
275 file modes." 267 file modes."
276 (and (>= (buffer-size) 2) 268 (and (>= (buffer-size) 2)
277 (save-restriction 269 (save-restriction
278 (widen) 270 (widen)
279 (string= "#!" (buffer-substring 1 3))) 271 (string= "#!" (buffer-substring (point-min) (+ 2 (point-min)))))
280 (let* ((current-mode (file-modes (buffer-file-name))) 272 (let* ((current-mode (file-modes (buffer-file-name)))
281 (add-mode (logand ?\111 (default-file-modes)))) 273 (add-mode (logand ?\111 (default-file-modes))))
282 (or (/= (logand ?\111 current-mode) 0) 274 (or (/= (logand ?\111 current-mode) 0)
283 (zerop add-mode) 275 (zerop add-mode)
284 (set-file-modes (buffer-file-name) 276 (set-file-modes (buffer-file-name)
285 (logior current-mode add-mode)))))) 277 (logior current-mode add-mode))))))
286 278
287 (provide 'executable) 279 (provide 'executable)
288 280
281 ;; arch-tag: 58458d1c-d9db-45ec-942b-8bbb1d5e319d
289 ;;; executable.el ends here 282 ;;; executable.el ends here