diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2017-11-25 22:55:35 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2017-11-25 22:55:35 -0800 |
commit | d20161b25e9cd184d841ba9e36ee5141c01fd75f (patch) | |
tree | 6026fea9d48e641bf63b23209970efd1f8024e2c /lisp/progmodes/ruby-mode.el | |
parent | e27004c5fe3c227476ea210ff5bee2efb783ae17 (diff) | |
parent | a89f0b6f33f9eb8910a1fceda9028d76ef50b05d (diff) | |
download | emacs-d20161b25e9cd184d841ba9e36ee5141c01fd75f.tar.gz |
Merge from origin/emacs-26
a89f0b6f33 maint: shorten https://lists.gnu.org/archive/html/... links
8be3aee281 Merge from Gnulib
265cee553f Work around GCC bug 80776 on Fedora 27 x86
dc7a97fb84 Tweak copy-file, rename-file doc
cfa2a944d4 Change font-lock-extend-region-multiline handling in mhtml...
a8664cc998 Minor cleanup in tramp-gvfs-handle-file-local-copy
55c5b12fa0 Add test for Bug#29423 in Tramp.
3198a1646e Avoid jumbled order in HTML rendered by shr.el
23bfc2d2db Make sure 'dired-filename' property is always put by ls-lisp
f7fdaea4c0 A better solution for bug#29347
86e6ed8521 ; * src/thread.c (acquire_global_lock): Fix thinko in last...
f300852037 Avoid a hang after C-g while sit-for on a Unix TTY
d7fc719ff1 Improve the doc string of 'list-packages'
b4f67ebb92 Improve discoverability of 'defvar' for suppressing warnings
8a2b204e64 Improve discoverability of 'read-buffer-completion-ignore-...
eea4e9194c Improve documentation of self-insert-uses-region-functions
e6e41dac87 Reflect changes in copy-file and rename-file in doc strings
0ec534070f * lisp/progmodes/cc-vars.el (c-offsets-alist): Doc fix. (...
1d0dbdff6c Reorder type predicates in ELisp manual
b081ec9dd7 Fix backward scrolling in buffers with header-line
8e40429c96 ; Fix some doc typos
ed2c542920 * lisp/bindings.el (buffer-file-coding-system): Add explic...
d82474e452 * src/fns.c (syms_of_fns) <overriding-plist-environment>: ...
292c09ff6d Fix incorrect interaction of drag/drop and double click (b...
d6fadb1d26 * lisp/menu-bar.el (menu-bar-options-save): Add display-li...
daa959efbc * lisp/menu-bar.el (menu-bar-options-save): Add global-dis...
17fc74d1b9 * lisp/follow.el (follow-mode): Restore mode line lighter....
f20c2e2f3d ; Compare process status against 127 exactly
2d203ffb7e Extract the common part of ruby-flymake-simple and ruby-fl...
09944d499a Add Rubocop Flymake backend
c65a0ae7c4 ; Fix a typo
7ab7603125 Update nt/INSTALL.W64 (Bug#28601)
11db253c08 Remove incorrect NEWS item about VC state indicator (Bug#2...
2fdc01c036 * lisp/emacs-lisp/byte-run.el (defsubst): Doc fix.
735c8b516e Make c-defun-name analyze more thoroughly a function type ...
92f0c4cd56 Avoid bogus abbreviated file names if HOME changes
8d450453fa * lisp/emacs-lisp/byte-run.el (inline): Give it a doc.
37a3b4ea40 Fix erc keep-place module with new defaults (Bug#29111)
6c312605bf Add window divider faces to NS (bug#29353)
# Conflicts:
# etc/NEWS
# lisp/ruler-mode.el
Diffstat (limited to 'lisp/progmodes/ruby-mode.el')
-rw-r--r-- | lisp/progmodes/ruby-mode.el | 149 |
1 files changed, 110 insertions, 39 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index da08bb0788e..dc1b0f8e2da 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -2254,24 +2254,38 @@ See `font-lock-syntax-table'.") (ruby-match-expression-expansion limit))))) ;;; Flymake support -(defcustom ruby-flymake-command '("ruby" "-w" "-c") - "External tool used to check Ruby source code. -This is a non empty list of strings, the checker tool possibly -followed by required arguments. Once launched it will receive -the Ruby source to be checked as its standard input." - :group 'ruby - :type '(repeat string)) - (defvar-local ruby--flymake-proc nil) -(defun ruby-flymake (report-fn &rest _args) - "Ruby backend for Flymake. Launches -`ruby-flymake-command' (which see) and passes to its standard -input the contents of the current buffer. The output of this -command is analyzed for error and warning messages." - (unless (executable-find (car ruby-flymake-command)) - (error "Cannot find a suitable checker")) - +(defun ruby-flymake-simple (report-fn &rest _args) + "`ruby -wc' backend for Flymake." + (unless (executable-find "ruby") + (error "Cannot find the ruby executable")) + + (ruby-flymake--helper + "ruby-flymake" + '("ruby" "-w" "-c") + (lambda (_proc source) + (goto-char (point-min)) + (cl-loop + while (search-forward-regexp + "^\\(?:.*.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$" + nil t) + for msg = (match-string 2) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 1))) + for type = (if (string-match "^warning" msg) + :warning + :error) + collect (flymake-make-diagnostic source + beg + end + type + msg) + into diags + finally (funcall report-fn diags))))) + +(defun ruby-flymake--helper (process-name command parser-fn) (when (process-live-p ruby--flymake-proc) (kill-process ruby--flymake-proc)) @@ -2281,40 +2295,97 @@ command is analyzed for error and warning messages." (setq ruby--flymake-proc (make-process - :name "ruby-flymake" :noquery t :connection-type 'pipe - :buffer (generate-new-buffer " *ruby-flymake*") - :command ruby-flymake-command + :name process-name :noquery t :connection-type 'pipe + :buffer (generate-new-buffer (format " *%s*" process-name)) + :command command :sentinel (lambda (proc _event) (when (eq 'exit (process-status proc)) (unwind-protect (if (with-current-buffer source (eq proc ruby--flymake-proc)) (with-current-buffer (process-buffer proc) - (goto-char (point-min)) - (cl-loop - while (search-forward-regexp - "^\\(?:.*.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$" - nil t) - for msg = (match-string 2) - for (beg . end) = (flymake-diag-region - source - (string-to-number (match-string 1))) - for type = (if (string-match "^warning" msg) - :warning - :error) - collect (flymake-make-diagnostic source - beg - end - type - msg) - into diags - finally (funcall report-fn diags))) + (funcall parser-fn proc source)) (flymake-log :debug "Canceling obsolete check %s" proc)) (kill-buffer (process-buffer proc))))))) (process-send-region ruby--flymake-proc (point-min) (point-max)) (process-send-eof ruby--flymake-proc)))) +(defcustom ruby-flymake-use-rubocop-if-available t + "Non-nil to use the Rubocop Flymake backend. +Only takes effect if Rubocop is installed." + :type 'boolean + :group 'ruby + :safe 'booleanp) + +(defcustom ruby-rubocop-config ".rubocop.yml" + "Configuration file for `ruby-flymake-rubocop'." + :type 'string + :group 'ruby + :safe 'stringp) + +(defun ruby-flymake-rubocop (report-fn &rest _args) + "Rubocop backend for Flymake." + (unless (executable-find "rubocop") + (error "Cannot find the rubocop executable")) + + (let ((command (list "rubocop" "--stdin" buffer-file-name "--format" "emacs" + "--cache" "false" ; Work around a bug in old version. + "--display-cop-names")) + config-dir) + (when buffer-file-name + (setq config-dir (locate-dominating-file buffer-file-name + ruby-rubocop-config)) + (when config-dir + (setq command (append command (list "--config" + (expand-file-name ruby-rubocop-config + config-dir))))) + + (ruby-flymake--helper + "rubocop-flymake" + command + (lambda (proc source) + ;; Finding the executable is no guarantee of + ;; rubocop working, especially in the presence + ;; of rbenv shims (which cross ruby versions). + (when (eq (process-exit-status proc) 127) + ;; Not sure what to do in this case. Maybe ideally we'd + ;; switch back to ruby-flymake-simple. + (flymake-log :warning "Rubocop returned status 127: %s" + (buffer-string))) + (goto-char (point-min)) + (cl-loop + while (search-forward-regexp + "^\\(?:.*.rb\\|-\\):\\([0-9]+\\):\\([0-9]+\\): \\(.*\\)$" + nil t) + for msg = (match-string 3) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 1)) + (string-to-number (match-string 2))) + for type = (cond + ((string-match "^[EF]: " msg) + :error) + ((string-match "^W: " msg) + :warning) + (t :note)) + collect (flymake-make-diagnostic source + beg + end + type + (substring msg 3)) + into diags + finally (funcall report-fn diags))))))) + +(defun ruby-flymake-auto (report-fn &rest args) + (apply + (if (and ruby-flymake-use-rubocop-if-available + (executable-find "rubocop")) + #'ruby-flymake-rubocop + #'ruby-flymake-simple) + report-fn + args)) + ;;;###autoload (define-derived-mode ruby-mode prog-mode "Ruby" "Major mode for editing Ruby code." @@ -2327,7 +2398,7 @@ command is analyzed for error and warning messages." (add-hook 'after-save-hook 'ruby-mode-set-encoding nil 'local) (add-hook 'electric-indent-functions 'ruby--electric-indent-p nil 'local) - (add-hook 'flymake-diagnostic-functions 'ruby-flymake nil 'local) + (add-hook 'flymake-diagnostic-functions 'ruby-flymake-auto nil 'local) (setq-local font-lock-defaults '((ruby-font-lock-keywords) nil nil)) (setq-local font-lock-keywords ruby-font-lock-keywords) |