[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#5911: flymake.el - enhancement request - flymake-goto-next-error sho
From: |
D Chiesa |
Subject: |
bug#5911: flymake.el - enhancement request - flymake-goto-next-error should go to the column, if possible |
Date: |
Fri, 9 Apr 2010 01:44:59 -0400 |
I use emacs v22.2.1 on Windows.
Flymake relies on compilation error patterns, similar to
compilation-error-regexp-alist , to detect errors and warnings.
But flymake discards column information for any errors, and as a result,
the functions flymake-goto-next-error and flymake-goto-prev-error do not
position the cursor on the error column.
This discards useful information, and also makes it more difficult to add
enhancements to flymake - such as the ability to offer a menu of "quick
fixes" that can be applied on the spot, through
flymake-display-err-menu-for-current-line .
The fix is to:
1- modify the flymake-ler struct, like so:
(defstruct (flymake-ler
(:constructor nil)
;; cheeso = 2010 apr 8 - add col-no field
(:constructor flymake-ler-make-ler (file line type text
&optional full-file col-no)))
file line type text full-file col-no)
2- modify the flymake-ler functions, accordingly
(defun flymake-ler-set-file (line-err-info file)
(flymake-ler-make-ler file
(flymake-ler-line line-err-info)
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
(flymake-ler-full-file line-err-info)
;; cheeso - 2010 apr 8
(flymake-ler-col-no line-err-info)
))
(defun flymake-ler-set-full-file (line-err-info full-file)
(flymake-ler-make-ler (flymake-ler-file line-err-info)
(flymake-ler-line line-err-info)
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
full-file
;; cheeso - 2010 apr 8
(flymake-ler-col-no line-err-info)
))
(defun flymake-ler-set-line (line-err-info line)
(flymake-ler-make-ler (flymake-ler-file line-err-info)
line
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
(flymake-ler-full-file line-err-info)
;; cheeso - 2010 apr 8
(flymake-ler-col-no line-err-info)
))
3- modify flymake-parse-line to capture the column number, and store it
in the flymake-ler struct that is created. (same as line-no, but use index
3, instead of 2)
(defun flymake-parse-line (line)
"Parse LINE to see if it is an error or warning.
Return its components if so, nil otherwise."
(let ((raw-file-name nil)
(line-no 0)
(col-no 0)
(err-type "e")
(err-text nil)
(patterns flymake-err-line-patterns)
(matched nil))
(while (and patterns (not matched))
(when (string-match (car (car patterns)) line)
(let* ((file-idx (nth 1 (car patterns)))
(line-idx (nth 2 (car patterns)))
(col-idx (nth 3 (car patterns)))
)
(setq raw-file-name (if file-idx (match-string file-idx line)
nil))
(setq line-no (if line-idx (string-to-number (match-string
line-idx line)) 0))
(setq col-no (if col-idx (string-to-number (match-string
col-idx line)) 0))
(setq err-text (if (> (length (car patterns)) 4)
(match-string (nth 4 (car patterns)) line)
(flymake-patch-err-text (substring line
(match-end 0)))))
(or err-text (setq err-text "<no error text>"))
(if (and err-text (string-match "^[wW]arning" err-text))
(setq err-type "w")
)
(flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s
line=%s text=%s" file-idx line-idx
raw-file-name line-no err-text)
(setq matched t)))
(setq patterns (cdr patterns)))
(if matched
;; cheeso
;;(flymake-ler-make-ler raw-file-name line-no err-type err-text)
(flymake-ler-make-ler raw-file-name line-no err-type err-text nil
col-no)
())))
4 - introduce new fn flymake-er-get-line-col , which returns (LINE COL) for
the error.
(defun flymake-er-get-line-col (err-info)
(list (nth 0 err-info)
(flymake-ler-col-no (car (nth 1 err-info))) ;; xxxx
))
5- transform all fns that get line number info, to get line+col info:
(defun flymake-get-first-err-line-col (err-info-list)
"Return first line with error."
(when err-info-list
(flymake-er-get-line-col (car err-info-list))))
(defun flymake-get-last-err-line-col (err-info-list)
"Return last line with error."
(when err-info-list
(flymake-er-get-line-col (nth (1- (length err-info-list))
err-info-list))))
(defun flymake-get-next-err-line-col (err-info-list line-no)
"Return next line with error."
(when err-info-list
(let* ((count (length err-info-list))
(idx 0))
(while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx
err-info-list))))
(setq idx (1+ idx)))
(if (< idx count)
(flymake-er-get-line-col (nth idx err-info-list))))))
(defun flymake-get-prev-err-line-col (err-info-list line-no)
"Return previous line with error."
(when err-info-list
(let* ((count (length err-info-list)))
(while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1-
count) err-info-list))))
(setq count (1- count)))
(if (> count 0)
(flymake-er-get-line-col (nth (1- count) err-info-list))))))
6- modify flymake-goto-next-error to use the column information
(defun flymake-goto-next-error ()
"Go to next error in error ring. Return (LINE COL), or nil if there are no
errors."
(interactive)
(let* ((line-col (flymake-get-next-err-line-col flymake-err-info
(flymake-current-line-no)))
(line-no (car line-col))
(col-no (cadr line-col))
)
(when (not line-no)
(setq line-col (flymake-get-first-err-line-col flymake-err-info))
(setq line-no (car line-col)
col-no (cadr line-col))
(flymake-log 1 "passed end of file"))
(if line-no
(flymake-goto-line line-col)
(flymake-log 1 "no errors in current buffer"))))
7- same for flymake-goto-prev-error
(defun flymake-goto-prev-error ()
"Go to previous error in err ring."
(interactive)
(let* ((line-col (flymake-get-prev-err-line-col flymake-err-info
(flymake-current-line-no)))
(line-no (car line-col))
(col-no (cadr line-col))
)
(when (not line-no)
(setq line-col (flymake-get-last-err-line-col flymake-err-info))
(setq line-no (car line-col)
col-no (cadr line-col))
(flymake-log 1 "passed beginning of file"))
(if line-no
(flymake-goto-line line-col)
(flymake-log 1 "no errors in current buffer"))))
8- modify flymake-goto-line to accept a (LINE COL) list, and act accordingly
(defun flymake-goto-line (line-col)
"LINE-COL contains (LINE-NO COL-NO). Go to line LINE-NO, then skip to the
COL-NO column."
(let ((line-no (car line-col))
(col-no (cadr line-col))
)
(goto-line line-no)
(when col-no
(while (> col-no 1)
(setq col-no (1- col-no))
(forward-char))))
line-col)
-Dino Chiesa
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug#5911: flymake.el - enhancement request - flymake-goto-next-error should go to the column, if possible,
D Chiesa <=