rubocop-0.6.0/ 0000755 0001752 0001753 00000000000 14105036074 011617 5 ustar elpa elpa rubocop-0.6.0/rubocop.el 0000644 0001752 0001753 00000021455 14105036074 013621 0 ustar elpa elpa ;;; rubocop.el --- An Emacs interface for RuboCop -*- lexical-binding: t -*-
;; Copyright © 2011-2021 Bozhidar Batsov
;; Author: Bozhidar Batsov
;; URL: https://github.com/bbatsov/rubocop-emacs
;; Version: 0.6.0
;; Keywords: project, convenience
;; Package-Requires: ((emacs "24"))
;; This file is NOT part of GNU Emacs.
;;; License:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; This library allows the user to easily invoke RuboCop to get feedback
;; about stylistic issues in Ruby code. It also gives access to RuboCop
;; auto-correction functionality.
;;
;;; Code:
(require 'tramp)
(defgroup rubocop nil
"An Emacs interface for RuboCop."
:group 'tools
:group 'convenience
:prefix "rubocop-"
:link '(url-link :tag "GitHub" "https://github.com/bbatsov/rubocop-emacs"))
(defcustom rubocop-project-root-files
'(".projectile" ".git" ".hg" ".bzr" "_darcs" "Gemfile")
"A list of files considered to mark the root of a project."
:type '(repeat string))
(defcustom rubocop-check-command
"rubocop --format emacs"
"The command used to run RuboCop checks."
:type 'string)
(defcustom rubocop-autocorrect-command
"rubocop -a --format emacs"
"The command used to run RuboCop's autocorrection."
:type 'string)
(defcustom rubocop-format-command
"rubocop -x --format emacs"
"The command used to run RuboCop's code formatting.
It's basically auto-correction limited to layout cops."
:type 'string)
(defcustom rubocop-extensions
'()
"A list of extensions to be loaded by RuboCop."
:type '(repeat string))
(defcustom rubocop-keymap-prefix (kbd "C-c C-r")
"RuboCop keymap prefix."
:group 'rubocop
:type 'string)
(defcustom rubocop-autocorrect-on-save nil
"Runs `rubocop-autocorrect-current-file' automatically on save."
:group 'rubocop
:type 'boolean)
(defcustom rubocop-prefer-system-executable nil
"Runs rubocop with the system executable even if inside a bundled project."
:group 'rubocop
:type 'boolean)
(defun rubocop-local-file-name (file-name)
"Retrieve local filename if FILE-NAME is opened via TRAMP."
(cond ((tramp-tramp-file-p file-name)
(tramp-file-name-localname (tramp-dissect-file-name file-name)))
(t
file-name)))
(defun rubocop-project-root (&optional no-error)
"Retrieve the root directory of a project if available.
When NO-ERROR is non-nil returns nil instead of raise an error."
(or
(car
(mapcar #'expand-file-name
(delq nil
(mapcar
(lambda (f) (locate-dominating-file default-directory f))
rubocop-project-root-files))))
(if no-error
nil
(error "You're not into a project"))))
(defun rubocop-buffer-name (file-or-dir)
"Generate a name for the RuboCop buffer from FILE-OR-DIR."
(concat "*RuboCop " file-or-dir "*"))
(defun rubocop-build-requires ()
"Build RuboCop requires from `rubocop-extensions'."
(if rubocop-extensions
(concat
" "
(mapconcat
(lambda (ext)
(format "--require %s" ext))
rubocop-extensions
" ")
" ")
""))
(defun rubocop-build-command (command path)
"Build the full command to be run based on COMMAND and PATH.
The command will be prefixed with `bundle exec` if RuboCop is bundled."
(concat
(if (and (not rubocop-prefer-system-executable) (rubocop-bundled-p)) "bundle exec " "")
command
(rubocop-build-requires)
" "
path))
(defun rubocop--dir-command (command &optional directory)
"Run COMMAND on DIRECTORY (if present).
Alternatively prompt user for directory."
(rubocop-ensure-installed)
(let ((directory
(or directory
(read-directory-name "Select directory: "))))
;; make sure we run RuboCop from a project's root if the command is executed within a project
(let ((default-directory (or (rubocop-project-root 'no-error) default-directory)))
(compilation-start
(rubocop-build-command command (rubocop-local-file-name directory))
'compilation-mode
(lambda (arg) (message arg) (rubocop-buffer-name directory))))))
;;;###autoload
(defun rubocop-check-project ()
"Run check on current project."
(interactive)
(rubocop-check-directory (rubocop-project-root)))
;;;###autoload
(defun rubocop-autocorrect-project ()
"Run autocorrect on current project."
(interactive)
(rubocop-autocorrect-directory (rubocop-project-root)))
;;;###autoload
(defun rubocop-format-project ()
"Run format on current project."
(interactive)
(rubocop-format-directory (rubocop-project-root)))
;;;###autoload
(defun rubocop-check-directory (&optional directory)
"Run check on DIRECTORY if present.
Alternatively prompt user for directory."
(interactive)
(rubocop--dir-command rubocop-check-command directory))
;;;###autoload
(defun rubocop-autocorrect-directory (&optional directory)
"Run autocorrect on DIRECTORY if present.
Alternatively prompt user for directory."
(interactive)
(rubocop--dir-command rubocop-autocorrect-command directory))
(defun rubocop-format-directory (&optional directory)
"Run format on DIRECTORY if present.
Alternatively prompt user for directory."
(interactive)
(rubocop--dir-command rubocop-format-command directory))
(defun rubocop--file-command (command)
"Run COMMAND on currently visited file."
(rubocop-ensure-installed)
(let ((file-name (buffer-file-name (current-buffer))))
(if file-name
;; make sure we run RuboCop from a project's root if the command is executed within a project
(let ((default-directory (or (rubocop-project-root 'no-error) default-directory)))
(compilation-start
(rubocop-build-command command (rubocop-local-file-name file-name))
'compilation-mode
(lambda (_arg) (rubocop-buffer-name file-name))))
(error "Buffer is not visiting a file"))))
;;;###autoload
(defun rubocop-check-current-file ()
"Run check on current file."
(interactive)
(rubocop--file-command rubocop-check-command))
;;;###autoload
(defun rubocop-autocorrect-current-file ()
"Run autocorrect on current file."
(interactive)
(rubocop--file-command rubocop-autocorrect-command))
(defun rubocop-autocorrect-current-file-silent ()
"This command is used by the minor mode to auto-correct on save.
See also `rubocop-autocorrect-on-save'."
(when rubocop-autocorrect-on-save
(save-window-excursion (rubocop-autocorrect-current-file))))
;;;###autoload
(defun rubocop-format-current-file ()
"Run format on current file."
(interactive)
(rubocop--file-command rubocop-format-command))
(defun rubocop-bundled-p ()
"Check if RuboCop has been bundled."
(let ((gemfile-lock (expand-file-name "Gemfile.lock" (rubocop-project-root))))
(when (file-exists-p gemfile-lock)
(with-temp-buffer
(insert-file-contents gemfile-lock)
(re-search-forward "rubocop" nil t)))))
(defun rubocop-ensure-installed ()
"Check if RuboCop is installed."
(unless (or (executable-find "rubocop") (rubocop-bundled-p))
(error "RuboCop is not installed")))
;;; Minor mode
(defvar rubocop-mode-map
(let ((map (make-sparse-keymap)))
(let ((prefix-map (make-sparse-keymap)))
(define-key prefix-map (kbd "p") #'rubocop-check-project)
(define-key prefix-map (kbd "d") #'rubocop-check-directory)
(define-key prefix-map (kbd "f") #'rubocop-check-current-file)
(define-key prefix-map (kbd "P") #'rubocop-autocorrect-project)
(define-key prefix-map (kbd "D") #'rubocop-autocorrect-directory)
(define-key prefix-map (kbd "F") #'rubocop-autocorrect-current-file)
(define-key prefix-map (kbd "X") #'rubocop-format-project)
(define-key prefix-map (kbd "y") #'rubocop-format-directory)
(define-key prefix-map (kbd "x") #'rubocop-format-current-file)
(define-key map rubocop-keymap-prefix prefix-map))
map)
"Keymap for RuboCop mode.")
;;;###autoload
(define-minor-mode rubocop-mode
"Minor mode to interface with RuboCop."
:lighter " RuboCop"
:keymap rubocop-mode-map
:group 'rubocop
(cond
(rubocop-mode (add-hook 'before-save-hook 'rubocop-autocorrect-current-file-silent nil t))
(t (remove-hook 'before-save-hook 'rubocop-autocorrect-current-file-silent t))))
(provide 'rubocop)
;;; rubocop.el ends here
rubocop-0.6.0/README.md 0000644 0001752 0001753 00000007561 14105036074 013107 0 ustar elpa elpa # RuboCop.el
## Synopsis
A simple Emacs interface for [RuboCop](https://github.com/rubocop-hq/rubocop).
## Installation
Please, note that the current version of `RuboCop.el` requires `RuboCop` 0.9.0 or later.
### Manual
Just drop `rubocop.el` somewhere in your `load-path`. I
favour the folder `~/.emacs.d/vendor`:
```lisp
(add-to-list 'load-path "~/.emacs.d/vendor")
(require 'rubocop)
```
### MELPA
If you're an Emacs 24 user or you have a recent version of package.el
you can install rubocop.el from the [MELPA](http://melpa.org/) and
[MELPA Stable](http://stable.melpa.org/) repositories.
## Usage
Command | Description | RuboCop mode binding
------------------------------------------------|---------------------------------------------------------|--------------------
M-x rubocop-check-project | Runs RuboCop on the entire project | `C-c C-r p`
M-x rubocop-check-directory | Prompts from a directory on which to run RuboCop | `C-c C-r d`
M-x rubocop-check-current-file | Runs RuboCop on the currently visited file | `C-c C-r f`
M-x rubocop-autocorrect-project | Runs auto-correct on the entire project | `C-c C-r P`
M-x rubocop-autocorrect-directory | Prompts for a directory on which to run auto-correct | `C-c C-r D`
M-x rubocop-autocorrect-current-file | Runs auto-correct on the currently visited file. | `C-c C-r F`
M-x rubocop-format-project | Runs format on the entire project | `C-c C-r X`
M-x rubocop-format-directory | Prompts for a directory on which to run format | `C-c C-r y`
M-x rubocop-format-current-file | Runs format on the currently visited file. | `C-c C-r x`
If you use them often you might want to enable `rubocop-mode` which will added some keybindings for them:
```lisp
(add-hook 'ruby-mode-hook #'rubocop-mode)
```
By default `rubocop-mode` uses the prefix `C-c C-r` for its commands, but you can change this if you wish:
``` emacs-lisp
(setq rubocop-keymap-prefix (kbd "C-c C-x"))
```
## Configuration
There are a couple of configuration variables that you can use to adjust RuboCop.el's behavior.
The variable `rubocop-autocorrect-on-save` controls whether to auto-correct automatically files on save when
`rubocop-mode` is active. It's disabled by default, but you can easily change this:
``` emacs-lisp
(setq rubocop-autocorrect-on-save t)
```
You can change the shell command used by `rubocop-check-*` commands via `rubocop-check-command`:
``` emacs-lisp
;; let's run only lint cops
(setq rubocop-check-command "rubocop --lint --format emacs")
```
You can change the shell command used by `rubocop-autocorrect-*` commands via `rubocop-autocorrect-command`:
``` emacs-lisp
;; let's run all auto-corrections possible (by default it's only the safe ones)
(setq rubocop-autocorrect-command "rubocop -A --format emacs")
```
You can change the shell command used by `rubocop-format-*` commands via `rubocop-format-command`.
## Alternatives
Flycheck and Flymake provide more sophisticated integration with various lint tools, including RuboCop.
## Known issues
Check out the project's
[issue list](https://github.com/rubocop-hq/rubocop-emacs/issues?sort=created&direction=desc&state=open)
a list of unresolved issues. By the way - feel free to fix any of them
and send me a pull request. :-)
## Contributors
Here's a [list](https://github.com/rubocop-hq/rubocop-emacs/contributors) of all the people who have contributed to the
development of RuboCop.el.
## Bugs & Improvements
Bug reports and suggestions for improvements are always
welcome. GitHub pull requests are even better! :-)
Cheers,
[Bozhidar](http://twitter.com/bbatsov)
rubocop-0.6.0/rubocop-pkg.el 0000644 0001752 0001753 00000000467 14105036074 014400 0 ustar elpa elpa ;; Generated package description from rubocop.el -*- no-byte-compile: t -*-
(define-package "rubocop" "0.6.0" "An Emacs interface for RuboCop" '((emacs "24")) :keywords '("project" "convenience") :authors '(("Bozhidar Batsov")) :maintainer '("Bozhidar Batsov") :url "https://github.com/rubocop/rubocop-emacs")