Abstract
First, I tried to implement own jshint invocation and handling tool. It was pretty fun, but later I found flymake package designed to work with syntax checking tools.
This article is based, and describes JS-Hint mode. It can be treated as development log and tips, as well as short tutorial on how to customize flymake mode.
Flymake
Flymake allows us to define interface to check files, tools to run these checks from time to time, and regexp based tools to highlight broken parts of the files.
Invoke
The entry point of flymake is how to invoke check program:
01 (defun flymake-js-hint-init ()
02 (let* ((temp-file (flymake-init-create-temp-buffer-copy
03 'flymake-create-temp-inplace))
04 (local-file (file-relative-name
05 temp-file
06 (file-name-directory buffer-file-name))))
07 (list "jshint" (list "--verbose" local-file))))
02 (let* ((temp-file (flymake-init-create-temp-buffer-copy
03 'flymake-create-temp-inplace))
04 (local-file (file-relative-name
05 temp-file
06 (file-name-directory buffer-file-name))))
07 (list "jshint" (list "--verbose" local-file))))
This code, as well as most of the other code is taken from Example—Configuring a tool called via make.
This function makes a copy of current buffer state into temporary file with unique name, and returns line to be called by flymake. The output usually contains errors and warnings, which is parsed and corresponding lines are highlighted.
Highlight
Flymake uses special list to hold all possible highlights - flymake-err-line-patterns. Each entry in this list is a list of next format:
(REGEXP FILE-ID [LINE-ID [COLUMN-ID [ERROR-TEXT-ID]]])
where:
REGEXP - what kind of lines to match, with groups,
FILE-ID - id of group in match containing file name with error/warning,
LINE-ID - id of group in match containing line in the file with error/warning,
COLUMN-ID - id of group in match containing column in line
ERROR-TEXT-ID - id of group in match containing message to display against corresponding line.
Example for jshint:
(REGEXP INIT-FUNCTION CLEANUP-FUNCTION GETFNAME-FUNCTION)
where:
REGEXP - is used to match a file,
INIT-FUNCTION - initializes a temporary file with current buffer context and returns specialized function as list,
CLEANUP-FUNCITON - removes temporary file and does other clean up functions,
GETFNAME-FUNCTION - maps temporary file names to real ones.
(REGEXP FILE-ID [LINE-ID [COLUMN-ID [ERROR-TEXT-ID]]])
where:
REGEXP - what kind of lines to match, with groups,
FILE-ID - id of group in match containing file name with error/warning,
LINE-ID - id of group in match containing line in the file with error/warning,
COLUMN-ID - id of group in match containing column in line
ERROR-TEXT-ID - id of group in match containing message to display against corresponding line.
Example for jshint:
01 (add-to-list 'flymake-err-line-patterns
02 '("^\\(.+\\): line \\([0-9]+\\), col \\([0-9]+\\), \\(.+\\)$" 1 2 3 4))
This code adds new rule to flymake list of rules. Next time flymake find line with error corresponding to this regexp - it will highlight it.02 '("^\\(.+\\): line \\([0-9]+\\), col \\([0-9]+\\), \\(.+\\)$" 1 2 3 4))
Register for flymake
When we have required parts of running and highlighting, we can link this all together and configure flymake:
01 (add-to-list 'flymake-allowed-file-name-masks
02 '(".+\\.js$"
03 flymake-js-hint-init
04 flymake-simple-cleanup
05 flymake-get-real-file-name))
flymake-allowed-file-name-masks - is a list of rules for flymake. Each entry is of the form:02 '(".+\\.js$"
03 flymake-js-hint-init
04 flymake-simple-cleanup
05 flymake-get-real-file-name))
(REGEXP INIT-FUNCTION CLEANUP-FUNCTION GETFNAME-FUNCTION)
where:
REGEXP - is used to match a file,
INIT-FUNCTION - initializes a temporary file with current buffer context and returns specialized function as list,
CLEANUP-FUNCITON - removes temporary file and does other clean up functions,
GETFNAME-FUNCTION - maps temporary file names to real ones.
Комментариев нет:
Отправить комментарий