Is there a way to ignore / cancel a specific fish shell completion while typing? - fish

Fish shell is awesome, and its completions is one of the reasons I love it so much.
But, every once in a while, when I type I get a completion that's not useful for me. The problem is the completion replaces what I wrote, and so I don't know how to continue.
Here's an example:
$ touch HELLO
$ echo goodbye > h
When I type the last letter, h, fish shell replaces it with HELLO where the capital H is already typed, and the ELLO part is grayed out, meaning that it will be replaced by future typing.
But I just wanted to create a file named h with the content goodbye - fish gives me a hard time :(
Anyone has any suggestions?

It does not replace what you typed. The effective string is still "h", so just pressing enter will create a file called "h".
(yes, this could be shown better, there is an open issue about it)

Related

How do you disable fish shell's guessing autocompletion feature?

In bash, if you type something like:
ls /etc/abc
and hit <tab>, it will beep, and do nothing, basically letting you know that it couldn't figure out how to complete it. In the case of that specific command, a file starting with /etc/abc didn't exist.
In fish, it will use some sophisticated algorithm to figure out what it thinks you may have meant, and can change what you typed completely, possible changing your ls /etc/abc to ls /etc/fstab, because at some point in the past, you may have typed ls /etc/fstab.
I'm sure it's not that arbitrary, but the fact is, it removed my /etc/abc arg, and replaced it with what it thought I meant. Sometimes, I made one mistake in one character, and instead of going back and fixing my mistake like I would in bash, hitting <tab> replaced the entire thing I wrote, forcing me to rewrite the entire arg.
I can see how some people might like this feature, but for me, it's insanely annoying. Maybe I'm just used to bash.
Is there a way to have fish turns this off, so it never replaces what I wrote? If I wrote /etc/abc, hit <tab>, and it can't figure out a completion that starts with that, leave it alone. Don't replace it with its best guess.
I don't even know what the feature is called. Does it even have a name, or is it just a nameless part of the autocompletion of fish?
Update:
A real example I just ran into.
I have a file in the current directory named lib.py. I type git difftool li and hit <tab>. It replaces what I wrote with git difftool templates/nxt_connect/dish_controls.html, immediately making me want to stab somebody as I have to delete the super long string it helpfully filled in for me, and try again. What's worse is that I assume I typed something in wrong, so I'll try exactly the same thing, and end up with exactly the same result, only to realize fish doesn't have a completion file built-in for git difftool, which is why it doesn't even check my current directory for files.
and can change what you typed completely, possible changing your ls /etc/abc to ls /etc/fstab,
Fish won't change /etc/abc to /etc/fstab
What it will do is fuzzy-match your command, so e.g. /etc/ft will match /etc/fstab, but that's only because both "f" and "t" are in "fstab" in that order, and only if it was the only possible match.
This won't happen with /etc/abc, because that doesn't match /etc/fstab.
because at some point in the past, you may have typed ls /etc/fstab.
It does not take history into account in this case. It really only uses history for the autosuggestion - the greyed-out continuation of what you typed, but that only does prefix matching.
Is there a way to have fish turns this off, so it never replaces what I wrote?
Fish provides no option to change this behavior.
The next fish release (version 3.2) will offer an "undo" function (bound to ctrl+z by default) so you can undo any match by pressing that.
is it just a nameless part of the autocompletion of fish?
fuzzy matching.

Enable returning multiple arguments as completion reply at once in fish shell

I am working on porting Google Cloud SDK command line auto completion feature to fish shell. When I have an unambiguous reply with multiple arguments:
A) Either the command is completed with all those arguments BUT spaces gets escaped (\ ) when I specify the function call in the complete command inside ''s or ""s, like: > complete ... -a '(__fun)'
B) or if I don't do that (just: -a (__fun)), then only the first argument of the reply gets into the completion and all the other arguments "get lost"
Is it possible to reply with multiple arguments at once in fish completion?
Could be done in a number of ways. You will have to hack it a bit, though, since as ridiculous_fish says it's not designed for this.
Easiest would be to ship your own wrapper function that can take the escaped output and pass it on in a way that works. Not very pretty, though, and would screw with autosuggestions unless you also go back and modify the history lines.
Here's something semi-hacky/semi-elegant I would propose:
If you have looked up a "sequence" of args you'd want to complete at once, at first invocation put the trailing args as the description to the first one. Once that one has been locked in, remove all other options but the first in this "description queue", keep going through it and it will simply be a matter of quickly pressing tab-tab-tab-tab.
Completions don't have to be perfect, they're mostly a lil help on the way until you have enough history lines that autosuggestions take over, imo.

How can I modify emacs' Search and Replace to perform a more complicated task?

total Emacs noob here. So right now I'm working on a fairly big LaTeX project in Emacs in which there are couple of places where I need to index some words, using the makeidx package. Because I also wanted indexed words to be bold, I created my own command \ind{} which would make the argument go bold and indexed. But right now I'm dissatisifed with this command so I'd like to change every instance of \ind{whatever} in my text by \textbf{whatever}\index{whatever by default}.
The thing is I know exactly what I want :
Go through the text, look for any instance of \ind{ and replace by \textbf{ using search-and-replace
Save the argument of \ind ("whatever" in this case) in memory
Ask me the user what should the argument of \index be. By default (by striking enter), it should be the first argument, but I can also change my mind and enter something different ("whatever by default" in this case). If there's no input (only a space " " for example) stop the program.
Write down \index{, the new argument and }.
Go to next occurance in the text.
But, alas!, I know not how to achieve this, so I need someone's help. If it should take too much time to explain how to do such a thing, would you please send me some tutorial about writing my own functions?
I hope I'm being clear, and thanks for your patience!
This approach seems vaguely unorthodox to me, but it works and seems sufficient for a one-off job...
In the replacement text for replace-regexp and query-replace-regexp (C-M-%), one newer escape sequence is \,(...), where ... can be any Lisp expression. There's a Lisp function read-from-minibuffer which reads arbitrary text typed by the user, with an optional default. Therefore:
C-M-%: Start query-replace-regexp.
\\ind{\([^}]+?\)}: The pattern to search for.
\\textbf{\1}\\index{\,(read-from-minibuffer "index content? " \1)}: The replacement text. The user will be prompted for the text to put in the braces following the \index{} element, using the original text between the braces following the \ind{} element as a default.
Note that when using query-replace-regexp, you'll have to confirm each choice by typing y after each. Use M-x replace-regexp if you want to avoid this step.
Vlad give you the LaTeX answer to your problem. An Emacs solution is the key-macro: start with
C-x (
to define a new macro, then do one step of your change, say:
C-s \ind{
<left>ex
Then copy and paste the argument in the \textbf macro... You have to be careful to move in a way that will be repeatable. Once the standard modification is done, you let the cursor after the whatever by default and end the definition by
C-x )
now C-x e will call the macro you just define, letting your cursor at the correct place to change the part you want to change You can also repeat the e to call the macro several time at once.
Why not just redefine the \ind so that it can get an optional argument?
For example:
\newcommand{\ind}[2][]{%
\def\first{#1}%
\ifx\first\empty
\textbf{#2}\index{#2}%
\else
\textbf{#2}\index{#1}%
\fi
}
This way you can use \ind{whatever} or \ind[whatever-else]{whatever}.

Matlab-like command history retrieval in unix command line

In Matlab, there is a very nice feature that I like. Suppose I typed the command very-long-command and then a few several commands afterwards. Then later if I need the long command again, I just type very and press the up arrow key, my long command appears. It finds the last command that starts with very. I couldn't do the same in unix command line, when I try to do it, it disregards whatever I typed, and goes back to the last commands in chronological order. Is there a way to do it?
In bash this functionality is provided by the commands history-search-forward and history-search-backward, which by default are not bound to any keys (see here). If you run
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
it will make up-arrow and down-arrow search backward and forward through the history for the string of characters between the start of the current line and the point. See also this related Stack Overflow question.
In bash, hitting ctrl-r will let you do a history search:
$ echo 'something very long'
something very long
$ # blah
$ # many commands later...
(reverse-i-search)`ec': echo 'something very long'
In the above snippet, I hit ctrl-r on the next line after # many commands later..., and then typed ec which brought me back to the echo command. At that point hitting Enter will execute the command.
You can do the same thing by using "!". For example:
$ echo "Hello"
Hello
$ !echo
echo "Hello"
Hello
However, it is generally a bad idea to do this sort of thing (what if the last command did something destructive?). If you expect you will reuse something, then I suggest you create a shell script and save it away somewhere (whenever I plan to reuse something, I create a script in ~/.local/bin).

Is there a way to display a macro list similar to displaying your mappings in Vim?

I know there is a way to list mappings via :map (or :imap, :cmap, etc.), but I can't find a way to list macros I have stored in my vimrc file (as in let #a = 'blahblah').
Is there a way to do this without having to manually looking inside it (via :split [myvimrcfile] or whatever way)?
Also, if it is possible, is there a way to attach some sort of documentation that would display with the macro to explain what it is for? I have a handful that I use quite a bit, but about 6 weeks apart. It would be nice to just quickly list them along with a comment that tells me what the macro does (or even just a name so I make sure I use the right one).
Thanks
In vim, the macros are just stored in registers. You can recall the content of any register and execute it as a macro (which is what the # does). To see a list of what is in your registers, use :reg.
You can see the contents of all the registers using the
:reg
command. Or an argument string like this
:reg ahx
will show you the contents of registers a, h, and x.
That way you can at least see what sequence of commands will be run and hopefully that will be clear enough for you to tell one from another.
The registers simply contain text. You can paste the command sequence in as text or you can copy text into a register and then run it as a command, depending on how you access the register.
I have not found any direct way to edit the contents of a register, but you can paste it into the file, edit it, and then save it back to the same register.
IHTH.
As /u/jheddings wrote the macros are stored as registers and what counts is the assignment of the code to the register (usually done in the vimrc files with let #a=blahblah
To ease the way to display the macros you defined in your vimrc file (in my case it is in the ~/.vimrc path) you can use this vim function:
function! ShowMacros()
10new
exe 'r!' . 'grep -B 1 -E "^\s*let #" ~/.vimrc'
call cursor(1,1)
endfunction
What it does:
10new - open a new vim window with ten lines size
exe ... - execute a command and put in the window
call ... - go to the first line first column
You can execute this function by tipping in the normal mode
:call ShowMacros
You could additionally create a key mapping or a command to fasten the way to call the function:
:cnoremap sm call ShowMacros()<CR>
command! sm call ShowMacros()`
This is the original post where I wrote the function similar to the above.
The OP asked, "is there a way to attach some sort of documentation that would display with the macro to explain what it is for?"
I have found VI / VIM macros extremely obtuse to understand even a week after I've written them, so I heartily support the idea of documentation. I have a suggestion for that, in two parts.
First is the process of documenting the macro in your .vimrc. I've developed the following .vimrc comment format that helps me understand, a week or a year or more later, what a macro is supposed to be doing. E.g.:
"
"= GENERIC CLIPBOARD YANK <F2>y (Y for Yank)
"= Yank the entire contents of the file into the clipboard; quit without saving.
"
"define F2 followed by y to be:
"| Go to line 1.
"| | From there, into the * buffer (system clipboard),
"| | | yank to the end of the file.
"| | | | Go to sleep for 1 second (to allow the clipboard to be updated).
"| | | | | Quit without saving the file.
"| | | | | |
map #2y 1G"*yG1gs:q!<CR>
"-------"-"-"-"--"------
Second, I am imagining that Jakub's ShowMacros() function above could be modified to grep a specific set of Help lines for each macro that would be in the file along with the definition, much the way the above command-line breakdown is attached to the definition, that would provide the needed User Help.
I've flagged two lines above with "= at the beginning of each, so that they can become the User Help. Then Jakub's grep command would search for "^\"= ". Here's the command I used. I'm not sure if the -E for Extended Regular Expressions is needed and the -B 1 is a nice touch to include one line previous to a matching sequence, so here I have an explicitly empty comment line.
In my vimrc, I only needed one backslash, for the initial parsing of the definitions. Here's the line, replacing the one in Jakub's function definition above:
exe 'r!' . 'grep -B 1 -E "^\"= " ~/.vimrc'
Thanks to Jakub's hint, I now can generate help from my .vimrc in pretty much exactly the way the OP is asking for. I've been using vi since 1983, so I'm pretty stoked.
Thanks Jakub!
IHTH,
August