radian-software / selectrum

🔔 Better solution for incremental narrowing in Emacs.
MIT License
736 stars 33 forks source link

Demo video demonstrating some highlights #504

Open clemera opened 3 years ago

clemera commented 3 years ago

@revrari mentioned he might want to record another video demonstrating more highlights of Selectrum in usage with Consult, Marginalia, Orderless and Embark (CC @minad and @oantolin). This issue is for discussing ideas and features which are worth including in such a demonstration to make it interesting and give a broad enough overview of the current capabilities.

Here are some features of Selectrum that might be worth showing/mentioning in such a demo:

minad commented 3 years ago

From the perspective of Consult it makes sense to show case the most important search/navigation commands:

Then I've often seen the need to browse the kill ring using consult-yank-pop. But note that Emacs 28 also has this built-in in a simpler form.

There are many more like "hidden gems", I particularly like the consult-register-load/store commands which I find pretty handy. I think in the end one should point the users to the readmes/wikis and encourage them to explore a bit.

In combination with Embark it may be really good to show the workflows:

The nice thing here is that Embark simply reuses the normal occur and grep mode. This is generally great about Embark, that actions/commands are simply reused. This is not to be overstated!

oantolin commented 3 years ago

One Embark feature which is perhaps not used as much as it could be is acting on things in non-minibuffer buffers. Say you bind embark-act to C-,. Then C-, w is my favorite way of getting the symbol at point into the kill-ring, or the full path of the file name at point (which includes things like the path to foo.el in (use-package foo ...)).

I also like using C-, M-% to replace the symbol at point (for this, make sure to put point at the beginning of the symbol, otherwise, query-replace misses that particular occurrence of the symbol).

In combination with consult-line, you can get a quick overview of all the occurrences of the symbol at point with C-, C l. (Of course you can also call consult-line and press M-n twice, but I find embark-act more convenient.) Or if you want to search for the symbol at point in all files in the current directory, say, you can use C-, C g to run consult-grep.

Another consult-line trick I use fairly often is that if I want to insert at point a duplicate of a line that is in the same buffer but far away from the point, I'll call consult-line to find the line using completion and then use C-, i to insert it at point. (Note that this example does use embark-act in the minibuffer, unlike all the others ---I include it because writing about consult-line reminded me.)

I sometimes mention Emacs commands in emails or markdown buffers (I'm typing this comment in a Markdown buffer). To make sure I don't spout nonsense I usually call describe-function to read the docstring of the function while I'm writing the text. And then I don't need to retype the function name in the email or markdown buffer: I switch to the help buffer, which leaves point on the function name, and press C-, i which inserts it in the text.

The other day I found myself needing to paste a bunch of book titles into several online bookstore websites, and I had the book titles in an org table. I quickly added an Embark target finder for the contents of the current org table cell to my init.el and then just used C-, w to put the cell contents in the OS clipboard. (I should probably add that target finder to Embark itself at some point.)

oantolin commented 3 years ago

(I guess the consult-grep tip isn't so hot, because you can run consult-grep and press M-n once; it's more savings for consult-line which needs two M-ns.)

clemera commented 3 years ago

I also use embark to open video links with mpv, I got the idea from here, transforming region contents is also nice with it.

clemera commented 3 years ago

Another thing that wasn't mentioned yet is the component wise matching of orderless using dispatchers.

clemera commented 3 years ago

@revrari Don't feel pressured to demo everything we mention here, just pick what you personally find interesting enough or which you think fit into a coherent demo. Always feel free to ask for more info how to do something if you run into problems, also see here for basic setups of various combinations. You can run the test scripts using:

cd test; ./run.sh <package-combo>.el

If you are using which-key you might also like to use it for getting prompted for embark actions:

(setq embark-action-indicator
      (lambda (map &optional _target)
        (which-key--show-keymap "Embark" map nil nil 'no-paging)
        #'which-key--hide-popup-ignore-command)
      embark-become-indicator embark-action-indicator)

Regarding orderless here is a my setup:

(setq orderless-matching-styles
      '(orderless-strict-leading-initialism orderless-regexp))

(setq orderless-style-dispatchers
      (list (defun my-orderless-dispatch (pattern _index total)
              (cond
               ((string-prefix-p "!" pattern)
                `(orderless-without-literal . ,(substring pattern 1)))
               ((string-suffix-p "!" pattern)
                `(orderless-strict-full-initialism . ,(substring pattern 0 -1)))
               ((string-suffix-p "=" pattern) `(orderless-literal . ,(substring pattern 0 -1)))
               ((string-suffix-p "~" pattern) `(orderless-flex . ,(substring pattern 0 -1)))))))

For example type !-- to exclude private elisp functions from you search or uf! to get only matches with exactly u and f as initials.

hmelman commented 3 years ago

Agreed on all of the above. Also:

ghost commented 3 years ago

Thank you all for your input. I am going to carefully study your remarks and will revert back if necessary.

ghost commented 3 years ago

@revrari mentioned he might want to record another video demonstrating more highlights of Selectrum in usage with Consult, Marginalia, Orderless and Embark (CC @minad and @oantolin). This issue is for discussing ideas and features which are worth including in such a demonstration to make it interesting and give a broad enough overview of the current capabilities.

Here are some features of Selectrum that might be worth showing/mentioning in such a demo:

  • General emphasis of keeping the usual minibuffer commands/features working unless we provide an enhanced replacement
  • File prompts with partial input /some/long/path/ -> /so/lo/pa/
  • Selection of candidates using quick keys (using M-i/M-m)
  • Toggling between vertical/horizontal display style (using M-q)
  • Using selectrum-display-action to display candidates outside the minibuffer
  • Selecting multiple candidates via completing-read-multiple
  • History browsing (using M-r) (C-i/TAB to insert and proceed, RET/C-m to select and submit)

Thank you. I have looked at each of these and have tested each. They are great features. I would recommend that we create several videos highlighting the features of each program rather than create one long video which looks at the features of all the programs. I.e. do a video called "Selectrum Tweaks" and then "Consult Tweaks" etc.

I would personally not include a feature like 'Selecting multiple candidates via completing-read-multiple' as this is a niche feature that may not be of interest to general users. I am however open to a different point of view.

minad commented 3 years ago

I would personally not include a feature like 'Selecting multiple candidates via completing-read-multiple' as this is a niche feature that may not be of interest to general users. I am however open to a different point of view.

I agree. There are many features we may like as developers since we spent a lot of time thinking about it, but which are not as important enough to be highlighted. Maybe take our ideas here just as hints to which features exist and pick what you like the best, fitting your workflow.

ghost commented 3 years ago

From the perspective of Consult it makes sense to show case the most important search/navigation commands:

  • consult-buffer (already discussed shortly in the current video by @revrari)
  • consult-line
  • consult-outline
  • consult-imenu (narrowing)
  • consult-grep/ripgrep (how does the filtering work, passing options via #xyz -- -i#xyz for example)

Then I've often seen the need to browse the kill ring using consult-yank-pop. But note that Emacs 28 also has this built-in in a simpler form.

There are many more like "hidden gems", I particularly like the consult-register-load/store commands which I find pretty handy. I think in the end one should point the users to the readmes/wikis and encourage them to explore a bit.

In combination with Embark it may be really good to show the workflows:

  • consult-line -> embark-export -> occur-edit-mode
  • consult-ripgrep -> embark-export -> wgrep

The nice thing here is that Embark simply reuses the normal occur and grep mode. This is generally great about Embark, that actions/commands are simply reused. This is not to be overstated!

Thank you for this. I have studied it carefully and think I can highlight all these features in one video. I understand these commands. I have a few questions:

Please explain what you mean by "recursive editing" (i.e. vis-à-vis consult-outline and consult-line) and briefly how this can be done.

You say that consult-buffer supports virtual buffers. Please be more specific as to how this can be enabled (say) for files that have been closed.

ghost commented 3 years ago

One more question. Is there a simply way (a shortcut key perhaps) to copy commands invoked with M-x from the minibuffer into another buffer? Would one need embark for this?

ghost commented 3 years ago
  • consult-grep/ripgrep (how does the filtering work, passing options via #xyz -- -i#xyz for example)

Please explain more fully his syntax to me.

ghost commented 3 years ago
  • consult-line
  • consult-outline

What would you like me to add specifically about these commands which I did not cover in my 1st video.

minad commented 3 years ago

Please explain what you mean by "recursive editing" (i.e. vis-à-vis consult-outline and consult-line) and briefly how this can be done.

You can set enable-recursive-minibuffers to t, then you can jump out of the minibuffer with C-x o and edit the existing buffers. (When you start a minibuffer you enter a recursive editing session - this recursion really happens on the C stack since you start a new recursive event loop.)

Now what I mean with "supports recursive editing" - the commands are robust if line numbers or buffers change. For example if you run consult-line, jump out of the minibuffer, edit, move lines around, then jump back to the minibuffer, the search results will still jump to the correct location.

You say that consult-buffer supports virtual buffers. Please be more specific as to how this can be enabled (say) for files that have been closed.

It is enabled by default if you have recentf-mode enabled. You can configure more virtual buffer sources or write your own even, see https://github.com/minad/consult#multiple-sources.

One more question. Is there a simply way (a shortcut key perhaps) to copy commands invoked with M-x from the minibuffer into another buffer? Would one need embark for this?

You can copy the currently selected candidate with embark-save to the kill ring.

Please explain more fully his syntax to me.

See https://github.com/minad/consult#asynchronous-search.

What would you like me to add specifically about these commands which I did not cover in my 1st video.

I think I saw on reddit that people wanted to see a longer showcase of swiper/consult-line. So maybe make it a bit more detailed? Interesting use cases:

ghost commented 3 years ago

Please explain what you mean by "recursive editing" (i.e. vis-à-vis consult-outline and consult-line) and briefly how this can be done.

You can set enable-recursive-minibuffers to t, then you can jump out of the minibuffer with C-x o and edit the existing buffers. (When you start a minibuffer you enter a recursive editing session - this recursion really happens on the C stack since you start a new recursive event loop.)

Okay. Got it.

Now what I mean with "supports recursive editing" - the commands are robust if line numbers or buffers change. For example if you run consult-line, jump out of the minibuffer, edit, move lines around, then jump back to the minibuffer, the search results will still jump to the correct location.

Okay. Got it.

You say that consult-buffer supports virtual buffers. Please be more specific as to how this can be enabled (say) for files that have been closed.

It is enabled by default if you have recentf-mode enabled. You can configure more virtual buffer sources or write your own even, see https://github.com/minad/consult#multiple-sources.

Ivy has a variable which simply turns this feature on. So I was wondering if there was an equivalent variable in Consult. But you have answered my question.

One more question. Is there a simply way (a shortcut key perhaps) to copy commands invoked with M-x from the minibuffer into another buffer? Would one need embark for this? You can copy the currently selected candidate with embark-save to the kill ring.

Will cover when I do Embark as well

I think I saw on reddit that people wanted to see a longer showcase of swiper/consult-line. So maybe make it a bit more detailed? Interesting use cases:

  • consult-line -> embark-snapshot
  • consult-line -> embark-export -> occur-edit-mode

I will look at these. Thanks.

minad commented 3 years ago

Ivy has a variable which simply turns this feature on. So I was wondering if there was an equivalent variable in Consult. But you have answered my question.

Yes, in Ivy and Ido it is a simple variable to enable virtual buffers. In Ivy virtual buffers are only bookmarks and recent files and in Ido there is only support for recent files. The available virtual buffers are hard coded. The idea of virtual buffers in Ivy goes back to Ido.

In Consult I originally had virtual buffer sources hard coded too, but replaced this with a flexible design where you can add/remove/modify arbitrary sources (https://github.com/minad/consult/issues/135). This design goes more in the direction of helm sources and helm-mini, but the Consult design is deliberately simpler and more restricted to ensure performance and robustness. See also https://github.com/minad/consult/wiki#buffer-sources.

ghost commented 3 years ago

I have completed the videos on Selectrum and Consult. I will need more time to study Orderless and Embark. It is a public holiday here which has allowed me to do this. I will likely only get to the other videos next week. When and how do you think I should release these? I can do so immediately, or wait a few days, releasing them together or separately.

clemera commented 3 years ago

Releasing each with some pause may give them more exposure, you can post them separately and more people will get aware of them. Thank you for doing this!

ghost commented 3 years ago

It is my pleasure. I hope the videos do justice to the programs in question.

clemera commented 3 years ago

No worries, I rather hope you enjoyed learning more about the packages along the way and feel that it was worth doing the work!

ghost commented 3 years ago

Just a question about Embark. If I invoke C-h as a reminder of which actions are available after running embark-act I see keybindings but if I try to execute any of them by typing (for example) "E" for embark-export, nothing happens. I have to use my arrow keys to select and then type RET. Is there something I am missing?

minad commented 3 years ago

There are multiple "prompters", which are used by Embark to query for the action. It seems you are using the completing-read prompter? There is also a keymap prompter, which executes the action corresponding to the key directly.

ghost commented 3 years ago

The current value of Embark Prompter is Use action keymaps

oantolin commented 3 years ago

@minad: @revrari mentioned pressing C-h that gets you the completing-read prompter if you are using the keymap prompter.

@revrari: Once you have pressed C-h, you can type text to narrow the list of commands using completion. The completion is against the command names, not the key bindings. As you've noted, you can also use the arrow keys and RET to select an action, this a normal completing-read session. If you want to use a key binding from the C-h view, just prefix it with @. So, to execute embark-export you could type exp RET or @ E.

minad commented 3 years ago

@revrari My recommendation would be to use which-key in combination with the keymap prompter. Unfortunately support is incomplete, since nested menus are not updated in which-key (https://github.com/oantolin/embark/issues/139). So it is only a half recommendation ;)

ghost commented 3 years ago

So, to execute embark-export you could type exp RET or @ E.

Awesome. Thanks.

ghost commented 3 years ago

@revrari My recommendation would be to use which-key in combination with the keymap prompter. Unfortunately support is incomplete, since nested menus are not updated in which-key (oantolin/embark#139). So it is only a half recommendation ;)

I did have which-key installed, but found the keymap prompter sufficient. So I removed it.

minad commented 3 years ago

I did have which-key installed, but found the keymap prompter sufficient. So I removed it.

Okay :+1: This is a matter of taste. I am more accustomed to using which-key everywhere, so this is my preference.

oantolin commented 3 years ago

If you want a contrarian view, I recommed pressing C-h until you've learned the key bindings, over using which-key. 😛 But I definitely should fix that problem with which-key even though I don't use it myself (to much automatic window movement for my taste, I prefer to control when I summon the keybinding reminder by pressing C-h).

oantolin commented 3 years ago

I'm lying, I don't actually recommend C-h, it's just what I do, not what I recommend. What I do recommend is figuring out your own preference, which I see you have done already. 😉

minad commented 3 years ago

If you want a contrarian view, I recommed pressing C-h until you've learned the key bindings, over using which-key. I'm lying, I don't actually recommend C-h, it's just what I do, not what I recommend. What I do recommend is figuring out your own preference, which I see you have done already. wink

Now that I think about it - maybe I could kick out which-key and really use C-h to summon the keybinding help, e.g., in combination with a prettified keybinding buffer. But for beginners I would definitely propose which-key to get started.

In any case, I am not 100% happy with the status quo:

EDIT: One more point regarding which-key - it would be great if menu-items would get supported at some point. There is an open PR for this but I am unsure if this will be merged soon. This would make the consult narrowing menu nicer and it may also be useful for Embark actions.

oantolin commented 3 years ago

Embark: For the keymap prompter I wouldn't want to switch to the completing read prompter when pressing C-h without which-key. Instead the usual keymap help buffer should be shown. Probably this is possible with minor tweaking?

Why do you want the usual keybinding buffer? You also said:

The keybinding buffer is ugly, I would like something more structured, hierarchical instead of this long flat list.

I thought that something like the completing-read prompter is a nice replacement for the keybindings buffer:

I haven't gotten around to it, but I wanted to figure out if I could use the completing-read prompter globally instead of the usual keybinding buffer (and instead of which-key, which is automatic --and thus "too aggressive" for me-- and hard to search --you have to scan visually!, it's as if completing-read was never invented!).

minad commented 3 years ago

Why do you want the usual keybinding buffer? You also said:

I am assuming that I have a better, prettier replacement for the keybinding buffer.

I thought that something like the completing-read prompter is a nice replacement for the keybindings buffer:

Agree. I just find the switch from keymap prompter to completing read prompter unexpected. A keybinding buffer as help for the keymap prompter would be more aligned with the usual behavior.

I haven't gotten around to it, but I wanted to figure out if I could use the completing-read prompter globally instead of the usual keybinding buffer (and instead of which-key, which is automatic --and thus "too aggressive" for me-- and hard to search --you have to scan visually!, it's as if completing-read was never invented!).

That's an interesting idea actually. I would like this since one would get a consistent interface everywhere and I value consistency. I do not disagree that completing read is better than which key or the keybinding buffer.

If you find a way to introduce completing-read globally instead of the keybinding buffer I see myself switching from which-key to that solution!

clemera commented 3 years ago

I experimented with prefix command completion a while ago , it depends on which-key but that doesn't bother me because I use both.

minad commented 3 years ago

@clemera Sounds good, but I would love to see something simpler then if it is possible without the which-key dependency. Simply showing a completing-read completion with all the keybindings. But probably this would involve doing a part of the which-key work, looking up all the keybindings and so on.

oantolin commented 3 years ago

It was really just laziness that I hadn't done this before now: I needed to find out how to change what C-h runs; but thanks to @clemera's blog post I now know that prefix-help-command is the variable to set!

(defun prompt-for-prefix-binding ()
  (interactive)
  (let* ((keys (this-command-keys))
         (prefix (seq-take keys (1- (length keys)))))
    (call-interactively
     (embark-completing-read-prompter
      (key-binding prefix)))))

(setq prefix-help-command #'prompt-for-prefix-binding)

EDIT: Wow, I love it!

EDIT2: @clemera suggested the above use of (key-binding prefix), I originally had (lookup-key (current-global-map) prefix).

clemera commented 3 years ago

@oantolin Maybe (key-binding prefix) would work for more cases?

oantolin commented 3 years ago

Oh, maybe, @clemera. And even if it were the same, it certainly feels like it more directly expresses intent. I'll use it instead in my config, thanks!

clemera commented 3 years ago

I will use your function, too! Very nice!

clemera commented 3 years ago

BTW, I also did not knew about the "@" trick so far which is a great addition!

minad commented 3 years ago

Great! I will also use that instead! This is indeed much better - and we get it nearly for free. I wouldn't have expected this to be so simple.

oantolin commented 3 years ago

BTW, I also did not knew about the "@" trick so far which is a great addition!

Yeah, in Emacs UX I'm all about late binding, so I wanted two-way escape hatches between the keymap prompter and the completing-read prompter.

minad commented 3 years ago

@oantolin What about adding embark-prefix-help-command to highlight this use case a bit more?

oantolin commented 3 years ago

@oantolin What about adding embark-prefix-help-command to highlight this use case a bit more?

Sure, no problem!

oantolin commented 3 years ago

Great! I will also use that instead! This is indeed much better - and we get it nearly for free. I wouldn't have expected this to be so simple.

This was indeed way easier than I expected. 🎉

ghost commented 3 years ago

Okay, I have just completed also the video on Embark. One more to go: Orderless.

oantolin commented 3 years ago

Thank you for all your work on this, @revrari.

clemera commented 3 years ago

The Selectrum is now available here + reddit thread, thanks again @revrari! Looking forward to watch the other demos as well!

ghost commented 3 years ago

I am not sure why this thread has been closed. I wanted still to discuss the videos on Embark and Consult with the authors. I also had questions about Orderless. Please let me know if you would like to preview your video before I release it. If so, we will need to create an alternative form of discussion.