Package: emacs;
Reported by: "D Chiesa" <dpchiesa <at> hotmail.com>
Date: Fri, 9 Apr 2010 05:56:01 UTC
Severity: wishlist
Merged with 8723
Found in version 23.2
Done: Stefan Kangas <stefankangas <at> gmail.com>
Bug is archived. No further changes may be made.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: "D Chiesa" <dpchiesa <at> hotmail.com> To: <bug-gnu-emacs <at> gnu.org> Subject: 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
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.