summaryrefslogtreecommitdiff
path: root/lisp/progmodes/ruby-mode.el
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-11-25 22:55:35 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2017-11-25 22:55:35 -0800
commitd20161b25e9cd184d841ba9e36ee5141c01fd75f (patch)
tree6026fea9d48e641bf63b23209970efd1f8024e2c /lisp/progmodes/ruby-mode.el
parente27004c5fe3c227476ea210ff5bee2efb783ae17 (diff)
parenta89f0b6f33f9eb8910a1fceda9028d76ef50b05d (diff)
downloademacs-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.el149
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)