-
-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify and improve counsel processes #1483
Conversation
57b04a0
to
646e535
Compare
counsel.el
Outdated
|
||
(defun counsel-set-async-exit-code (cmd number str) | ||
"For CMD, associate NUMBER exit code with STR." | ||
"Associate NUMBER exit code with STR for CMD." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here was to phrase the doc in a way that avoids checkdoc
warning - args out of sequence.
Ah, didn't realise As regards adding a Pros:
Cons:
|
Yet another option which avoids both messing with the WDYT? Note that, even with this approach, the question of whether to give |
counsel.el
Outdated
@@ -132,113 +132,100 @@ descriptions.") | |||
(defvar counsel-async-ignore-re nil | |||
"Regexp matching candidates to ignore in `counsel--async-filter'.") | |||
|
|||
(defun counsel--async-command (cmd &optional process-sentinel process-filter) | |||
(defun counsel-delete-process (&optional name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this function back to the original place, so that it's easy to see what changed in the diff. Moving functions around is fine, but only if their content doesn't change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem. Should I also move the function to before its first call site in a separate commit, or just leave it put?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you prefer. There won't be a compiler warning if you leave it put. But it might also be nice to group the API part of counsel (to which counsel-delete-process
belongs) separately from the adaptations part (e.g. counsel-ag
). Looking at it now, this is the case already, so it's fine not to move it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll see if I find anything which can be reordered after I refactor the other points.
counsel.el
Outdated
|
||
(defcustom counsel-async-filter-update-time 500000 | ||
"The amount of time in microseconds to wait until updating | ||
`counsel--async-filter'." | ||
:type 'integer | ||
:group 'ivy) | ||
|
||
(autoload 'encode-time-value "time-date") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer a require
instead of autoload, since the likelihood of using counsel
without calling counsel--async-filter
is low.
Another issue is that encode-time-value
is obsolete as of 25.1. A quick look at the doc doesn't suggest an alternative, strange.
Since your commit says that this change is relevant to Emacs < 24.3.
, maybe it makes sense to put Emacs >= 24.3
as the minimal requirement for Ivy. If I recall correctly, 24.3 is the most common one, 24.1 and 24.2 are rare.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer a
require
instead of autoload, since the likelihood of usingcounsel
without callingcounsel--async-filter
is low.
OK, but... (see below)
Another issue is that
encode-time-value
is obsolete as of 25.1. A quick look at the doc doesn't suggest an alternative, strange.
Another issue is that
encode-time-value
is obsolete as of 25.1. A quick look at the doc doesn't suggest an alternative, strange.
Good catch.
Since your commit says that this change is relevant to
Emacs < 24.3.
, maybe it makes sense to putEmacs >= 24.3
as the minimal requirement for Ivy. If I recall correctly, 24.3 is the most common one, 24.1 and 24.2 are rare.
I'm not against raising the minimum required Emacs version, but (a) it is not necessary for this particular case; and (b) perhaps it should be discussed in a dedicated issue.
I only used encode-time-value
because I thought it was slightly less hacky than writing (list 0 0 counsel-async-filter-update-time)
. What changed in Emacs 24.3 is a fourth picoseconds element was added to time values, so the only thing needed for backward compatibility is dropping the fourth time value element from (list 0 0 counsel-async-filter-update-time 0)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a less hacky way of doing (list 0 0 counsel-async-filter-update-time)
is (seconds-to-time (* 1e-06 counsel-async-filter-update-time))
.
Honestly, I think it was sub-optimal to choose microseconds as a unit in the first place, but oh well.
@@ -1079,7 +1060,7 @@ INITIAL-INPUT can be given as the initial minibuffer input." | |||
(defvar counsel-dired-listing-switches "-alh" | |||
"Switches passed to `ls' for `counsel-cmd-to-dired'.") | |||
|
|||
(defun counsel-cmd-to-dired (full-cmd &optional process-filter) | |||
(defun counsel-cmd-to-dired (full-cmd &optional filter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to split off the straightforward changes like process-status
from the other changes, much easier to review smaller pieces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK.
counsel.el (counsel--async-exit-code-plist) (counsel-async-ignore-re): Fix docstring. (counsel-locate-action-extern): Reword docstring and reindent. (counsel-locate): Simplify default action. ivy.el (ivy-magic-slash-non-match-action): Revert erroneous function-quote. Re #1483
Let's go with that. |
(with-current-buffer (process-buffer process) | ||
(goto-char (point-min)) | ||
(setq size (- (buffer-size) (forward-line (buffer-size)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks a bit like a hack, but it's actually a fast way to count the lines in a buffer. Look at the code of count-lines
- it's a bunch of Elisp code with regexes, loops, narrowing etc - looks expensive to me. I suggest to keep the code, maybe extract it to counsel-count-lines
so that it looks less hacky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's actually a fast way to count the lines in a buffer.
I know, I recognised the algorithm from the source of count-lines
. :)
Look at the code of
count-lines
- it's a bunch of Elisp code with regexes, loops, narrowing etc - looks expensive to me.
Actually, the only overhead involved in calling count-lines
is due to save-excursion
, save-restriction
and narrow-to-region
. The complicated loops and regexps only take effect when selective-display
is enabled buffer-locally, which is never the case for counsel
process buffers.
I suggest to keep the code, maybe extract it to
counsel-count-lines
so that it looks less hacky.
In descending order of personal preference:
- Call
count-lines
directly. - Add
counsel-count-lines
. - Add a descriptive comment to the current filter code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, by far the fastest (and hackiest) way to count lines is the following: https://emacs.stackexchange.com/a/3822/15748.
But it comes with too many caveats to be reliably useful.
Let me know if the PR rework is too much work, I can slice it up into smaller commits myself in that case. |
100% agreed. I'm sorry both for the slight delay in getting back to this and the initial megadump. If you don't mind waiting another day I'll try to have a cleaner set of commits with the discussed refactor ready by tomorrow. Either way, thanks for the quick feedback! |
Thanks, it's no trouble at all, and no urgency either. I'm just trying to avoid the situation of a promising PR going stale because the maintainer is asking the contributor to jump through too many hoops :) |
Don't worry, you're still shy of the number of hoops I throw myself through anyway. :) |
Do you have any thoughts on whether to add |
f8b7f38
to
b4cd5cb
Compare
(counsel--async-sentinel, counsel-cmd-to-dired) (counsel--gg-sentinel, counsel--gg-count): Inspect process-status and process-exit-status instead of user-facing description.
The fourth element in (SEC-HIGH SEC-LOW MICROSEC PICOSEC) was only added in 24.3.
(counsel--gg-count, counsel-linux-app-action-open-desktop): Simplify logic.
(counsel-linux-app-action-default, counsel-linux-app-action-file): Make asynchronous.
(counsel-delete-process): Take optional process name argument. (counsel--async-command): Use it, adding similar optional process name argument. Return process object. Simplify. (counsel--gg-candidates, counsel--gg-count): Reuse counsel--async-command. (counsel--gg-count-sentinel): New defun extracting lambda sentinel from counsel--gg-count. (counsel--gg-count): Use it.
@abo-abo I've split the PR into more atomic commits (and found a couple of bugs in the process :). The simplification of Please also go through my replies to your inline and sometimes hidden review comments, in case you still don't agree with one of my proposed approaches. Thanks. |
Thanks. |
Thanks!
Same here, but that seems very strange to me...
Why build a string out of the entire buffer's contents only to pass it to |
OK, my impression was that (condition-case nil
(+ (read (current-buffer)))
(error 0)) |
If you want to save some typing, you can also write (or (ignore-errors (+ (read (current-buffer))))
0) but I don't think it's worth the trouble. |
I just realized that in this case all |
Yeah, exactly. |
(counsel-linux-app-action-default, counsel-linux-app-action-file): Make asynchronous. Re: abo-abo#1483
Summary
(
counsel--async-filter
): Simplify. Fix time comparison for Emacs < 24.3.(
counsel-delete-process
): Take optional process name argument.(
counsel--async-command
): Allow specifying process name, and default sentinel and filter functions via new:default
argument value.(
counsel--async-sentinel
,counsel-cmd-to-dired
,counsel--gg-sentinel
): Simplify. Inspectprocess-status
andprocess-exit-status
instead of user-facing description.(
counsel--gg-candidates
,counsel--gg-count
): Reusecounsel--async-command
.These should all be backward compatible, but extend the APIs of
counsel-delete-process
andcounsel--async-command
. Please see each commit individually for details.Discussion
counsel--async-command
could have taken mandatorysentinel
andfilter
arguments to allow the distinction betweennil
meaninginternal-default-process-{sentinel,filter}
andcounsel--async-{sentinel,filter}
, respectively, but it has already been documented in the manual as requiring only a single argument.internal-default-process-{sentinel,filter}
were only added in Emacs 24.4 and are non-trivial to backport, hence the new:default
argument tocounsel--async-command
.counsel-delete-process
andcounsel--async-command
than extend their argument lists?