Re: How to do history expansion on a string?
Bart Schaefer <[email protected]>
| Newsgroups | gmane.comp.shells.zsh.devel,gmane.comp.shells.zsh.user |
|---|---|
| Message-ID | <CAH+w=7YkbmpAmm2Wwz4tEzqf5V_nVBwSKA+EgB3ib-WQ6y461w@mail.gmail.com> |
On Wed, Feb 12, 2025 at 4:00 PM vapnik spaknik <[email protected]> wrote: > > Is it possible to expand a bang pattern stored in a string? (e.g. "!123:2"). It depends on when/where/how you want to "expand" it. If you mean expand all the way from !123:2 to ending up with the second word from history event 123, there's no direct way to use bang-references without being able to execute zle widgets to modify the command buffer. > I've tried the zpty and zsocket modules If the shell spawned in zpty has exactly the same history as the shell where you want the expansion, you should be able to do this by using the :p history modifier to get the result of history expansion printed without actually executing a command, so theoretically you can push something into zpty and read it back again expanded, but if you can do all that you can probably also use a zle widget. > I want to make a convenience function for selecting bangs using fzf I have no idea if fzf could drive that, so I'll explain a few things that are possible and let you try to work it out from there. Case 1: If actual bang-text such as !123:2 etc. is present as part of a command line (ZLE $BUFFER) then invoking the expand-word widget at any cursor position will expand all such references, rewriting the contents of the buffer. Note single quotes around a word prevent history expansions, but double quotes do not. Case 2: If the bang-text is stored in a parameter and a reference to that parameter is on the command line, then invoking expand-word with the cursor on that specific word will edit the parameter value into the command line (as with any parameter reference), and now you're back to case 1. By default, however, the result will insert \! so the reference form needs to account for that and for any quoting around it. E.g., ${~bangtext} is sufficient for an unquoted reference, but with double quotes like "${~bangtext}" the backslash will reappear. Case 3: The bang-text is in a parameter and you're able to use a zle widget to modify $BUFFER, you can insert the value directly with something like LBUFFER+=${bangtext} to get a command line like case 1, and then invoke "zle expand-word". The alternative to any of that is to write the desired expansion as a reference to $history. E.g., !123:2 is ${history[123][(w)2]}, although not all conversions are that simple.