diff options
Diffstat (limited to 'lisp/progmodes/compile.el')
-rw-r--r-- | lisp/progmodes/compile.el | 356 |
1 files changed, 239 insertions, 117 deletions
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 7f87dbcd6b1..e68441547b6 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -1,7 +1,8 @@ ;;; compile.el --- run compiler as inferior of Emacs, parse error messages ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +;; Free Software Foundation, Inc. ;; Authors: Roland McGrath <roland@gnu.org>, ;; Daniel Pfeiffer <occitan@esperanto.org> @@ -38,11 +39,14 @@ ;; LINE will be nil for a message that doesn't contain them. Then the ;; location refers to a indented beginning of line or beginning of file. ;; Once any location in some file has been jumped to, the list is extended to -;; (COLUMN LINE FILE-STRUCTURE MARKER . VISITED) for all LOCs pertaining to -;; that file. +;; (COLUMN LINE FILE-STRUCTURE MARKER TIMESTAMP . VISITED) +;; for all LOCs pertaining to that file. ;; MARKER initially points to LINE and COLUMN in a buffer visiting that file. ;; Being a marker it sticks to some text, when the buffer grows or shrinks ;; before that point. VISITED is t if we have jumped there, else nil. +;; TIMESTAMP is necessary because of "incremental compilation": `omake -P' +;; polls filesystem for changes and recompiles when a file is modified +;; using the same *compilation* buffer. this necessitates re-parsing markers. ;; FILE-STRUCTURE is a list of ;; ((FILENAME . DIRECTORY) FORMATS (LINE LOC ...) ...) @@ -84,13 +88,13 @@ ;;;###autoload (defcustom compilation-mode-hook nil - "*List of hook functions run by `compilation-mode' (see `run-mode-hooks')." + "List of hook functions run by `compilation-mode' (see `run-mode-hooks')." :type 'hook :group 'compilation) ;;;###autoload (defcustom compilation-window-height nil - "*Number of lines in a compilation window. If nil, use Emacs default." + "Number of lines in a compilation window. If nil, use Emacs default." :type '(choice (const :tag "Default" nil) integer) :group 'compilation) @@ -164,6 +168,10 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) "^[ \t]*\\[[^] \n]+\\][ \t]*\\([^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):[0-9]+:[0-9]+:\\)?\ \\( warning\\)?" 1 2 3 (4)) + (maven + ;; Maven is a popular build tool for Java. Maven is Free Software. + "\\(.*?\\):\\[\\([0-9]+\\),\\([0-9]+\\)\\]" 1 2 3) + (bash "^\\([^: \n\t]+\\): line \\([0-9]+\\):" 1 2) @@ -264,8 +272,9 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) " in \\([^()\n ]+\\)(\\([0-9]+\\))$" 1 2) (msft + ;; AFAWK, The message may be a "warning", "error", or "fatal error". "^\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \ -: \\(?:error\\|warnin\\(g\\)\\) C[0-9]+:" 2 3 nil (4)) +: \\(?:warnin\\(g\\)\\|[a-z ]+\\) C[0-9]+:" 2 3 nil (4)) (oracle "^\\(?:Semantic error\\|Error\\|PCC-[0-9]+:\\).* line \\([0-9]+\\)\ @@ -280,6 +289,10 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) " at \\([^ \n]+\\) line \\([0-9]+\\)\\(?:[,.]\\|$\\| \ during global destruction\\.$\\)" 1 2) + (php + "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" + 2 3 nil nil) + (rxp "^\\(?:Error\\|Warnin\\(g\\)\\):.*\n.* line \\([0-9]+\\) char\ \\([0-9]+\\) of file://\\(.+\\)" @@ -336,6 +349,68 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?" nil 2 nil 2 nil (0 'default t) (1 compilation-error-face prepend) (2 compilation-line-face prepend)) + + (perl--Pod::Checker + ;; podchecker error messages, per Pod::Checker. + ;; The style is from the Pod::Checker::poderror() function, eg. + ;; *** ERROR: Spurious text after =cut at line 193 in file foo.pm + ;; + ;; Plus end_pod() can give "at line EOF" instead of a + ;; number, so for that match "on line N" which is the + ;; originating spot, eg. + ;; *** ERROR: =over on line 37 without closing =back at line EOF in file bar.pm + ;; + ;; Plus command() can give both "on line N" and "at line N"; + ;; the latter is desired and is matched because the .* is + ;; greedy. + ;; *** ERROR: =over on line 1 without closing =back (at head1) at line 3 in file x.pod + ;; + "^\\*\\*\\* \\(?:ERROR\\|\\(WARNING\\)\\).* \\(?:at\\|on\\) line \ +\\([0-9]+\\) \\(?:.* \\)?in file \\([^ \t\n]+\\)" + 3 2 nil (1)) + (perl--Test + ;; perl Test module error messages. + ;; Style per the ok() function "$context", eg. + ;; # Failed test 1 in foo.t at line 6 + ;; + "^# Failed test [0-9]+ in \\([^ \t\r\n]+\\) at line \\([0-9]+\\)" + 1 2) + (perl--Test2 + ;; Or when comparing got/want values, + ;; # Test 2 got: "xx" (t-compilation-perl-2.t at line 10) + ;; + ;; And under Test::Harness they're preceded by progress stuff with + ;; \r and "NOK", + ;; ... NOK 1# Test 1 got: "1234" (t/foo.t at line 46) + ;; + "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^ \t\r\n]+\\) at line \ +\\([0-9]+\\))" + 2 3) + (perl--Test::Harness + ;; perl Test::Harness output, eg. + ;; NOK 1# Test 1 got: "1234" (t/foo.t at line 46) + ;; + ;; Test::Harness is slightly designed for tty output, since + ;; it prints CRs to overwrite progress messages, but if you + ;; run it in with M-x compile this pattern can at least step + ;; through the failures. + ;; + "^.*NOK.* \\([^ \t\r\n]+\\) at line \\([0-9]+\\)" + 1 2) + (weblint + ;; The style comes from HTML::Lint::Error::as_string(), eg. + ;; index.html (13:1) Unknown element <fdjsk> + ;; + ;; The pattern only matches filenames without spaces, since that + ;; should be usual and should help reduce the chance of a false + ;; match of a message from some unrelated program. + ;; + ;; This message style is quite close to the "ibm" entry which is + ;; for IBM C, though that ibm bit doesn't put a space after the + ;; filename. + ;; + "^\\([^ \t\r\n(]+\\) (\\([0-9]+\\):\\([0-9]+\\)) " + 1 2 3) ) "Alist of values for `compilation-error-regexp-alist'.") @@ -443,7 +518,7 @@ Highlight entire line if t; don't highlight source lines if nil.") "Overlay used to temporarily highlight compilation matches.") (defcustom compilation-error-screen-columns t - "*If non-nil, column numbers in error messages are screen columns. + "If non-nil, column numbers in error messages are screen columns. Otherwise they are interpreted as character positions, with each character occupying one column. The default is to use screen columns, which requires that the compilation @@ -454,21 +529,21 @@ especially the TAB character." :version "20.4") (defcustom compilation-read-command t - "*Non-nil means \\[compile] reads the compilation command to use. + "Non-nil means \\[compile] reads the compilation command to use. Otherwise, \\[compile] just uses the value of `compile-command'." :type 'boolean :group 'compilation) ;;;###autoload (defcustom compilation-ask-about-save t - "*Non-nil means \\[compile] asks which buffers to save before compiling. + "Non-nil means \\[compile] asks which buffers to save before compiling. Otherwise, it saves all modified buffers without asking." :type 'boolean :group 'compilation) ;;;###autoload (defcustom compilation-search-path '(nil) - "*List of directories to search for source files named in error messages. + "List of directories to search for source files named in error messages. Elements should be directory names, not file names of directories. The value nil as an element means to try the default directory." :type '(repeat (choice (const :tag "Default" nil) @@ -477,7 +552,7 @@ The value nil as an element means to try the default directory." ;;;###autoload (defcustom compile-command "make -k " - "*Last shell command used to do a compilation; default for next compilation. + "Last shell command used to do a compilation; default for next compilation. Sometimes it is useful for files to supply local values for this variable. You might also use mode hooks to specify it in certain modes, like this: @@ -495,7 +570,7 @@ You might also use mode hooks to specify it in certain modes, like this: ;;;###autoload (defcustom compilation-disable-input nil - "*If non-nil, send end-of-file as compilation process input. + "If non-nil, send end-of-file as compilation process input. This only affects platforms that support asynchronous processes (see `start-process'); synchronous compilation processes never accept input." :type 'boolean @@ -606,6 +681,41 @@ Faces `compilation-error-face', `compilation-warning-face', (defvar compilation-error-list nil) (defvar compilation-old-error-list nil) +(defcustom compilation-auto-jump-to-first-error nil + "If non-nil, automatically jump to the first error after `compile'." + :type 'boolean + :group 'compilation + :version "23.1") + +(defvar compilation-auto-jump-to-next nil + "If non-nil, automatically jump to the next error encountered.") +(make-variable-buffer-local 'compilation-auto-jump-to-next) + + +(defvar compilation-skip-to-next-location t + "*If non-nil, skip multiple error messages for the same source location.") + +(defcustom compilation-skip-threshold 1 + "Compilation motion commands skip less important messages. +The value can be either 2 -- skip anything less than error, 1 -- +skip anything less than warning or 0 -- don't skip any messages. +Note that all messages not positively identified as warning or +info, are considered errors." + :type '(choice (const :tag "Warnings and info" 2) + (const :tag "Info" 1) + (const :tag "None" 0)) + :group 'compilation + :version "22.1") + +(defcustom compilation-skip-visited nil + "Compilation motion commands skip visited messages if this is t. +Visited messages are ones for which the file, line and column have been jumped +to from the current content in the current compilation buffer, even if it was +from a different message." + :type 'boolean + :group 'compilation + :version "22.1") + (defun compilation-face (type) (or (and (car type) (match-end (car type)) compilation-warning-face) (and (cdr type) (match-end (cdr type)) compilation-info-face) @@ -653,13 +763,19 @@ Faces `compilation-error-face', `compilation-warning-face', l2 (setcdr l1 (cons (list ,key) l2))))))) +(defun compilation-auto-jump (buffer pos) + (with-current-buffer buffer + (goto-char pos) + (if compilation-auto-jump-to-first-error + (compile-goto-error)))) ;; This function is the central driver, called when font-locking to gather ;; all information needed to later jump to corresponding source code. ;; Return a property list with all meta information on this error location. (defun compilation-error-properties (file line end-line col end-col type fmt) - (unless (< (next-single-property-change (match-beginning 0) 'directory nil (point)) + (unless (< (next-single-property-change (match-beginning 0) + 'directory nil (point)) (point)) (if file (if (functionp file) @@ -711,6 +827,13 @@ Faces `compilation-error-face', `compilation-warning-face', (setq type (or (and (car type) (match-end (car type)) 1) (and (cdr type) (match-end (cdr type)) 0) 2))) + + (when (and compilation-auto-jump-to-next + (>= type compilation-skip-threshold)) + (kill-local-variable 'compilation-auto-jump-to-next) + (run-with-timer 0 nil 'compilation-auto-jump + (current-buffer) (match-beginning 0))) + (compilation-internal-error-properties file line end-line col end-col type fmt))) (defun compilation-move-to-column (col screen) @@ -917,7 +1040,7 @@ to a function that generates a unique name." (unless (equal command (eval compile-command)) (setq compile-command command)) (save-some-buffers (not compilation-ask-about-save) nil) - (setq compilation-directory default-directory) + (setq-default compilation-directory default-directory) (compilation-start command comint)) ;; run compile with the default command line @@ -927,20 +1050,22 @@ If this is run in a Compilation mode buffer, re-use the arguments from the original use. Otherwise, recompile using `compile-command'." (interactive) (save-some-buffers (not compilation-ask-about-save) nil) - (let ((default-directory - (or (and (not (eq major-mode (nth 1 compilation-arguments))) - compilation-directory) - default-directory))) + (let ((default-directory (or compilation-directory default-directory))) (apply 'compilation-start (or compilation-arguments `(,(eval compile-command)))))) (defcustom compilation-scroll-output nil - "*Non-nil to scroll the *compilation* buffer window as output appears. + "Non-nil to scroll the *compilation* buffer window as output appears. Setting it causes the Compilation mode commands to put point at the end of their output window so that the end of the output is always -visible rather than the beginning." - :type 'boolean +visible rather than the beginning. + +The value `first-error' stops scrolling at the first error, and leaves +point on its location in the *compilation* buffer." + :type '(choice (const :tag "No scrolling" nil) + (const :tag "Scroll compilation output" t) + (const :tag "Stop scrolling at the first error" first-error)) :version "20.3" :group 'compilation) @@ -957,8 +1082,7 @@ Otherwise, construct a buffer name from MODE-NAME." (funcall name-function mode-name)) (compilation-buffer-name-function (funcall compilation-buffer-name-function mode-name)) - ((and (eq mode-command major-mode) - (eq major-mode (nth 1 compilation-arguments))) + ((eq mode-command major-mode) (buffer-name)) (t (concat "*" (downcase mode-name) "*")))) @@ -1010,7 +1134,7 @@ Returns the compilation buffer created." (with-current-buffer (setq outbuf (get-buffer-create - (compilation-buffer-name name-of-mode mode name-function))) + (compilation-buffer-name name-of-mode mode name-function))) (let ((comp-proc (get-buffer-process (current-buffer)))) (if comp-proc (if (or (not (eq (process-status comp-proc) 'run)) @@ -1028,12 +1152,17 @@ Returns the compilation buffer created." (buffer-disable-undo (current-buffer)) ;; first transfer directory from where M-x compile was called (setq default-directory thisdir) + ;; Remember the original dir, so we can use it when we recompile. + ;; default-directory' can't be used reliably for that because it may be + ;; affected by the special handling of "cd ...;". + (set (make-local-variable 'compilation-directory) thisdir) ;; Make compilation buffer read-only. The filter can still write it. ;; Clear out the compilation buffer. (let ((inhibit-read-only t) (default-directory thisdir)) - ;; Then evaluate a cd command if any, but don't perform it yet, else start-command - ;; would do it again through the shell: (cd "..") AND sh -c "cd ..; make" + ;; Then evaluate a cd command if any, but don't perform it yet, else + ;; start-command would do it again through the shell: (cd "..") AND + ;; sh -c "cd ..; make" (cd (if (string-match "^\\s *cd\\(?:\\s +\\(\\S +?\\)\\)?\\s *[;&\n]" command) (if (match-end 1) (substitute-env-vars (match-string 1 command)) @@ -1049,6 +1178,9 @@ Returns the compilation buffer created." (if highlight-regexp (set (make-local-variable 'compilation-highlight-regexp) highlight-regexp)) + (if (or compilation-auto-jump-to-first-error + (eq compilation-scroll-output 'first-error)) + (set (make-local-variable 'compilation-auto-jump-to-next) t)) ;; Output a mode setter, for saving and later reloading this buffer. (insert "-*- mode: " name-of-mode "; default-directory: " (prin1-to-string default-directory) @@ -1060,7 +1192,8 @@ Returns the compilation buffer created." (setq thisdir default-directory)) (set-buffer-modified-p nil)) ;; Pop up the compilation buffer. - (setq outwin (display-buffer outbuf nil t)) + ;; http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01638.html + (setq outwin (display-buffer outbuf)) (with-current-buffer outbuf (let ((process-environment (append @@ -1101,60 +1234,34 @@ Returns the compilation buffer created." (funcall compilation-process-setup-function)) (compilation-set-window-height outwin) ;; Start the compilation. - (if (fboundp 'start-process) - (let ((proc (if (eq mode t) - (get-buffer-process - (with-no-warnings - (comint-exec outbuf (downcase mode-name) - shell-file-name nil `("-c" ,command)))) - (start-process-shell-command (downcase mode-name) - outbuf command)))) - ;; Make the buffer's mode line show process state. - (setq mode-line-process '(":%s")) - (set-process-sentinel proc 'compilation-sentinel) - (set-process-filter proc 'compilation-filter) - ;; Use (point-max) here so that output comes in - ;; after the initial text, - ;; regardless of where the user sees point. - (set-marker (process-mark proc) (point-max) outbuf) - (when compilation-disable-input - (condition-case nil - (process-send-eof proc) - ;; The process may have exited already. - (error nil))) - (setq compilation-in-progress - (cons proc compilation-in-progress))) - ;; No asynchronous processes available. - (message "Executing `%s'..." command) - ;; Fake modeline display as if `start-process' were run. - (setq mode-line-process ":run") - (force-mode-line-update) - (sit-for 0) ; Force redisplay - (save-excursion - ;; Insert the output at the end, after the initial text, - ;; regardless of where the user sees point. - (goto-char (point-max)) - (let* ((buffer-read-only nil) ; call-process needs to modify outbuf - (status (call-process shell-file-name nil outbuf nil "-c" - command))) - (cond ((numberp status) - (compilation-handle-exit 'exit status - (if (zerop status) - "finished\n" - (format "\ -exited abnormally with code %d\n" - status)))) - ((stringp status) - (compilation-handle-exit 'signal status - (concat status "\n"))) - (t - (compilation-handle-exit 'bizarre status status))))) - ;; Without async subprocesses, the buffer is not yet - ;; fontified, so fontify it now. - (let ((font-lock-verbose nil)) ; shut up font-lock messages - (font-lock-fontify-buffer)) - (set-buffer-modified-p nil) - (message "Executing `%s'...done" command))) + (let ((proc + (if (eq mode t) + ;; comint uses `start-file-process'. + (get-buffer-process + (with-no-warnings + (comint-exec + outbuf (downcase mode-name) + (if (file-remote-p default-directory) + "/bin/sh" + shell-file-name) + nil `("-c" ,command)))) + (start-file-process-shell-command (downcase mode-name) + outbuf command)))) + ;; Make the buffer's mode line show process state. + (setq mode-line-process '(":%s")) + (set-process-sentinel proc 'compilation-sentinel) + (set-process-filter proc 'compilation-filter) + ;; Use (point-max) here so that output comes in + ;; after the initial text, + ;; regardless of where the user sees point. + (set-marker (process-mark proc) (point-max) outbuf) + (when compilation-disable-input + (condition-case nil + (process-send-eof proc) + ;; The process may have exited already. + (error nil))) + (setq compilation-in-progress + (cons proc compilation-in-progress)))) ;; Now finally cd to where the shell started make/grep/... (setq default-directory thisdir)) (if (buffer-local-value 'compilation-scroll-output outbuf) @@ -1271,30 +1378,6 @@ exited abnormally with code %d\n" (put 'compilation-mode 'mode-class 'special) -(defvar compilation-skip-to-next-location t - "*If non-nil, skip multiple error messages for the same source location.") - -(defcustom compilation-skip-threshold 1 - "*Compilation motion commands skip less important messages. -The value can be either 2 -- skip anything less than error, 1 -- -skip anything less than warning or 0 -- don't skip any messages. -Note that all messages not positively identified as warning or -info, are considered errors." - :type '(choice (const :tag "Warnings and info" 2) - (const :tag "Info" 1) - (const :tag "None" 0)) - :group 'compilation - :version "22.1") - -(defcustom compilation-skip-visited nil - "*Compilation motion commands skip visited messages if this is t. -Visited messages are ones for which the file, line and column have been jumped -to from the current content in the current compilation buffer, even if it was -from a different message." - :type 'boolean - :group 'compilation - :version "22.1") - ;;;###autoload (defun compilation-mode (&optional name-of-mode) "Major mode for compilation log buffers. @@ -1388,6 +1471,8 @@ Optional argument MINOR indicates this is called from ;; with the next-error function in simple.el, and it's only ;; coincidentally named similarly to compilation-next-error. (setq next-error-function 'compilation-next-error-function) + (set (make-local-variable 'comint-file-name-prefix) + (or (file-remote-p default-directory) "")) (set (make-local-variable 'font-lock-extra-managed-props) '(directory message help-echo mouse-face debug)) (set (make-local-variable 'compilation-locs) @@ -1536,7 +1621,7 @@ Just inserts the text, but uses `insert-before-markers'." (eq (prog1 last (setq last (nth 2 (car msg)))) last)) (if compilation-skip-visited - (nthcdr 4 (car msg))) + (nthcdr 5 (car msg))) (if compilation-skip-to-next-location (eq (car msg) loc)) ;; count this message only if none of the above are true @@ -1556,6 +1641,7 @@ looking for the next message." (error "Not in a compilation buffer")) (or pt (setq pt (point))) (let* ((msg (get-text-property pt 'message)) + ;; `loc' is used by the compilation-loop macro. (loc (car msg)) last) (if (zerop n) @@ -1645,7 +1731,7 @@ This is the value of `next-error-function' in Compilation buffers." (when reset (setq compilation-current-error nil)) (let* ((columns compilation-error-screen-columns) ; buffer's local value - (last 1) + (last 1) timestamp (loc (compilation-next-error (or n 1) nil (or compilation-current-error compilation-messages-start @@ -1658,10 +1744,22 @@ This is the value of `next-error-function' in Compilation buffers." compilation-current-error (copy-marker (line-beginning-position))) loc (car loc)) - ;; If loc contains no marker, no error in that file has been visited. If - ;; the marker is invalid the buffer has been killed. So, recalculate all - ;; markers for that file. - (unless (and (nth 3 loc) (marker-buffer (nth 3 loc))) + ;; If loc contains no marker, no error in that file has been visited. + ;; If the marker is invalid the buffer has been killed. + ;; If the file is newer than the timestamp, it has been modified + ;; (`omake -P' polls filesystem for changes and recompiles when needed + ;; in the same process and buffer). + ;; So, recalculate all markers for that file. + (unless (and (nth 3 loc) (marker-buffer (nth 3 loc)) + ;; There may be no timestamp info if the loc is a `fake-loc'. + ;; So we skip the time-check here, although we should maybe + ;; change `compilation-fake-loc' to add timestamp info. + (or (null (nth 4 loc)) + (equal (nth 4 loc) + (setq timestamp + (with-current-buffer + (marker-buffer (nth 3 loc)) + (visited-file-modtime)))))) (with-current-buffer (compilation-find-file marker (caar (nth 2 loc)) (cadr (car (nth 2 loc)))) (save-restriction @@ -1684,7 +1782,8 @@ This is the value of `next-error-function' in Compilation buffers." (set-marker (nth 3 col) (point)) (setcdr (nthcdr 2 col) `(,(point-marker))))))))) (compilation-goto-locus marker (nth 3 loc) (nth 3 end-loc)) - (setcdr (nthcdr 3 loc) t))) ; Set this one as visited. + (setcdr (nthcdr 3 loc) (list timestamp)) + (setcdr (nthcdr 4 loc) t))) ; Set this one as visited. (defvar compilation-gcpro nil "Internal variable used to keep some values from being GC'd.") @@ -1710,7 +1809,7 @@ region and the first line of the next region." (or (consp file) (setq file (list file))) (setq file (compilation-get-file-structure file)) ;; Between the current call to compilation-fake-loc and the first occurrence - ;; of an error message referring to `file', the data is only kept is the + ;; of an error message referring to `file', the data is only kept in the ;; weak hash-table compilation-locs, so we need to prevent this entry ;; in compilation-locs from being GC'd away. --Stef (push file compilation-gcpro) @@ -1891,7 +1990,24 @@ attempts to find a file whose name is produced by (format FMT FILENAME)." (let* ((name (read-file-name (format "Find this %s in (default %s): " compilation-error filename) - spec-dir filename t nil)) + spec-dir filename t nil + ;; The predicate below is fine when called from + ;; minibuffer-complete-and-exit, but it's too + ;; restrictive otherwise, since it also prevents the + ;; user from completing "fo" to "foo/" when she + ;; wants to enter "foo/bar". + ;; + ;; Try to make sure the user can only select + ;; a valid answer. This predicate may be ignored, + ;; tho, so we still have to double-check afterwards. + ;; TODO: We should probably fix read-file-name so + ;; that it never ignores this predicate, even when + ;; using popup dialog boxes. + ;; (lambda (name) + ;; (if (file-directory-p name) + ;; (setq name (expand-file-name filename name))) + ;; (file-exists-p name)) + )) (origname name)) (cond ((not (file-exists-p name)) @@ -2045,9 +2161,9 @@ The file-structure looks like this: ;; compilation-error-list) to point-min, but that was only meaningful for ;; the internal uses of compilation-forget-errors: all calls from external ;; packages seem to be followed by a move of compilation-parsing-end to - ;; something equivalent to point-max. So we speculatively move + ;; something equivalent to point-max. So we heuristically move ;; compilation-current-error to point-max (since the external package - ;; won't know that it should do it). --stef + ;; won't know that it should do it). --Stef (setq compilation-current-error nil) (let* ((proc (get-buffer-process (current-buffer))) (mark (if proc (process-mark proc))) @@ -2058,7 +2174,13 @@ The file-structure looks like this: ;; we need to put ours just before the insertion point rather ;; than at the insertion point. If that's not possible, then ;; don't use a marker. --Stef - (if (> pos (point-min)) (copy-marker (1- pos)) pos)))) + (if (> pos (point-min)) (copy-marker (1- pos)) pos))) + ;; Again, since this command is used in buffers that contain several + ;; compilations, to set the beginning of "this compilation", it's a good + ;; place to reset compilation-auto-jump-to-next. + (set (make-local-variable 'compilation-auto-jump-to-next) + (or compilation-auto-jump-to-first-error + (eq compilation-scroll-output 'first-error)))) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.gcov\\'" . compilation-mode)) |