Skip to content
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

consult-prompt UI #130

Closed
leungbk opened this issue Jan 5, 2021 · 18 comments
Closed

consult-prompt UI #130

leungbk opened this issue Jan 5, 2021 · 18 comments
Labels
feature New feature or request

Comments

@leungbk
Copy link

leungbk commented Jan 5, 2021

As discussed in the wishlist, consult-prompt would offer a list of all prompts, including eshell, comint, and possibly more. I'll try to implement this within the next week or so, but before I start, I want to clarify what the UI should be like.

Helm has separate commands for 1) selecting a prompt from all (say) comint buffers and 2) selecting a prompt from only the current comint buffer. Do we want separate commands here as well?

Consult also has [space-bar-]narrowing functionality so you can easily narrow to comints only etc.

Numerous major modes are derived from comint, so filtering by comint alone would lead to shell-mode buffers getting mixed in with inf-ruby and inferior-python buffers, which isn't always what I would want.

An alternative is to allow space-bar-filtering by major mode. If multiple major modes start with the same letter, we'd have to make a defcustom for the user to choose major mode gets that letter.

We'd additionally need something like

(defcustom consult-prompt-types
  '((eshell-mode . eshell-next-prompt)
    (shell-mode  . comint-next-prompt)
    ;; (haskell-mode . haskell-interactive-mode-prompt-next)
    )
  "Association list mapping major modes to next-prompt functions.")

to let us acquire all the prompts. The user would specify the major mode and a function to navigate to the next prompt. At each prompt, we'd extract the first line of input (not sure if there's a robust way of capturing more lines of input at a given prompt). Does this sound reasonable?

@minad
Copy link
Owner

minad commented Jan 5, 2021

Sounds good! Thank you for discussing first, this way we can hopefully avoid a chaos during the review as in #83. A few comments/questions:

  • It would be great to use this space-bar filtering/narrowing per major mode. The user should be able to configure the key as you propose. I think we should be precise here and not filter by comint but by the actual major mode, which may be derived from comint.
  • Can we support preview?
  • How do you plan to display the prompt in the selection list? Name of the major-mode, current directory, buffer name? Maybe some special info depending on the type of the prompt?

@minad minad added the feature New feature or request label Jan 5, 2021
@leungbk
Copy link
Author

leungbk commented Jan 7, 2021

It would be great to use this space-bar filtering/narrowing per major mode. The user should be able to configure the key as you propose. I think we should be precise here and not filter by comint but by the actual major mode, which may be derived from comint.

OK.

Can we support preview?

OK.

How do you plan to display the prompt in the selection list? Name of the major-mode, current directory, buffer name? Maybe some special info depending on the type of the prompt?

I was thinking that the name of the major mode along with the buffer name and the first line of the prompt contents would be enough, and that the current directory would be added as some metadata for Marginalia or something (I don't yet understand the internals of that package).

What do you mean by "the type of the prompt"?

Here's helm-eshell-prompts-all in action, used to navigate between all prompts across all eshell buffers. I envisioned consult-prompts to work in a similar manner, but that it would include comint-derived modes as well, classified by major mode as we discussed above. It's possible we're not on the same page as to what we want consult-prompt to do.
output-2021-01-06-21:56:45

@minad
Copy link
Owner

minad commented Jan 7, 2021

What you describe sounds good. By prompt contents you mean the last output or the last line? For me prompt usually just means "dir > " or something else depending on the shell/mode. And this wouldn't been informative enough to select. That's the reason I am asking - Marginalia could also be an option to add more infos, but note that you cannot filter based on annotations. At least not directly, you can always do embark occur and then flush-lines.

@leungbk
Copy link
Author

leungbk commented Jan 7, 2021

By prompt contents you mean the last output or the last line? For me prompt usually just means "dir > " or something else depending on the shell/mode. And this wouldn't been informative enough to select.

I mean something like /home/alice > echo "some command", where the candidate contains the first line of the input at that prompt.

That's the reason I am asking - Marginalia could also be an option to add more infos, but note that you cannot filter based on annotations. At least not directly, you can always do embark occur and then flush-lines.

Do you want the output corresponding to a given input prompt to appear in Marginalia annotations as a single line of ^J-separated text?

@minad
Copy link
Owner

minad commented Jan 7, 2021

I mean something like /home/alice > echo "some command", where the candidate contains the first line of the input at that prompt.

I don't get that. Why is there input at the prompt, which I did not execute yet? In 99% of my cases the prompt is empty.

Do you want the output corresponding to a given input prompt to appear in Marginalia annotations as a single line of ^J-separated text?

Output to the corresponding prompt? Which output, I thought the command has not been executed? Do you mean the last command from the history and the last output?

@leungbk
Copy link
Author

leungbk commented Jan 7, 2021

I don't get that. Why is there input at the prompt, which I did not execute yet? In 99% of my cases the prompt is empty.

Output to the corresponding prompt? Which output, I thought the command has not been executed? Do you mean the last command from the history and the last output?

I think we have something different in mind. I envisioned consult-prompts to be able to navigate between multiple prompts from all shell-like buffers, including between all prompts (many of which will be non-empty) in a particular buffer. I think what you describe sounds more like https://github.com/emacs-helm/helm-selector (which I find more useful, but to which I would not assign the name consult-prompts). Do I have this right?

@minad
Copy link
Owner

minad commented Jan 7, 2021

Ah, now I get it. You want something which should show a list of prompts in the current buffer not jumping across buffers. Why is this even useful? Why is this needed in contrast to consult-line? Or is the idea that you can still jump across buffers since you include all prompts of all shell buffers?

Yes, I had something like this helm-selector in mind which allows me to jump between shells and possible create a new one if none of a certain type exists. If you find helm-selector more useful, why do you not propose that one first?

@leungbk
Copy link
Author

leungbk commented Jan 7, 2021

Why is this needed in contrast to consult-line?

Same reason that consult-imenu exists: narrower search space for certain queries. I can live without my conception of consult-prompt being included in consult.el though.

Yes, I had something like this helm-selector in mind which allows me to jump between shells and possible create a new one if none of a certain type exists. If you find helm-selector more useful, why do you not propose that one first?

I thought you would have preferred that the helm-selector-like functionality be a part of the existing consult-buffer, where there already exists spacebar-narrowing functionality. Should we have consult-selector (or whatever, not sure what the name should be) as a separate command? I don't feel strongly either way.

@minad
Copy link
Owner

minad commented Jan 7, 2021

Same reason that consult-imenu exists: narrower search space for certain queries. I can live without my conception of consult-prompt being included in consult.el though.

Yes, but consult-imenu already provides something more specific since it hooks into the existing imenu infrastructure. The consult-prompt you envision is easily emulated (at least in a single buffer) by consult-line with an initial input regexp. There is still the functionality for multiple buffers, but for this we might want to consider some kind of generalized consult-line instead which queries more buffers. consult-prompt would then just be a special case of this consult-line-multibuffer with an initial regexp input.
What do you think about a generalized consult-line-multibuffer?

I thought you would have preferred that the helm-selector-like functionality be a part of the existing consult-buffer, where there already exists spacebar-narrowing functionality. Should we have consult-selector (or whatever, not sure what the name should be) as a separate command? I don't feel strongly either way.

This sounds like a very good idea too! I would actually prefer that. Note #135. So we should at first clean up the buffer sources. Right now this is an ad-hoc mess. It works but it should be cleaned up if we want to add more sources. But when I initially started this I was happy with only files and buffers.

@minad
Copy link
Owner

minad commented Jan 8, 2021

You want to obtain the prompts using these next-prompt functions right? This is certainly different than using consult-line regexps, but I still wonder about the tradeoffs. Maybe most of these functions also use regexps internally? I've at least seen comint-prompt-regexp. But maybe some special modes use markers instead for their next-prompt function?

@leungbk
Copy link
Author

leungbk commented Jan 9, 2021

What do you think about a generalized consult-line-multibuffer?

That sounds fine.

You want to obtain the prompts using these next-prompt functions right? This is certainly different than using consult-line regexps, but I still wonder about the tradeoffs. Maybe most of these functions also use regexps internally? I've at least seen comint-prompt-regexp. But maybe some special modes use markers instead for their next-prompt function?

  1. If we plan to have consult-line-multibuffer, should we still implement this consult-prompt?
  2. I was inclined not to use regexps since the default regexp won't always be right for shell-mode if the user is using a flashy zsh theme or something. But the prompt regexp can still be customized in that case, so I don't feel strongly either way. If regexps are not used, comint-next-prompt seems to check input fields to determine where a prompt lies.

@minad
Copy link
Owner

minad commented Jan 9, 2021

Okay, I see that consult-prompt would work differently than a potential more general consult-line-multibuffer. What do think about the use cases? Would you still see the need for consult-prompt or would a multi buffer search be enough? I usually prefer the more general solution if it is possible and still works reasonably well for the special cases. But there is also consult-error, so I think we can also have consult-prompt. How are the corresponding helm commands called? I saw helm-comint. Is there also the more general helm-prompt?

@minad
Copy link
Owner

minad commented Jan 9, 2021

One more thought - right now most commands are single buffer. Also consult-error, which is unlike counsel-compilation-error I think. This avoids the complications of selecting the relevant set of buffers. But if we add a multi buffer consult-prompt the behavior of the commands should somehow be aligned. Then there is consult-project-imenu. Maybe all consult-prompt, consult-error and consult-imenu should then be made available in two variants. A local one and one that works across buffers, with a reasonable behavior to select the relevant buffers.

@leungbk
Copy link
Author

leungbk commented Jan 9, 2021

Okay, I see that consult-prompt would work differently than a potential more general consult-line-multibuffer. What do think about the use cases? Would you still see the need for consult-prompt or would a multi buffer search be enough? I usually prefer the more general solution if it is possible and still works reasonably well for the special cases. But there is also consult-error, so I think we can also have consult-prompt.

consult-prompt(-multibuffer) would be something that I expect to use only sometimes, to be able to navigate to the output corresponding to some input I happen to remember. In both the single- and multi-buffer cases, this command obviates the need to type in the prompt regexp to guarantee that I match against a prompt.

I do not expect to use consult-line-multibuffer myself, since consult-multi-occur does its job better: setting list-matching-lines-default-context-lines to some nonzero integer gives the results surrounding context in the occur buffer, whereas showing multi-line context in consult-line is not, as far as I know, something that Selectrum or Icomplete are very good at doing right now.

How are the corresponding helm commands called? I saw helm-comint. Is there also the more general helm-prompt?

helm-eshell-prompts offers as candidates the prompts (such as /home/alice >> ) within the current Eshell buffer.

helm-eshell-prompts-all offers all prompts from all Eshell buffers, and can be called from any buffer.

helm-comint-prompts-all can only be called from a comint buffer, which doesn't make sense to me. Otherwise it is similar to helm-eshell-prompts-all.

@minad
Copy link
Owner

minad commented Jan 9, 2021

Okay I see! For me this consult-prompt functionality does not seem useful since I am very accustomed to regular shells and terminals. And there you usually don't do something like this. Furthermore you could always search for the input or parts of the output you remember. But this does not mean that I don't want to have this feature!

But I want a simple solution and there is one readily available - we should really just use regexps! The consult-outline command already works with arbitrary regexps (at least internally), I have to recheck, but I tried at some point to generalize (see 50141d3 in the consult-match branch).

I think we should go that route and simply use the correct prompt regexp.Then we get that feature (at least in the single buffer case) for free. And the multi buffer should then be implemented as consult-outline-multibuffer (if it is even needed after all).

We could even implement consult-outline such that it uses the prompt regexp when used in a shell/terminal buffer! Then we wouldn't even need an extra command! Right now, when I execute consult-outline in eshell, I get the error "No headings". What do you think?

But maybe using regexp is not general/robust enough, that's the question here.

@leungbk
Copy link
Author

leungbk commented Jan 10, 2021

We could even implement consult-outline such that it uses the prompt regexp when used in a shell/terminal buffer!

But maybe using regexp is not general/robust enough, that's the question here.

I'm fine with using a regexp with consult-outline. So it seems we should simply use an association list to determine a makeshift outline-regexp. Should we wait for your consult-match branch to be merged?

@minad
Copy link
Owner

minad commented Jan 10, 2021

Consult-match was just an experiment. You can modify consult-outline accordingly or implement consult-prompt on top of it. I don't think we have both outlines and prompts? If the regexp approach turns out to be too weak we can still reconsider your original proposal. But let's try the easy solution first :)

@minad
Copy link
Owner

minad commented Jan 16, 2021

I think the discussion here has concluded, please feel free to proceed with a PR if you are still interested! I close this issue since I am not going to implement this myself as of now. The feature request is still on the wish list though, so it won't get lost. By the way, do you have any idea regarding the evil issue (emacs-evil/evil#1406)?

@minad minad closed this as completed Jan 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants