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 |
