Skip to content

Commit

Permalink
Add new custom variable 'projectile-cmd-hist-ignoredups'
Browse files Browse the repository at this point in the history
Add new custom variable 'projectile-cmd-hist-ignoredups', which can be
used to tweak how duplicates are dealt with in projectile's command
history.  The custom variable is identical in behaviour to
'eshell-hist-ignoredups'.

Specifically, the existing default behavior is maintained with the
value of t, which means consecutive duplicates are ignored.  A value
of 'erase means only the last duplicate is kept, whilst a value of nil
means all duplicates are kept.
  • Loading branch information
LaurenceWarne authored and bbatsov committed Jan 23, 2024
1 parent 55e9026 commit f7e6084
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* [#1870](https://github.com/bbatsov/projectile/pull/1870): Add package command for CMake projects.
* [#1875](https://github.com/bbatsov/projectile/pull/1875): Add support for Sapling VCS.
* [#1876](https://github.com/bbatsov/projectile/pull/1876): Add support for Jujutsu VCS.
* [#1877](https://github.com/bbatsov/projectile/pull/1877): Add custom variable `projectile-cmd-hist-ignoredups`.

## 2.8.0 (2023-10-13)

Expand Down
6 changes: 6 additions & 0 deletions doc/modules/ROOT/pages/projects.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -838,3 +838,9 @@ external command or an Emacs Lisp function:
In addition caching of commands can be disabled by setting the variable
`projectile-project-enable-cmd-caching` is to `nil`. This is useful for
preset-based CMake projects.

By default, Projectile will not add consecutive duplicate commands to its
command history. To alter this behaviour you can use `projectile-cmd-hist-ignoredups`.
The default value of `t` means consecutive duplicates are ignore, a value
of `nil` means nothing is ignored, and a value of `'erase'` means only
the last duplicate is kept in the command history.
24 changes: 22 additions & 2 deletions projectile.el
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,17 @@ If the value is nil, there is no limit to the opend buffers count."
:type 'integer
:package-version '(projectile . "2.2.0"))

(defcustom projectile-cmd-hist-ignoredups t
"Controls when inputs are added to projectile's command history.
A value of t means consecutive duplicates are ignored.
A value of `erase' means only the last duplicate is kept.
A value of nil means nothing is ignored."
:type '(choice (const :tag "Don't ignore anything" nil)
(const :tag "Ignore consecutive duplicates" t)
(const :tag "Only keep last duplicate" erase))
:package-version '(projectile . "2.9.0"))

(defvar projectile-project-test-suffix nil
"Use this variable to override the current project's test-suffix property.
It takes precedence over the test-suffix for the project type when set.
Expand Down Expand Up @@ -5227,8 +5238,17 @@ The command actually run is returned."
(when command-map
(puthash default-directory command command-map)
(let ((hist (projectile--get-command-history project-root)))
(unless (string= (car-safe (ring-elements hist)) command)
(ring-insert hist command))))
(cond
((eq projectile-cmd-hist-ignoredups t)
(unless (string= (car-safe (ring-elements hist)) command)
(ring-insert hist command)))
((eq projectile-cmd-hist-ignoredups 'erase)
(let ((idx (ring-member hist command)))
(while idx
(ring-remove hist idx)
(setq idx (ring-member hist command))))
(ring-insert hist command))
(t (ring-insert hist command)))))
(when save-buffers
(save-some-buffers (not compilation-ask-about-save)
(lambda ()
Expand Down
24 changes: 21 additions & 3 deletions test/projectile-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -2138,25 +2138,43 @@ projectile-process-current-project-buffers-current to have similar behaviour"
(expect 'async-shell-command :to-have-been-called-with "cmd" nil nil))))

(describe "projectile--run-project-cmd"
(it "command history is not duplicated"

(before-each
(spy-on 'projectile-run-compilation)
(spy-on 'projectile-maybe-read-command :and-call-fake
(lambda (arg default-cmd prompt) default-cmd))
;; Stops projectile--run-project-cmd from creating a new directory for
;; the compilation dir
(spy-on 'file-directory-p :and-return-value t)
(spy-on 'file-directory-p :and-return-value t))

(it "projectile-cmd-hist-ignoredups set to t"

(let ((command-map (make-hash-table :test 'equal))
(projectile-cmd-hist-ignoredups t)
;; history is based on the project root, so we set it to a random
;; path to ensure there are no existing commands in history
(projectile-project-root "/a/random/path"))
(projectile--run-project-cmd "foo" command-map)
(projectile--run-project-cmd "foo" command-map)
(projectile--run-project-cmd "bar" command-map)
(projectile--run-project-cmd "foo" command-map)
(expect 'projectile-run-compilation :to-have-been-called-times 4)
(expect (ring-elements
(projectile--get-command-history projectile-project-root))
:to-equal '("foo" "bar" "foo"))))

(it "projectile-cmd-hist-ignoredups set to erase"
(let ((command-map (make-hash-table :test 'equal))
(projectile-cmd-hist-ignoredups 'erase)
(projectile-project-root "/a/random/path"))
(projectile--run-project-cmd "foo" command-map)
(projectile--run-project-cmd "bar" command-map)
(projectile--run-project-cmd "foo" command-map)
(projectile--run-project-cmd "foo" command-map)
(expect 'projectile-run-compilation :to-have-been-called-times 4)
(expect (ring-elements
(projectile--get-command-history projectile-project-root))
:to-equal '("bar" "foo")))))
:to-equal '("foo" "bar")))))

(describe "projectile-test-prefix"
:var ((mock-projectile-project-types
Expand Down

0 comments on commit f7e6084

Please sign in to comment.