diff options
Diffstat (limited to 'lisp/progmodes/flymake.el')
-rw-r--r-- | lisp/progmodes/flymake.el | 586 |
1 files changed, 268 insertions, 318 deletions
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 6f5d0855e19..4b14d321a46 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -1,6 +1,6 @@ ;;; flymake.el -- a universal on-the-fly syntax checker -;; Copyright (C) 2003, 2004, 2005 Free Software Foundation +;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation ;; Author: Pavel Kobiakov <pk_at_work@yahoo.com> ;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com> @@ -32,16 +32,33 @@ ;;; Code: -;;;; [[ Silence the byte-compiler +(defvar flymake-is-running nil + "If t, flymake syntax check process is running for the current buffer.") +(make-variable-buffer-local 'flymake-is-running) -(defvar flymake-check-start-time) -(defvar flymake-check-was-interrupted) -(defvar flymake-err-info) -(defvar flymake-is-running) -(defvar flymake-last-change-time) -(defvar flymake-new-err-info) +(defvar flymake-timer nil + "Timer for starting syntax check.") +(make-variable-buffer-local 'flymake-timer) -;;;; ]] +(defvar flymake-last-change-time nil + "Time of last buffer change.") +(make-variable-buffer-local 'flymake-last-change-time) + +(defvar flymake-check-start-time nil + "Time at which syntax check was started.") +(make-variable-buffer-local 'flymake-check-start-time) + +(defvar flymake-check-was-interrupted nil + "Non-nil if syntax check was killed by `flymake-compile'.") +(make-variable-buffer-local 'flymake-check-was-interrupted) + +(defvar flymake-err-info nil + "Sorted list of line numbers and lists of err info in the form (file, err-text).") +(make-variable-buffer-local 'flymake-err-info) + +(defvar flymake-new-err-info nil + "Same as `flymake-err-info', effective when a syntax check is in progress.") +(make-variable-buffer-local 'flymake-new-err-info) ;;;; [[ Xemacs overlay compatibility (if (featurep 'xemacs) (progn @@ -69,25 +86,30 @@ (multiple-value-bind (s0 s1 s2) (current-time) (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2))))))) -(defsubst flymake-replace-regexp-in-string (regexp rep str) - (if (fboundp 'replace-in-string) - (replace-in-string str regexp rep) - (replace-regexp-in-string regexp rep str))) - -(defun flymake-split-string (str pattern) - "Split STR into a list of substrings bounded by PATTERN. +(defalias 'flymake-replace-regexp-in-string + (if (eval-when-compile (fboundp 'replace-regexp-in-string)) + 'replace-regexp-in-string + (lambda (regexp rep str) + (replace-in-string str regexp rep)))) + +(defalias 'flymake-split-string + (if (condition-case nil (equal (split-string " bc " " " t) '("bc")) + (error nil)) + (lambda (str pattern) (split-string str pattern t)) + (lambda (str pattern) + "Split STR into a list of substrings bounded by PATTERN. Zero-length substrings at the beginning and end of the list are omitted." - (let* ((splitted (split-string str pattern))) - (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0)))) - (setq splitted (cdr splitted))) - (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted)))))) - (setq splitted (reverse (cdr (reverse splitted))))) - splitted)) - -(defsubst flymake-get-temp-dir () + (let ((split (split-string str pattern))) + (if (and (> (length split) 0) (= 0 (length (elt split 0)))) + (setq split (cdr split))) + (if (and (> (length split) 0) (= 0 (length (elt split (1- (length split)))))) + (setq split (nreverse (cdr (nreverse split))))) + split)))) + +(defalias 'flymake-get-temp-dir (if (fboundp 'temp-directory) - (temp-directory) - temporary-file-directory)) + 'temp-directory + (lambda () temporary-file-directory))) (defalias 'flymake-line-beginning-position (if (fboundp 'line-beginning-position) @@ -99,20 +121,26 @@ Zero-length substrings at the beginning and end of the list are omitted." 'line-end-position (lambda (&optional arg) (save-excursion (end-of-line arg) (point))))) -(defun flymake-popup-menu (pos menu-data) - "Pop up the flymake menu at position POS, using the data MENU-DATA. + +(defun flymake-popup-menu (menu-data) + "Pop up the flymake menu at point, using the data MENU-DATA. POS is a list of the form ((X Y) WINDOW), where X and Y are pixels positions from the top left corner of WINDOW's frame. MENU-DATA is a list of error and warning messages returned by `flymake-make-err-menu-data'." (if (featurep 'xemacs) - (let* ((x-pos (nth 0 (nth 0 pos))) - (y-pos (nth 1 (nth 0 pos))) + (let* ((pos (flymake-get-point-pixel-pos)) + (x-pos (nth 0 pos)) + (y-pos (nth 1 pos)) (fake-event-props '(button 1 x 1 y 1))) (setq fake-event-props (plist-put fake-event-props 'x x-pos)) (setq fake-event-props (plist-put fake-event-props 'y y-pos)) - (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props))) - (x-popup-menu pos (flymake-make-emacs-menu menu-data)))) + (popup-menu (flymake-make-xemacs-menu menu-data) + (make-event 'button-press fake-event-props))) + (x-popup-menu (if (eval-when-compile (fboundp 'posn-at-point)) + (posn-at-point) + (list (flymake-get-point-pixel-pos) (selected-window))) + (flymake-make-emacs-menu menu-data)))) (defun flymake-make-emacs-menu (menu-data) "Return a menu specifier using MENU-DATA. @@ -121,10 +149,9 @@ MENU-DATA is a list of error and warning messages returned by See `x-popup-menu' for the menu specifier format." (let* ((menu-title (nth 0 menu-data)) (menu-items (nth 1 menu-data)) - (menu-commands nil)) - (setq menu-commands (mapcar (lambda (foo) - (cons (nth 0 foo) (nth 1 foo))) - menu-items)) + (menu-commands (mapcar (lambda (foo) + (cons (nth 0 foo) (nth 1 foo))) + menu-items))) (list menu-title (cons "" menu-commands)))) (if (featurep 'xemacs) (progn @@ -141,21 +168,10 @@ See `x-popup-menu' for the menu specifier format." menu-items)) (cons menu-title menu-commands))) -(defun flymake-xemacs-window-edges (&optional window) - (let ((edges (window-pixel-edges window)) - tmp) - (setq tmp edges) - (setcar tmp (/ (car tmp) (face-width 'default))) - (setq tmp (cdr tmp)) - (setcar tmp (/ (car tmp) (face-height 'default))) - (setq tmp (cdr tmp)) - (setcar tmp (/ (car tmp) (face-width 'default))) - (setq tmp (cdr tmp)) - (setcar tmp (/ (car tmp) (face-height 'default))) - edges)) - )) ;; xemacs +(unless (eval-when-compile (fboundp 'posn-at-point)) + (defun flymake-current-row () "Return current row number in current frame." (if (fboundp 'window-edges) @@ -167,6 +183,24 @@ See `x-popup-menu' for the menu specifier format." (selected-frame) (selected-window))) +(defun flymake-get-point-pixel-pos () + "Return point position in pixels: (x, y)." + (let ((mouse-pos (mouse-position)) + (pixel-pos nil) + (ret nil)) + (if (car (cdr mouse-pos)) + (progn + (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row)) + (setq pixel-pos (mouse-pixel-position)) + (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos))) + (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos))))) + (progn + (setq ret '(0 0)))) + (flymake-log 3 "mouse pos is %s" ret) + ret)) + +) ;; End of (unless (fboundp 'posn-at-point) + ;;;; ]] (defcustom flymake-log-level -1 @@ -187,7 +221,7 @@ are the string substitutions (see `format')." ;;(with-temp-buffer ;; (insert msg) ;; (insert "\n") - ;; (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t) ; make log file name customizable + ;; (flymake-save-buffer-in-file "d:/flymake.log" t) ; make log file name customizable ;;) ))) @@ -203,59 +237,34 @@ are the string substitutions (see `format')." (setcar (nthcdr pos tmp) val) tmp)) -(defvar flymake-pid-to-names (flymake-makehash) - "Hash table mapping PIDs to source buffer names and output files.") - -(defun flymake-reg-names (pid source-buffer-name) - "Associate PID with SOURCE-BUFFER-NAME in `flymake-pid-to-names'." - (unless (stringp source-buffer-name) - (error "Invalid buffer name")) - (puthash pid (list source-buffer-name) flymake-pid-to-names)) - -(defun flymake-get-source-buffer-name (pid) - "Return buffer name associated with PID in `flymake-pid-to-names'." - (nth 0 (gethash pid flymake-pid-to-names))) - -(defun flymake-unreg-names (pid) - "Remove the entry associated with PID from `flymake-pid-to-names'." - (remhash pid flymake-pid-to-names)) - -(defvar flymake-buffer-data (flymake-makehash) - "Data specific to syntax check tool, in name-value pairs.") - -(make-variable-buffer-local 'flymake-buffer-data) - -(defun flymake-get-buffer-value (buffer name) - (gethash name (with-current-buffer buffer flymake-buffer-data))) - -(defun flymake-set-buffer-value (buffer name value) - (puthash name value (with-current-buffer buffer flymake-buffer-data))) +(defvar flymake-processes nil + "List of currently active flymake processes.") (defvar flymake-output-residual nil) (make-variable-buffer-local 'flymake-output-residual) (defcustom flymake-allowed-file-name-masks - '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name) - (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name) - (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name) - (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name) - (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) - ;; (".+\\.cpp$" 1) - ;; (".+\\.java$" 3) - ;; (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$") + '(("\\.c\\'" flymake-simple-make-init) + ("\\.cpp\\'" flymake-simple-make-init) + ("\\.xml\\'" flymake-xml-init) + ("\\.html?\\'" flymake-xml-init) + ("\\.cs\\'" flymake-simple-make-init) + ("\\.pl\\'" flymake-perl-init) + ("\\.h\\'" flymake-master-make-header-init flymake-master-cleanup) + ("\\.java\\'" flymake-simple-make-java-init flymake-simple-java-cleanup) + ("[0-9]+\\.tex\\'" flymake-master-tex-init flymake-master-cleanup) + ("\\.tex\\'" flymake-simple-tex-init) + ("\\.idl\\'" flymake-simple-make-init) + ;; ("\\.cpp\\'" 1) + ;; ("\\.java\\'" 3) + ;; ("\\.h\\'" 2 ("\\.cpp\\'" "\\.c\\'") ;; ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) - ;; (".+\\.idl$" 1) - ;; (".+\\.odl$" 1) - ;; (".+[0-9]+\\.tex$" 2 (".+\\.tex$") + ;; ("\\.idl\\'" 1) + ;; ("\\.odl\\'" 1) + ;; ("[0-9]+\\.tex\\'" 2 ("\\.tex\\'") ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) - ;; (".+\\.tex$" 1) + ;; ("\\.tex\\'" 1) ) "*Files syntax checking is allowed for." :group 'flymake @@ -288,10 +297,12 @@ Return nil if we cannot, non-nil if we can." (defun flymake-get-cleanup-function (file-name) "Return cleanup function to be used for the file." - (nth 1 (flymake-get-file-name-mode-and-masks file-name))) + (or (nth 1 (flymake-get-file-name-mode-and-masks file-name)) + 'flymake-simple-cleanup)) (defun flymake-get-real-file-name-function (file-name) - (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name)) + (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) + 'flymake-get-real-file-name)) (defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..") "Dirs to look for buildfile." @@ -491,7 +502,7 @@ instead of reading master file from disk." (file-name-nondirectory patched-source-file-name)))) (forward-line 1))) (when found - (flymake-save-buffer-in-file (current-buffer) patched-master-file-name))) + (flymake-save-buffer-in-file patched-master-file-name))) ;;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer)) (kill-buffer master-file-temp-buffer))) ;;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found) @@ -581,15 +592,12 @@ Find master file, patch and save it." (file-name-nondirectory source-file-name)) nil)))) -(defun flymake-save-buffer-in-file (buffer file-name) - (or buffer - (error "Invalid buffer")) - (with-current-buffer buffer - (save-restriction - (widen) - (make-directory (file-name-directory file-name) 1) - (write-region (point-min) (point-max) file-name nil 566))) - (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name)) +(defun flymake-save-buffer-in-file (file-name) + (save-restriction + (widen) + (make-directory (file-name-directory file-name) 1) + (write-region (point-min) (point-max) file-name nil 566)) + (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name)) (defun flymake-save-string-to-file (file-name data) "Save string DATA to file FILE-NAME." @@ -604,44 +612,46 @@ Find master file, patch and save it." (defun flymake-process-filter (process output) "Parse OUTPUT and highlight error lines. It's flymake process filter." - (let* ((pid (process-id process)) - (source-buffer (get-buffer (flymake-get-source-buffer-name pid)))) + (let ((source-buffer (process-buffer process))) - (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid) + (flymake-log 3 "received %d byte(s) of output from process %d" + (length output) (process-id process)) (when source-buffer (with-current-buffer source-buffer (flymake-parse-output-and-residual output))))) (defun flymake-process-sentinel (process event) "Sentinel for syntax check buffers." - (if (memq (process-status process) '(signal exit)) - (let*((exit-status (process-exit-status process)) - (command (process-command process)) - (pid (process-id process)) - (source-buffer (get-buffer (flymake-get-source-buffer-name pid))) - (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer)))) - - (flymake-log 2 "process %d exited with code %d" pid exit-status) - (condition-case err - (progn - (flymake-log 3 "cleaning up using %s" cleanup-f) - (funcall cleanup-f source-buffer) - - (flymake-unreg-names pid) - (delete-process process) - - (when source-buffer - (with-current-buffer source-buffer - - (flymake-parse-residual) - (flymake-post-syntax-check exit-status command) - (setq flymake-is-running nil)))) - (error - (let ((err-str (format "Error in process sentinel for buffer %s: %s" - source-buffer (error-message-string err)))) - (flymake-log 0 err-str) - (with-current-buffer source-buffer - (setq flymake-is-running nil)))))))) + (when (memq (process-status process) '(signal exit)) + (let* ((exit-status (process-exit-status process)) + (command (process-command process)) + (source-buffer (process-buffer process)) + (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer)))) + + (flymake-log 2 "process %d exited with code %d" + (process-id process) exit-status) + (condition-case err + (progn + (flymake-log 3 "cleaning up using %s" cleanup-f) + (when (buffer-live-p source-buffer) + (with-current-buffer source-buffer + (funcall cleanup-f))) + + (delete-process process) + (setq flymake-processes (delq process flymake-processes)) + + (when (buffer-live-p source-buffer) + (with-current-buffer source-buffer + + (flymake-parse-residual) + (flymake-post-syntax-check exit-status command) + (setq flymake-is-running nil)))) + (error + (let ((err-str (format "Error in process sentinel for buffer %s: %s" + source-buffer (error-message-string err)))) + (flymake-log 0 err-str) + (with-current-buffer source-buffer + (setq flymake-is-running nil)))))))) (defun flymake-post-syntax-check (exit-status command) (setq flymake-err-info flymake-new-err-info) @@ -689,11 +699,6 @@ It's flymake process filter." (list flymake-output-residual))) (setq flymake-output-residual nil))) -(defvar flymake-err-info nil - "Sorted list of line numbers and lists of err info in the form (file, err-text).") - -(make-variable-buffer-local 'flymake-err-info) - (defun flymake-er-make-er (line-no line-err-info-list) (list line-no line-err-info-list)) @@ -703,11 +708,6 @@ It's flymake process filter." (defun flymake-er-get-line-err-info-list (err-info) (nth 1 err-info)) -(defvar flymake-new-err-info nil - "Same as `flymake-err-info', effective when a syntax check is in progress.") - -(make-variable-buffer-local 'flymake-new-err-info) - ;; getters/setters for line-err-info: (file, line, type, text). (defun flymake-ler-make-ler (file line type text &optional full-file) (list file line type text full-file)) @@ -897,7 +897,8 @@ Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting." (while (< idx count) (setq line-err-info (flymake-parse-line (nth idx lines))) (when line-err-info - (setq real-file-name (funcall get-real-file-name-f (current-buffer) (flymake-ler-get-file line-err-info))) + (setq real-file-name (funcall get-real-file-name-f + (flymake-ler-get-file line-err-info))) (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name)) (if (flymake-same-files real-file-name source-file-name) @@ -1131,12 +1132,12 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." ;; "Remove any formatting made by flymake." ;; ) -(defun flymake-get-program-dir (buffer) - "Get dir to start program in." - (unless (bufferp buffer) - (error "Invalid buffer")) - (with-current-buffer buffer - default-directory)) +;; (defun flymake-get-program-dir (buffer) +;; "Get dir to start program in." +;; (unless (bufferp buffer) +;; (error "Invalid buffer")) +;; (with-current-buffer buffer +;; default-directory)) (defun flymake-safe-delete-file (file-name) (when (and file-name (file-exists-p file-name)) @@ -1168,19 +1169,18 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." (flymake-clear-project-include-dirs-cache) (setq flymake-check-was-interrupted nil) - (setq flymake-buffer-data (flymake-makehash 'equal)) (let* ((source-file-name buffer-file-name) (init-f (flymake-get-init-function source-file-name)) (cleanup-f (flymake-get-cleanup-function source-file-name)) - (cmd-and-args (funcall init-f (current-buffer))) + (cmd-and-args (funcall init-f)) (cmd (nth 0 cmd-and-args)) (args (nth 1 cmd-and-args)) (dir (nth 2 cmd-and-args))) (if (not cmd-and-args) (progn (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name) - (funcall cleanup-f (current-buffer))) + (funcall cleanup-f)) (progn (setq flymake-last-change-time nil) (flymake-start-syntax-check-process cmd args dir))))))) @@ -1193,11 +1193,10 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." (when dir (let ((default-directory dir)) (flymake-log 3 "starting process on dir %s" default-directory))) - (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args))) + (setq process (apply 'start-process "flymake-proc" (current-buffer) cmd args)) (set-process-sentinel process 'flymake-process-sentinel) (set-process-filter process 'flymake-process-filter) - - (flymake-reg-names (process-id process) (buffer-name)) + (push process flymake-processes) (setq flymake-is-running t) (setq flymake-last-change-time nil) @@ -1205,7 +1204,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." (flymake-report-status nil "*") (flymake-log 2 "started process %d, command=%s, dir=%s" - (process-id process) (process-command process) default-directory) + (process-id process) (process-command process) + default-directory) process) (error (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s" @@ -1213,23 +1213,23 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." (source-file-name buffer-file-name) (cleanup-f (flymake-get-cleanup-function source-file-name))) (flymake-log 0 err-str) - (funcall cleanup-f (current-buffer)) + (funcall cleanup-f) (flymake-report-fatal-status "PROCERR" err-str)))))) -(defun flymake-kill-process (pid &optional rest) - "Kill process PID." - (signal-process pid 9) - (let* ((buffer-name (flymake-get-source-buffer-name pid))) - (when (and buffer-name (get-buffer buffer-name)) - (with-current-buffer (get-buffer buffer-name) +(defun flymake-kill-process (proc) + "Kill process PROC." + (kill-process proc) + (let* ((buf (process-buffer proc))) + (when (buffer-live-p buf) + (with-current-buffer buf (setq flymake-check-was-interrupted t)))) - (flymake-log 1 "killed process %d" pid)) + (flymake-log 1 "killed process %d" (process-id proc))) (defun flymake-stop-all-syntax-checks () "Kill all syntax check processes." (interactive) - (let ((pids (copy-hash-table flymake-pid-to-names))) - (maphash 'flymake-kill-process pids))) + (while flymake-processes + (flymake-kill-process (pop flymake-processes)))) (defun flymake-compilation-is-running () (and (boundp 'compilation-in-progress) @@ -1241,31 +1241,6 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." (flymake-stop-all-syntax-checks) (call-interactively 'compile)) -(defvar flymake-is-running nil - "If t, flymake syntax check process is running for the current buffer.") - -(make-variable-buffer-local 'flymake-is-running) - -(defvar flymake-timer nil - "Timer for starting syntax check.") - -(make-variable-buffer-local 'flymake-timer) - -(defvar flymake-last-change-time nil - "Time of last buffer change.") - -(make-variable-buffer-local 'flymake-last-change-time) - -(defvar flymake-check-start-time nil - "Time at which syntax check was started.") - -(make-variable-buffer-local 'flymake-check-start-time) - -(defvar flymake-check-was-interrupted nil - "Non-nil if syntax check was killed by `flymake-compile'.") - -(make-variable-buffer-local 'flymake-check-was-interrupted) - (defcustom flymake-no-changes-timeout 0.5 "Time to wait after last change before starting compilation." :group 'flymake @@ -1294,33 +1269,16 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'." "Return number of lines in buffer BUFFER." (count-lines (point-min) (point-max))) -(defun flymake-get-point-pixel-pos () - "Return point position in pixels: (x, y)." - (let ((mouse-pos (mouse-position)) - (pixel-pos nil) - (ret nil)) - (if (car (cdr mouse-pos)) - (progn - (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row)) - (setq pixel-pos (mouse-pixel-position)) - (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos))) - (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos))))) - (progn - (setq ret '(0 0)))) - (flymake-log 3 "mouse pos is %s" ret) - ret)) - (defun flymake-display-err-menu-for-current-line () "Display a menu with errors/warnings for current line if it has errors and/or warnings." (interactive) (let* ((line-no (flymake-current-line-no)) (line-err-info-list (nth 0 (flymake-find-err-info flymake-err-info line-no))) (menu-data (flymake-make-err-menu-data line-no line-err-info-list)) - (choice nil) - (menu-pos (list (flymake-get-point-pixel-pos) (selected-window)))) + (choice nil)) (if menu-data (progn - (setq choice (flymake-popup-menu menu-pos menu-data)) + (setq choice (flymake-popup-menu menu-data)) (flymake-log 3 "choice=%s" choice) (when choice (eval choice))) @@ -1579,20 +1537,14 @@ With arg, turn Flymake mode on if and only if arg is positive." (error "Invalid file-name")) (let* ((dir (file-name-directory file-name)) + ;; Not sure what this slash-pos is all about, but I guess it's just + ;; trying to remove the leading / of absolute file names. (slash-pos (string-match "/" dir)) - (temp-dir (concat (file-name-as-directory (flymake-get-temp-dir)) (substring dir (1+ slash-pos))))) + (temp-dir (expand-file-name (substring dir (1+ slash-pos)) + (flymake-get-temp-dir)))) - (file-truename (concat (file-name-as-directory temp-dir) - (file-name-nondirectory file-name))))) - -(defun flymake-strrchr (str ch) - (let* ((count (length str)) - (pos nil)) - (while (and (not pos) (> count 0)) - (if (= ch (elt str (1- count))) - (setq pos (1- count))) - (setq count (1- count))) - pos)) + (file-truename (expand-file-name (file-name-nondirectory file-name) + temp-dir)))) (defun flymake-delete-temp-directory (dir-name) "Attempt to delete temp dir created by `flymake-create-temp-with-folder-structure', do not fail on error." @@ -1601,45 +1553,55 @@ With arg, turn Flymake mode on if and only if arg is positive." (slash-pos nil)) (while (> (length suffix) 0) + (setq suffix (directory-file-name suffix)) ;;+(flymake-log 0 "suffix=%s" suffix) - (flymake-safe-delete-directory (file-truename (concat (file-name-as-directory temp-dir) suffix))) - (setq slash-pos (flymake-strrchr suffix (string-to-char "/"))) - (if slash-pos - (setq suffix (substring suffix 0 slash-pos)) - (setq suffix ""))))) + (flymake-safe-delete-directory + (file-truename (expand-file-name suffix temp-dir))) + (setq suffix (file-name-directory suffix))))) + +(defvar flymake-temp-source-file-name nil) +(make-variable-buffer-local 'flymake-temp-source-file-name) + +(defvar flymake-master-file-name nil) +(make-variable-buffer-local 'flymake-master-file-name) + +(defvar flymake-temp-master-file-name nil) +(make-variable-buffer-local 'flymake-temp-master-file-name) -(defun flymake-init-create-temp-buffer-copy (buffer create-temp-f) +(defvar flymake-base-dir nil) +(make-variable-buffer-local 'flymake-base-dir) + +(defun flymake-init-create-temp-buffer-copy (create-temp-f) "Make a temporary copy of the current buffer, save its name in buffer data and return the name." - (let* ((source-file-name (buffer-file-name buffer)) + (let* ((source-file-name buffer-file-name) (temp-source-file-name (funcall create-temp-f source-file-name "flymake"))) - (flymake-save-buffer-in-file buffer temp-source-file-name) - (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name) + (flymake-save-buffer-in-file temp-source-file-name) + (setq flymake-temp-source-file-name temp-source-file-name) temp-source-file-name)) -(defun flymake-simple-cleanup (buffer) +(defun flymake-simple-cleanup () "Do cleanup after `flymake-init-create-temp-buffer-copy'. Delete temp file." - (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) - (flymake-safe-delete-file temp-source-file-name) - (with-current-buffer buffer - (setq flymake-last-change-time nil)))) + (flymake-safe-delete-file flymake-temp-source-file-name) + (setq flymake-last-change-time nil)) -(defun flymake-get-real-file-name (buffer file-name-from-err-msg) +(defun flymake-get-real-file-name (file-name-from-err-msg) "Translate file name from error message to \"real\" file name. Return full-name. Names are real, not patched." - (let* ((real-name nil) - (source-file-name (buffer-file-name buffer)) - (master-file-name (flymake-get-buffer-value buffer "master-file-name")) - (temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")) - (temp-master-file-name (flymake-get-buffer-value buffer "temp-master-file-name")) - (base-dirs (list (flymake-get-buffer-value buffer "base-dir") - (file-name-directory source-file-name) - (if master-file-name (file-name-directory master-file-name) nil))) - (files (list (list source-file-name source-file-name) - (list temp-source-file-name source-file-name) - (list master-file-name master-file-name) - (list temp-master-file-name master-file-name)))) + (let* ((real-name nil) + (source-file-name buffer-file-name) + (master-file-name flymake-master-file-name) + (temp-source-file-name flymake-temp-source-file-name) + (temp-master-file-name flymake-temp-master-file-name) + (base-dirs + (list flymake-base-dir + (file-name-directory source-file-name) + (if master-file-name (file-name-directory master-file-name)))) + (files (list (list source-file-name source-file-name) + (list temp-source-file-name source-file-name) + (list master-file-name master-file-name) + (list temp-master-file-name master-file-name)))) (when (equal 0 (length file-name-from-err-msg)) (setq file-name-from-err-msg source-file-name)) @@ -1687,27 +1649,23 @@ Return full-name. Names are real, not patched." (setq base-dirs-count (1- base-dirs-count)))))) real-name)) -(defun flymake-init-find-buildfile-dir (buffer source-file-name buildfile-name) +(defun flymake-init-find-buildfile-dir (source-file-name buildfile-name) "Find buildfile, store its dir in buffer data and return its dir, if found." - (let* ((buildfile-dir (flymake-find-buildfile buildfile-name - (file-name-directory source-file-name) - flymake-buildfile-dirs))) - (if (not buildfile-dir) - (progn - (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name) - (with-current-buffer buffer - (flymake-report-fatal-status "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name))) - ) - (progn - (flymake-set-buffer-value buffer "base-dir" buildfile-dir))) - buildfile-dir)) + (let* ((buildfile-dir + (flymake-find-buildfile buildfile-name + (file-name-directory source-file-name) + flymake-buildfile-dirs))) + (if buildfile-dir + (setq flymake-base-dir buildfile-dir) + (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name) + (flymake-report-fatal-status + "NOMK" (format "No buildfile (%s) found for %s" + buildfile-name source-file-name))))) -(defun flymake-init-create-temp-source-and-master-buffer-copy (buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list) +(defun flymake-init-create-temp-source-and-master-buffer-copy (get-incl-dirs-f create-temp-f master-file-masks include-regexp-list) "Find master file (or buffer), create it's copy along with a copy of the source file." - (let* ((source-file-name (buffer-file-name buffer)) - (temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f)) - (master-file-name nil) - (temp-master-file-name nil) + (let* ((source-file-name buffer-file-name) + (temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f)) (master-and-temp-master (flymake-create-master-file source-file-name temp-source-file-name get-incl-dirs-f create-temp-f @@ -1716,21 +1674,14 @@ Return full-name. Names are real, not patched." (if (not master-and-temp-master) (progn (flymake-log 1 "cannot find master file for %s" source-file-name) - (when (bufferp buffer) - (with-current-buffer buffer - (flymake-report-status "!" ""))) ; NOMASTER - ) - (progn - (setq master-file-name (nth 0 master-and-temp-master)) - (setq temp-master-file-name (nth 1 master-and-temp-master)) - (flymake-set-buffer-value buffer "master-file-name" master-file-name) - (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name) - )) - temp-master-file-name)) + (flymake-report-status "!" "") ; NOMASTER + nil) + (setq flymake-master-file-name (nth 0 master-and-temp-master)) + (setq flymake-temp-master-file-name (nth 1 master-and-temp-master))))) -(defun flymake-master-cleanup (buffer) - (flymake-simple-cleanup buffer) - (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name"))) +(defun flymake-master-cleanup () + (flymake-simple-cleanup) + (flymake-safe-delete-file flymake-temp-master-file-name)) ;;;; make-specific init-cleanup routines (defun flymake-get-syntax-check-program-args (source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f) @@ -1762,30 +1713,30 @@ Return full-name. Names are real, not patched." (concat "-DCHK_SOURCES=" source) "check-syntax"))) -(defun flymake-simple-make-init-impl (buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f) +(defun flymake-simple-make-init-impl (create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f) "Create syntax check command line for a directly checked source file. Use CREATE-TEMP-F for creating temp copy." (let* ((args nil) - (source-file-name (buffer-file-name buffer)) - (buildfile-dir (flymake-init-find-buildfile-dir buffer source-file-name build-file-name))) + (source-file-name buffer-file-name) + (buildfile-dir (flymake-init-find-buildfile-dir source-file-name build-file-name))) (if buildfile-dir - (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f))) + (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f))) (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir use-relative-base-dir use-relative-source get-cmdline-f)))) args)) -(defun flymake-simple-make-init (buffer) - (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline)) +(defun flymake-simple-make-init () + (flymake-simple-make-init-impl 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline)) -(defun flymake-master-make-init (buffer get-incl-dirs-f master-file-masks include-regexp-list) +(defun flymake-master-make-init (get-incl-dirs-f master-file-masks include-regexp-list) "Create make command line for a source file checked via master file compilation." (let* ((make-args nil) (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy - buffer get-incl-dirs-f 'flymake-create-temp-inplace + get-incl-dirs-f 'flymake-create-temp-inplace master-file-masks include-regexp-list))) (when temp-master-file-name - (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile"))) + (let* ((buildfile-dir (flymake-init-find-buildfile-dir temp-master-file-name "Makefile"))) (if buildfile-dir (setq make-args (flymake-get-syntax-check-program-args temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline))))) @@ -1795,30 +1746,29 @@ Use CREATE-TEMP-F for creating temp copy." (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs)) ;;;; .h/make specific -(defun flymake-master-make-header-init (buffer) - (flymake-master-make-init buffer - 'flymake-get-include-dirs - '(".+\\.cpp$" ".+\\.c$") +(defun flymake-master-make-header-init () + (flymake-master-make-init 'flymake-get-include-dirs + '("\\.cpp\\'" "\\.c\\'") '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2))) ;;;; .java/make specific -(defun flymake-simple-make-java-init (buffer) - (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline)) +(defun flymake-simple-make-java-init () + (flymake-simple-make-init-impl 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline)) -(defun flymake-simple-ant-java-init (buffer) - (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline)) +(defun flymake-simple-ant-java-init () + (flymake-simple-make-init-impl 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline)) -(defun flymake-simple-java-cleanup (buffer) +(defun flymake-simple-java-cleanup () "Cleanup after `flymake-simple-make-java-init' -- delete temp file and dirs." - (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) - (flymake-safe-delete-file temp-source-file-name) - (when temp-source-file-name - (flymake-delete-temp-directory (file-name-directory temp-source-file-name))))) + (flymake-safe-delete-file flymake-temp-source-file-name) + (when flymake-temp-source-file-name + (flymake-delete-temp-directory + (file-name-directory flymake-temp-source-file-name)))) ;;;; perl-specific init-cleanup routines -(defun flymake-perl-init (buffer) +(defun flymake-perl-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy - buffer 'flymake-create-temp-inplace)) + 'flymake-create-temp-inplace)) (local-file (concat (flymake-build-relative-filename (file-name-directory buffer-file-name) (file-name-directory temp-file)) @@ -1830,13 +1780,13 @@ Use CREATE-TEMP-F for creating temp copy." ;;(list "latex" (list "-c-style-errors" file-name)) (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name))) -(defun flymake-simple-tex-init (buffer) - (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))) +(defun flymake-simple-tex-init () + (flymake-get-tex-args (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace))) -(defun flymake-master-tex-init (buffer) +(defun flymake-master-tex-init () (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy - buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace - '(".+\\.tex$") + 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace + '("\\.tex\\'") '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2)))) (when temp-master-file-name (flymake-get-tex-args temp-master-file-name)))) @@ -1845,8 +1795,8 @@ Use CREATE-TEMP-F for creating temp copy." '(".")) ;;;; xml-specific init-cleanup routines -(defun flymake-xml-init (buffer) - (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)))) +(defun flymake-xml-init () + (list "xml" (list "val" (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)))) (provide 'flymake) |