Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
counsel-git-grep fails if there are unreadable directories #1502
and then invoke counsel-git-grep (
Sorry about that.
The number one reason in the csh considered harmful paper suggesting not to use csh, at least as a programming language, is the difficulty of throwing away errors from programs but not the desired output.
For my project's git repo:
I like the idea of being able to configure
@icarus-sparry I assumed that the intended metric here was 'number of lines' as documented in the code, so was just pointing out the inconsistency, in case using something other than
Going back to the problem I saw, I don't have the expertise to comment on the solutions you listed.
I tried solution 3 in
@shalin24 Addressing your points.
Units for size
I am not aware of anything that would not be a lot slower than
sh -c "du -s .git 2>/dev/null"
Yes, it will work. My concern is efficiency. With
I was essentially just brainstorming. The
Sorry, I hadn't been following the content of this issue; I think I could have spared everyone some time/writing.
I believe all of the aforementioned issues can and should be solved via
I propose either:
diff --git a/counsel.el b/counsel.el index 83cbbc9..b9e8cd5 100644 --- a/counsel.el +++ b/counsel.el @@ -1248,7 +1248,9 @@ counsel--git-grep-count-func-default "Default defun to calculate `counsel--git-grep-count'." (if (eq system-type 'windows-nt) 0 - (read (shell-command-to-string "du -s .git 2>/dev/null")))) + (read (with-output-to-string + (call-process "du" nil (list standard-output nil) nil + "-s" ".git"))))) (defvar counsel--git-grep-count-func #'counsel--git-grep-count-func-default "Defun to calculate `counsel--git-grep-count' for `counsel-git-grep'.")
in which case the size of the unreadable parent directory itself is returned in this example (8 KiB on my machine), or:
diff --git a/counsel.el b/counsel.el index 83cbbc9..c9e9830 100644 --- a/counsel.el +++ b/counsel.el @@ -1248,7 +1248,12 @@ counsel--git-grep-count-func-default "Default defun to calculate `counsel--git-grep-count'." (if (eq system-type 'windows-nt) 0 - (read (shell-command-to-string "du -s .git 2>/dev/null")))) + (with-temp-buffer + (let ((status (call-process "du" nil '(t nil) nil "-s" ".git"))) + (if (eq status 0) + (read (buffer-string)) + ;; Handle error + ))))) (defvar counsel--git-grep-count-func #'counsel--git-grep-count-func-default "Defun to calculate `counsel--git-grep-count' for `counsel-git-grep'.")
in order to handle the error differently.
This is negligible to me, since these instructions are tied to a single key press - they're not some code that gets called in a loop. An overhead of
This is a lot less clear than:
Not everyone is familiar with Elisp, but most are familiar with a shell. So it's a huge advantage to be able to see transparently that Emacs does the same thing as the shell. On numerous bugs I've told users to simply copy-paste the shell command from code and run it to examine the output, it's very useful.
Now if someone cares a lot about overhead, it could be possible to make a compile-time macro that would parse the
This issue isn't about shell overhead; it's about dealing with incompatibilities between and nuisances of shells; see #1502 (comment).
Indeed, the calling convention of
If the only blocker here is code readability, just add a convenience wrapper. Here's a toy example, off the top of my head:
(defun counsel--process-output (&rest command) "Call `process-file' on COMMAND, returnings its stdout." (with-output-to-string (apply #'process-file (car command) nil (list standard-output nil) nil (cdr command)))) ;; Usage (read (counsel--process-output "du" "-s" ".git"))
One can obviously take this idea to town, e.g. by adding another command which also returns the error code returned, for further error handling.
In a programming environment like Emacs, which already provides a system interface, the customisable shell should be reserved, where possible, for users; not programmers of libraries written in ultra-high-level languages like Elisp.
As a mere interested user I obviously can't speak from authority, but I see Ivy/Counsel as libraries which provide many interactive conveniences for the average Emacs user. Providing an over-simplified source, at the expense of a restriction on the shell users are able to use, is not one of said conveniences. It is up to convenience libraries to bite the bullet, where necessary, in the name of increased usefulness and reduced restriction to the user.
As I've said, it is possible to make calling processes directly more readable. Given the incompatibilities between different shells, I would argue calling processes directly is more transparent than any shell invocation under the sun. When invoking the shell, I can never be entirely confident that all the arguments and shell redirections are escaped and quoted properly to be as cross-platform as I'd like them to be. Calling processes directly gives me more confidence and reduces mental strain.
I don't find telling someone to run "du -s .git" any more difficult than copy-pasting a shell command from an Elisp program, but that's just me.
To summarise my points:
This is just my $0.02; if you disagree, you disagree. Either way, thanks for all your work.
tcsh throws more errors for the latest
I defined my own function that uses the latter command from above, and set
Still, I am wondering if and when this will be updated/fixed in a different way?
I think consensus has been reached, since this issue was originally reported, that the ideal solution for this and several other issues would be to move away from the shell to direct process invocation. I have been interested in doing this for a while now, but have lacked and will continue to lack the time to do it wholesale. In the meantime, @abo-abo has recently started incrementally refactoring specific features to avoid the shell. This might inspire others (and me) to tackle one shell issue at a time, rather than incubating a major overhaul which never comes. Either way, sorry about the delay.