Mercurial > emacs
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 |