diff --git a/README.md b/README.md index 954e442..3647d64 100644 --- a/README.md +++ b/README.md @@ -33,20 +33,22 @@ automatically when `ruby-mode` is started. These keybindings are available in any Ruby source file: -Keybinding | Description | -------------|-------------------------------------------------------------------------------| -`C-c , v` | Verify the spec file associated with the current buffer | -`C-c , a` | Run spec for entire project | -`C-c , t` | Toggle back and forth between a spec and its target | -`C-c , e` | Toggle back and forth between a method and its examples in the spec file | -`C-c , 4 t` | Find in the other window the spec or the target file | -`C-c , 4 e` | As above, but try to navigate to the example or method corresponding to point | -`C-c , r` | Re-run the last verification process | -`C-c , y` | Yank the last verification command to clipboard | -`C-c , m` | Run all specs related to the current buffer | -`C-c , c` | Run the current spec and all after it | -`C-c , s` | Verify the example or method defined at point | -`C-c , f` | Re-run just the failed examples from the last run | +| Keybinding | Description | +| -------------- | ----------------------------------------------------------------------------------------- | +| `C-c , v` | Verify the spec file associated with the current buffer | +| `C-c , a` | Run spec for entire project | +| `C-c , t` | Toggle back and forth between a spec and its target | +| `C-c , e` | Toggle back and forth between a method and its examples in the spec file | +| `C-c , 4 t` | Find in the other window the spec or the target file | +| `C-c , 4 e` | As above, but try to navigate to the example or method corresponding to point | +| `C-c , r` | Re-run the last verification process | +| `C-c , y` | Yank the last verification command to clipboard | +| `C-c , m` | Run all specs related to the current buffer | +| `C-c , c` | Run the current spec and all after it | +| `C-c , s` | Verify the example or method defined at point | +| `C-c , f` | Re-run just the failed examples from the last run | +| `C-c , g v` | Verify the spec file associated with the current buffer, filtered by one or multiple tags | +| `C-c , g a` | Run spec for entire project, filtered by one or multiple tags | ### RSpec mode @@ -61,12 +63,15 @@ Keybinding | Description | These keybindings are available in Dired buffers: -Keybinding | Description | ------------|----------------------------------------------------------------| -`C-c , v` | Run all specs in the current directory | -`C-c , s` | Run marked specs or spec at point (works with directories too) | -`C-c , a` | Run the 'spec' rake task for the project of the current file | -`C-c , r` | Re-run the last RSpec invocation | +Keybinding | Description | +-------------|--------------------------------------------------------------------------------------------------| +`C-c , v` | Run all specs in the current directory | +`C-c , s` | Run marked specs or spec at point (works with directories too) | +`C-c , a` | Run the 'spec' rake task for the project of the current file | +`C-c , r` | Re-run the last RSpec invocation | +`C-c , g v` | Run all specs in the current directory, filtered by one or multiple tags | +`C-c , g s` | Run marked specs or spec at point, filtered by one or multiple tags (works with directories too) | +`C-c , g a` | Run the 'spec' rake task for the project of the current file, filtered by one or multiple tags | See `rspec-mode.el` for further usage. diff --git a/rspec-mode.el b/rspec-mode.el index ff233b9..df523c9 100644 --- a/rspec-mode.el +++ b/rspec-mode.el @@ -101,6 +101,8 @@ (define-prefix-command 'rspec-verifiable-mode-keymap) (defvar rspec-mode-keymap) (define-prefix-command 'rspec-mode-keymap) +(defvar rspec-verifiable-tags-mode-keymap) +(define-prefix-command 'rspec-verifiable-tags-mode-keymap) (define-key rspec-verifiable-mode-keymap (kbd "v") 'rspec-verify) (define-key rspec-verifiable-mode-keymap (kbd "a") 'rspec-verify-all) @@ -115,6 +117,10 @@ (define-key rspec-verifiable-mode-keymap (kbd "s") 'rspec-verify-method) (define-key rspec-verifiable-mode-keymap (kbd "f") 'rspec-run-last-failed) +(define-key rspec-verifiable-mode-keymap (kbd "g") rspec-verifiable-tags-mode-keymap) +(define-key rspec-verifiable-tags-mode-keymap (kbd "v") 'rspec-verify-tags) +(define-key rspec-verifiable-tags-mode-keymap (kbd "a") 'rspec-verify-tags-all) + (set-keymap-parent rspec-mode-keymap rspec-verifiable-mode-keymap) (define-key rspec-mode-keymap (kbd "s") 'rspec-verify-single) @@ -122,11 +128,19 @@ (defvar rspec-dired-mode-keymap) (define-prefix-command 'rspec-dired-mode-keymap) +(defvar rspec-dired-tags-mode-keymap) +(define-prefix-command 'rspec-dired-tags-mode-keymap) + (define-key rspec-dired-mode-keymap (kbd "v") 'rspec-dired-verify) (define-key rspec-dired-mode-keymap (kbd "s") 'rspec-dired-verify-single) (define-key rspec-dired-mode-keymap (kbd "a") 'rspec-verify-all) (define-key rspec-dired-mode-keymap (kbd "r") 'rspec-rerun) +(define-key rspec-dired-mode-keymap (kbd "g") rspec-dired-tags-mode-keymap) +(define-key rspec-dired-tags-mode-keymap (kbd "v") 'rspec-dired-verify-tags) +(define-key rspec-dired-tags-mode-keymap (kbd "a") 'rspec-verify-tags-all) +(define-key rspec-dired-tags-mode-keymap (kbd "s") 'rspec-dired-verify-tags-single) + (defgroup rspec-mode nil "RSpec minor mode." :group 'languages) @@ -466,6 +480,28 @@ buffers concurrently" (rspec-run-single-file (rspec-spec-file-for (buffer-file-name)) (rspec-core-options))) +(defvar rspec-tags-history nil + "History of tags used in rspec-verify-tags-* functions.") + +(defun rspec-add-tags-to-history (tags) + "Add TAGS to rspec-tags-history and optionally save to savehist." + (dolist (tag tags) + (add-to-history 'rspec-tags-history tag)) + (when (and (featurep 'savehist) savehist-mode) + (unless (member 'rspec-tags-history savehist-additional-variables) + (add-to-list 'savehist-additional-variables 'rspec-tags-history)))) + +(defun rspec-verify-tags () + "Run the specified spec, or the spec file for the current buffer, filtered by one or multiple tags." + (interactive) + (rspec--autosave-buffer-maybe) + (let* ((tags-string (completing-read-multiple "Select tags (separated by comma): " rspec-tags-history)) + (tags-list (if (stringp tags-string) (split-string tags-string ",\\s-*") tags-string))) + (rspec-add-tags-to-history tags-list) + (rspec-run-single-file (rspec-spec-file-for (buffer-file-name)) + (concat (mapconcat #'(lambda (tag) (format " --tag %s" tag)) tags-list " ")) + (rspec-core-options)))) + (defun rspec-verify-matching () "Run the specs related to the current buffer. This is more fuzzy that a simple verify." @@ -513,21 +549,49 @@ in long-running test suites." (declare-function dired-get-marked-files "dired") (defun rspec-dired-verify () - "Run all specs in the current directory." + "Run all specs in the current directory, filtered by one or multiple tags." (interactive) (rspec-run-single-file (dired-current-directory) (rspec-core-options))) +(defun rspec-dired-verify-tags () + "Run all specs in the current directory, filtered by one or multiple tags." + (interactive) + (let* ((tags-string (completing-read-multiple "Select tags (separated by comma): " rspec-tags-history)) + (tags-list (if (stringp tags-string) (split-string tags-string ",\\s-*") tags-string))) + (rspec-add-tags-to-history tags-list) + (rspec-run-single-file (dired-current-directory) + (concat (mapconcat #'(lambda (tag) (format " --tag %s" tag)) tags-list " ") " " + (rspec-core-options))))) + (defun rspec-dired-verify-single () "Run marked specs or spec at point (works with directories too)." (interactive) (rspec-compile (dired-get-marked-files) (rspec-core-options))) +(defun rspec-dired-verify-tags-single () + "Run marked specs or spec at point, filtered by one or multiple tags (works with directories too)." + (interactive) + (let* ((tags-string (completing-read-multiple "Select tags (separated by comma): " rspec-tags-history)) + (tags-list (if (stringp tags-string) (split-string tags-string ",\\s-*") tags-string))) + (rspec-add-tags-to-history tags-list) + (rspec-compile (dired-get-marked-files) + (concat (mapconcat #'(lambda (tag) (format " --tag %s" tag)) tags-list " ") " " + (rspec-core-options))))) + (defun rspec-verify-all () "Run the `spec' rake task for the project of the current file." (interactive) (rspec-run (rspec-core-options))) +(defun rspec-verify-tags-all () + "Run the `spec' rake task for the project of the current file, filtered by one or multiple tags." + (interactive) + (let* ((tags-string (completing-read-multiple "Select tags (separated by comma): " rspec-tags-history)) + (tags-list (if (stringp tags-string) (split-string tags-string ",\\s-*") tags-string))) + (rspec-add-tags-to-history tags-list) + (rspec-run (concat (rspec-core-options) (mapconcat #'(lambda (tag) (format " --tag %s" tag)) tags-list " "))))) + (defun rspec-toggle-spec-and-target () "Switch to the spec or the target file for the current buffer. If the current buffer is visiting a spec file, switches to the