]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/flymake.el
Small flymake changes.
[gnu-emacs] / lisp / progmodes / flymake.el
index 715ddc2b8275adba839075612c879a4ed697a0ac..a90f380d1c3fbcf99df63c1321d3698820421c73 100644 (file)
@@ -1,6 +1,6 @@
 ;;; flymake.el -- a universal on-the-fly syntax checker
 
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 ;;   Free Software Foundation, Inc.
 
 ;; Author:  Pavel Kobyakov <pk_at_work@yahoo.com>
@@ -79,7 +79,7 @@
       'float-time
     (if (featurep 'xemacs)
        (lambda ()
-         (multiple-value-bind (s0 s1 s2) (current-time)
+         (multiple-value-bind (s0 s1 s2) (values-list (current-time))
            (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2)))))))
 
 (defalias 'flymake-replace-regexp-in-string
@@ -106,16 +106,6 @@ Zero-length substrings at the beginning and end of the list are omitted."
       'temp-directory
     (lambda () temporary-file-directory)))
 
-(defalias 'flymake-line-beginning-position
-  (if (fboundp 'line-beginning-position)
-      'line-beginning-position
-    (lambda (&optional arg) (save-excursion (beginning-of-line arg) (point)))))
-
-(defalias 'flymake-line-end-position
-  (if (fboundp 'line-end-position)
-      'line-end-position
-    (lambda (&optional arg) (save-excursion (end-of-line arg) (point)))))
-
 (defun flymake-posn-at-point-as-event (&optional position window dx dy)
   "Return pixel position of top left corner of glyph at POSITION,
 relative to top left corner of WINDOW, as a mouse-1 click
@@ -263,9 +253,13 @@ are the string substitutions (see `format')."
 
 (make-variable-buffer-local 'flymake-output-residual)
 
+(defgroup flymake nil
+  "A universal on-the-fly syntax checker."
+  :version "23.1"
+  :group 'tools)
+
 (defcustom flymake-allowed-file-name-masks
-  '(("\\.c\\'" flymake-simple-make-init)
-    ("\\.cpp\\'" flymake-simple-make-init)
+  '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'" flymake-simple-make-init)
     ("\\.xml\\'" flymake-xml-init)
     ("\\.html?\\'" flymake-xml-init)
     ("\\.cs\\'" flymake-simple-make-init)
@@ -286,7 +280,7 @@ are the string substitutions (see `format')."
     ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 ))
     ;; ("\\.tex\\'" 1)
     )
-  "*Files syntax checking is allowed for."
+  "Files syntax checking is allowed for."
   :group 'flymake
   :type '(repeat (string symbol symbol symbol)))
 
@@ -340,13 +334,10 @@ Return nil if we cannot, non-nil if we can."
 Buildfile includes Makefile, build.xml etc.
 Return its file name if found, or nil if not found."
   (or (flymake-get-buildfile-from-cache source-dir-name)
-      (let* ((file (locate-dominating-file
-                    source-dir-name
-                    (concat "\\`" (regexp-quote buildfile-name) "\\'"))))
+      (let* ((file (locate-dominating-file source-dir-name buildfile-name)))
         (if file
             (progn
               (flymake-log 3 "found buildfile at %s" file)
-              (setq file (file-name-directory file))
               (flymake-add-buildfile-to-cache source-dir-name file)
               file)
           (progn
@@ -382,7 +373,7 @@ Return t if so, nil if not."
 
 (defun flymake-find-possible-master-files (file-name master-file-dirs masks)
   "Find (by name and location) all possible master files.
-Master files are .cpp and .c for and .h.  Files are searched for
+Master files include .cpp and .c for .h.  Files are searched for
 starting from the .h directory and max max-level parent dirs.
 File contents are not checked."
   (let* ((dirs master-file-dirs)
@@ -422,9 +413,11 @@ to the beginning of the list (File.h -> File.cpp moved to top)."
        (not (equal file-one file-two))))
 
 (defcustom flymake-check-file-limit 8192
-  "Max number of chars to look at when checking possible master file."
+  "Maximum number of chars to look at when checking possible master file.
+Nil means search the entire file."
   :group 'flymake
-  :type 'integer)
+  :type '(choice (const :tag "No limit" nil)
+                 (integer :tag "Characters")))
 
 (defun flymake-check-patch-master-file-buffer
        (master-file-temp-buffer
@@ -432,22 +425,34 @@ to the beginning of the list (File.h -> File.cpp moved to top)."
         source-file-name patched-source-file-name
         include-dirs regexp)
   "Check if MASTER-FILE-NAME is a master file for SOURCE-FILE-NAME.
-For .cpp master file this means it includes SOURCE-FILE-NAME (.h).
 If yes, patch a copy of MASTER-FILE-NAME to include PATCHED-SOURCE-FILE-NAME
 instead of SOURCE-FILE-NAME.
+
+For example, foo.cpp is a master file if it includes foo.h.
+
 Whether a buffer for MATER-FILE-NAME exists, use it as a source
 instead of reading master file from disk."
   (let* ((source-file-nondir (file-name-nondirectory source-file-name))
+         (source-file-extension (file-name-extension source-file-nondir))
+         (source-file-nonext (file-name-sans-extension source-file-nondir))
          (found                     nil)
         (inc-name                  nil)
         (search-limit              flymake-check-file-limit))
     (setq regexp
           (format regexp       ; "[ \t]*#[ \t]*include[ \t]*\"\\(.*%s\\)\""
-                  (regexp-quote source-file-nondir)))
+                  ;; Hack for tex files, where \include often excludes .tex.
+                  ;; Maybe this is safe generally.
+                  (if (and (> (length source-file-extension) 1)
+                           (string-equal source-file-extension "tex"))
+                      (format "%s\\(?:\\.%s\\)?"
+                              (regexp-quote source-file-nonext)
+                              (regexp-quote source-file-extension))
+                    (regexp-quote source-file-nondir))))
     (unwind-protect
         (with-current-buffer master-file-temp-buffer
-          (when (> search-limit (point-max))
-            (setq search-limit (point-max)))
+          (if (or (not search-limit)
+                  (> search-limit (point-max)))
+              (setq search-limit (point-max)))
           (flymake-log 3 "checking %s against regexp %s"
                        master-file-name regexp)
           (goto-char (point-min))
@@ -458,6 +463,11 @@ instead of reading master file from disk."
 
               (flymake-log 3 "found possible match for %s" source-file-nondir)
               (setq inc-name (match-string 1))
+              (and (> (length source-file-extension) 1)
+                   (string-equal source-file-extension "tex")
+                   (not (string-match (format "\\.%s\\'" source-file-extension)
+                                      inc-name))
+                   (setq inc-name (concat inc-name "." source-file-extension)))
               (when (eq t (compare-strings
                            source-file-nondir nil nil
                            inc-name (- (length inc-name)
@@ -641,7 +651,7 @@ It's flymake process filter."
            (flymake-report-status "" "")       ; PASSED
          (if (not flymake-check-was-interrupted)
              (flymake-report-fatal-status "CFGERR"
-                                          (format "Configuration error has occured while running %s" command))
+                                          (format "Configuration error has occurred while running %s" command))
            (flymake-report-status nil ""))) ; "STOPPED"
       (flymake-report-status (format "%d/%d" err-count warn-count) ""))))
 
@@ -803,9 +813,10 @@ Return t if it has at least one flymake overlay, nil if no overlay."
 (defun flymake-highlight-line (line-no line-err-info-list)
   "Highlight line LINE-NO in current buffer.
 Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
-  (goto-line line-no)
-  (let* ((line-beg (flymake-line-beginning-position))
-        (line-end (flymake-line-end-position))
+  (goto-char (point-min))
+  (forward-line (1- line-no))
+  (let* ((line-beg (point-at-bol))
+        (line-end (point-at-eol))
         (beg      line-beg)
         (end      line-end)
         (tooltip-text (flymake-ler-text (nth 0 line-err-info-list)))
@@ -854,11 +865,9 @@ Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
                                       (flymake-ler-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)
-           (setq line-err-info (flymake-ler-set-file line-err-info nil))
-         (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))))
-
-       (setq err-info-list (flymake-add-err-info err-info-list line-err-info)))
+       (when (flymake-same-files real-file-name source-file-name)
+         (setq line-err-info (flymake-ler-set-file line-err-info nil))
+         (setq err-info-list (flymake-add-err-info err-info-list line-err-info))))
       (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no"))
       (setq idx (1+ idx)))
     err-info-list))
@@ -1150,7 +1159,8 @@ 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 (apply 'start-process "flymake-proc" (current-buffer) cmd args))
+         (setq process (apply 'start-file-process
+                              "flymake-proc" (current-buffer) cmd args))
          (set-process-sentinel process 'flymake-process-sentinel)
          (set-process-filter process 'flymake-process-filter)
           (push process flymake-processes)
@@ -1269,7 +1279,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
   (if (not (file-exists-p file))
       (flymake-log 1 "File %s does not exist" file)
     (find-file file)
-    (goto-line line)))
+    (goto-char (point-min))
+    (forward-line (1- line))))
 
 ;; flymake minor mode declarations
 (defvar flymake-mode-line nil)
@@ -1443,7 +1454,8 @@ With arg, turn Flymake mode on if and only if arg is positive."
 
 (defun flymake-goto-line (line-no)
   "Go to line LINE-NO, then skip whitespace."
-  (goto-line line-no)
+  (goto-char (point-min))
+  (forward-line (1- line-no))
   (flymake-skip-whitespace))
 
 (defun flymake-goto-next-error ()
@@ -1697,9 +1709,10 @@ Use CREATE-TEMP-F for creating temp copy."
 
 ;;;; .h/make specific
 (defun flymake-master-make-header-init ()
-  (flymake-master-make-init 'flymake-get-include-dirs
-                           '("\\.cpp\\'" "\\.c\\'")
-                           "[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
+  (flymake-master-make-init
+   'flymake-get-include-dirs
+   '("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'")
+   "[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
 
 ;;;; .java/make specific
 (defun flymake-simple-make-java-init ()
@@ -1741,11 +1754,14 @@ Use CREATE-TEMP-F for creating temp copy."
 (defun flymake-simple-tex-init ()
   (flymake-get-tex-args (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)))
 
+;; Perhaps there should be a buffer-local variable flymake-master-file
+;; that people can set to override this stuff.  Could inherit from
+;; the similar AUCTeX variable.
 (defun flymake-master-tex-init ()
   (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy
                                  'flymake-get-include-dirs-dot 'flymake-create-temp-inplace
                                 '("\\.tex\\'")
-                                "[ \t]*\\input[ \t]*{\\(.*%s\\)}")))
+                                "[ \t]*\\in\\(?:put\\|clude\\)[ \t]*{\\(.*%s\\)}")))
     (when temp-master-file-name
       (flymake-get-tex-args temp-master-file-name))))
 
@@ -1758,5 +1774,4 @@ Use CREATE-TEMP-F for creating temp copy."
 
 (provide 'flymake)
 
-;; arch-tag: 8f0d6090-061d-4cac-8862-7c151c4a02dd
 ;;; flymake.el ends here