Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@

### Bugs fixed

- [#2140](https://github.com/bbatsov/projectile/pull/2140): `projectile-verbose` now covers five more messages Projectile emitted without being asked: caching a file the `find-file` hook picked up, a search path entry that doesn't exist, an indexing command that exited non-zero but produced usable output (both the sync and async runners), and a session file from an older format version. Commands you invoke still report what they did whatever the option is set to, and the two that are also commands (`projectile-cache-current-file`, `projectile-discover-projects-in-directory`) still speak when invoked directly.
- [#2139](https://github.com/bbatsov/projectile/pull/2139): The file-notification cache updates now honor the VCS's ignore rules too, so a watched project no longer gains files a re-index would never have listed - the last place `.gitignore` was going unread, after [#2126](https://github.com/bbatsov/projectile/pull/2126) fixed it for files opened by hand. One `git check-ignore` covers a whole batch of events, since a batch can be an entire directory moved into the project.
- [#1927](https://github.com/bbatsov/projectile/issues/1927): A known projects file Projectile can't read is now moved aside with a `.corrupt` suffix and reported, instead of being read as an empty list - which made it look like another Emacs had removed every project, so the merge dropped the session's projects too and overwrote the file. Projectile also strips text properties when saving, since a propertized string whose properties don't read back is how the file gets corrupted in the first place.

Expand Down
7 changes: 7 additions & 0 deletions doc/modules/ROOT/pages/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,13 @@ suppress them:
(setq projectile-verbose nil)
----

What this covers is the things Projectile says *without being asked* - caching a
file you have just opened, a background index that had something to report, a
session file it had to skip, a search path entry that no longer exists, a
project whose watches it gave up on. Commands you invoke still report what they
did either way, so turning this off makes Projectile quieter rather than mute:
`projectile-invalidate-cache` still confirms that it ran.

=== Menu bar

Projectile adds a menu to the Emacs menu bar by default. To disable it:
Expand Down
30 changes: 21 additions & 9 deletions projectile.el
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,13 @@ is set to `alien'."
:package-version '(projectile . "3.1.0"))

(defcustom projectile-verbose t
"Echo messages that are not errors."
"Whether to echo the messages Projectile emits without being asked.

This covers what Projectile says as a side effect of something else -
caching a file you just opened, a background index that had something to
report, a session file it had to skip. Commands you invoke still say
what they did whatever this is set to: turning it off makes Projectile
quieter, not mute."
:group 'projectile
:type 'boolean
:package-version '(projectile . "0.12.0"))
Expand Down Expand Up @@ -2348,9 +2354,10 @@ PROJECT-ROOT defaults to the current project."
;; UI immediately after the new file was created.
(when (projectile-persistent-cache-p)
(projectile--schedule-cache-flush current-project)))
(message "File %s added to project %s cache."
(propertize current-file 'face 'font-lock-keyword-face)
(propertize current-project 'face 'font-lock-keyword-face)))))))
(when (or projectile-verbose (called-interactively-p 'interactive))
(message "File %s added to project %s cache."
(propertize current-file 'face 'font-lock-keyword-face)
(propertize current-project 'face 'font-lock-keyword-face))))))))

;; cache opened files automatically to reduce the need for cache invalidation
(defun projectile-cache-files-find-file-hook (&optional project-root)
Expand Down Expand Up @@ -2645,7 +2652,8 @@ discover projects there."
(let ((dir (projectile--known-project-root (projectile-project-root directory))))
(unless (member dir projectile-known-projects)
(projectile-add-known-project dir)))))
(message "Project search path directory %s doesn't exist" directory)))
(when (or projectile-verbose (called-interactively-p 'interactive))
(message "Project search path directory %s doesn't exist" directory))))

(defvar projectile--search-path-discovered nil
"Non-nil once `projectile-project-search-path' has been auto-discovered.
Expand Down Expand Up @@ -3734,7 +3742,7 @@ Only text sent to standard output is taken into account."
;; Non-zero exit but we still got a listing: trust it. Only
;; mention it (quietly) when there was stderr worth seeing.
(files
(when had-stderr
(when (and had-stderr projectile-verbose)
(message "Projectile: `%s' exited with code %d but produced output; using it (see *projectile-files-errors*)"
full-command exit-code)))
;; Non-zero exit and nothing on stdout: a real failure.
Expand Down Expand Up @@ -16395,9 +16403,13 @@ with a message, so the user learns why nothing was restored."
projectile-session--format-version)
data))
((and (consp data) (plist-member data :projectile-session-version))
(message "Ignoring session file %s: format version %s (expected %s)"
file (plist-get data :projectile-session-version)
projectile-session--format-version)
;; `projectile-session-restore-all' can walk a directory full of these
;; at startup, so this is exactly the kind of thing that shouldn't
;; announce itself once per file.
(when projectile-verbose
(message "Ignoring session file %s: format version %s (expected %s)"
file (plist-get data :projectile-session-version)
projectile-session--format-version))
nil))))

(defun projectile-session--read (root)
Expand Down
98 changes: 98 additions & 0 deletions test/projectile-core-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,102 @@
(let ((projectile-sort-order 'no-such-order))
(expect (projectile-sort-files '("b" "a")) :to-equal '("b" "a")))))

(describe "projectile-verbose"
;; The line it draws: Projectile stays quiet about what it does off its
;; own bat, and still answers for what you asked it to do.

(describe "caching the file you just opened"
(it "says nothing when the find-file hook did it"
(projectile-test-with-project (("main.el" . ";; x"))
(let ((projectile-verbose nil)
(projectile-enable-caching t)
(root (projectile-project-root)))
(puthash root '("other.el") projectile-projects-cache)
(spy-on 'message)
(with-temp-buffer
(setq buffer-file-name (expand-file-name "main.el" root))
(projectile-cache-current-file root))
;; it still cached the file...
(expect (gethash root projectile-projects-cache) :to-contain "main.el")
;; ...without announcing it
(expect 'message :not :to-have-been-called))))

(it "still answers when you invoke it yourself"
(projectile-test-with-project (("main.el" . ";; x"))
(let ((projectile-verbose nil)
(projectile-enable-caching t)
(root (projectile-project-root)))
(puthash root '("other.el") projectile-projects-cache)
(spy-on 'message)
(spy-on 'called-interactively-p :and-return-value t)
(with-temp-buffer
(setq buffer-file-name (expand-file-name "main.el" root))
(projectile-cache-current-file root))
(expect 'message :to-have-been-called)))))

(describe "a search path entry that doesn't exist"
(it "says nothing during the automatic scan"
(let ((projectile-verbose nil))
(spy-on 'message)
(projectile-discover-projects-in-directory "/no/such/directory/")
(expect 'message :not :to-have-been-called)))

(it "still says so when you run the command"
(let ((projectile-verbose nil))
(spy-on 'message)
(spy-on 'called-interactively-p :and-return-value t)
(projectile-discover-projects-in-directory "/no/such/directory/")
(expect 'message :to-have-been-called))))

(describe "an indexing command that exits non-zero with output"
(it "keeps the note to itself, but still uses the output"
(projectile-test-with-sandbox
(projectile-test-with-files ("project/" "project/.projectile")
(let ((default-directory (projectile-test-project-root))
(projectile-verbose nil))
(spy-on 'message)
(expect (projectile-files-via-ext-command
default-directory "printf 'a.el\\0'; echo boom >&2; exit 1")
:to-equal '("a.el"))
(expect 'message :not :to-have-been-called)))))

(it "mentions it when asked to be verbose"
(projectile-test-with-sandbox
(projectile-test-with-files ("project/" "project/.projectile")
(let ((default-directory (projectile-test-project-root))
(projectile-verbose t))
(spy-on 'message)
(projectile-files-via-ext-command
default-directory "printf 'a.el\\0'; echo boom >&2; exit 1")
(expect 'message :to-have-been-called))))))

(describe "a session file from another format version"
(it "is skipped silently, since restore-all can meet a directory of them"
(projectile-test-with-temp-files ((file ".eld"))
(let ((projectile-verbose nil))
(projectile-serialize '(:projectile-session-version 0 :tabs nil) file)
(spy-on 'message)
(expect (projectile-session--read-file file) :to-be nil)
(expect 'message :not :to-have-been-called))))

(it "says which file it skipped when asked to be verbose"
(projectile-test-with-temp-files ((file ".eld"))
(let ((projectile-verbose t))
(projectile-serialize '(:projectile-session-version 0 :tabs nil) file)
(spy-on 'message)
(expect (projectile-session--read-file file) :to-be nil)
(expect 'message :to-have-been-called)))))

(describe "what it deliberately does not cover"
(it "leaves a command's own answer alone"
;; `projectile-invalidate-cache' exists to be invoked; saying nothing
;; would leave you wondering whether it ran.
(projectile-test-with-project (("main.el" . ";; x"))
(let ((projectile-verbose t)
(root (projectile-project-root)))
(puthash root '("main.el") projectile-projects-cache)
(spy-on 'message)
(projectile-invalidate-cache nil)
(expect 'message :to-have-been-called))))))

;;; projectile-core-test.el ends here
Loading