Remove preset binding in fish shell - fish

I am unable to remove the default binding in Fish shell for CTRL + p.
I want to activate separate "background" app outside of the terminal using the CTRL+P shortcut.
I have tried:
bind --erase \cp up-or-search
However the binding remains. How can I remove the preset bindings? The documentation does not mention it.

I want this shortcut to propagate up to the parent process rather than Fish swallowing it and reacting to it.
That's not how it works.
If by "parent process" you mean the terminal, that gets first dibs on every key. It gets to decide what is passed on and what isn't.
If by "parent process" you mean an in-terminal process that started fish: That typically stays in the background and doesn't read any keys at all.
And fish will (and has to) read all input it receives, even if it then decides to do nothing. Reading it is how it finds out what it has to do, and it cannot stuff the input back.
And the terminal has no idea what the processes running inside it have bound or not, so it also can't decide to send keys that it knows the shell will do something with and keep others for itself.
Your mental model is incorrect.
How can I remove the preset bindings?
To erase a preset binding, you could run
bind --erase --preset \cp
However, you would have to arrange for that to be run after the binding has actually been set up. You might want to store it in a function called fish_user_key_bindings. Fish runs that after it sets up the bindings, whenever it does it (e.g. if you switch to vi-mode it'll rerun it).
Typically to disable a binding you would rather make your own that does nothing, like
bind \cp true
Not that this would help what you want to do, see above.

Related

How to execute a Sublime plugin command from the command line?

I use the plugin SimpleSession with Sublime Text 3 (but any plugin could be considered). If I save a session with multiple windows, this creates a .simplesession file. How can I open that session file just by clicking on the file? The goal is to avoid having to launch ST3 and use the Command Palette to run the "Load Session" command. Currently, clicking on the .simplesession file causes ST3 to open it as a regular file.
Sublime doesn't know that a simplesession file is important in any way, so double clicking on one is going to open it the same as Sublime would open any other file.
Since it's a plugin that created the file, that plugin is the only thing that knows that it's special and what to do with it. So what you really need is the way to tell the plugin to take the action for you.
All actions in Sublime (including things as simple as inserting text) are taken by executing a command. Here that would be a command in the plugin that created the file in question, which would tell it that you want to carry out the action you would normally take manually, such as loading a session.
To do that from within Sublime you'd do something like bind a keyboard key to the appropriate command, add it to a menu, the command palette, etc. If you want to take the action from outside of Sublime, then you need to communicate that command to Sublime in order to get it to execute.
In core Sublime you can do this by executing the subl program that ships with Sublime and tell it a plugin command that you would like to execute.
Although it's possible to do this, the solution provided here has the requirement that Sublime already be running due to technical limitations within Sublime itself, but more on that in a moment.
This answer will give you the information that you need to formulate the command line that you need to execute in order to get the plugin command to run and carry out the action that you desire.
If you want to run this command in response to double clicking a file of a particular type (here a simplesession file), how you do that is specific to the operating system and file browser that you're using, and is best asked as a separate question.
Assuming you instead want a level of integration where you just have a desktop shortcut, start menu entry, etc that does this, this is more straight forward because such a shortcut is really just a visual wrapper that executes a command of your choosing.
Again, how you would do that is different depending on your OS, but the important part is knowing what full command line you need to give to the shortcut to be able to run it, which is what this answer tells you how to construct.
Important Note: The specific package in your question implements a load_session command, which prompts you for the session to load from a list of sessions you've previously created.
This command doesn't take any argument that would tell it what session to load without asking you to pick one first. As a result, what you want isn't technically possible without more work because there's no way to directly tell the load_session command the file that you want to open.
In order to more fully automate things in this particular case, the underlying package needs to be modified. In particular either the load_session command would need an optional argument which, when given, would cause it to load that session without prompting first, or
a new command would need to be created to do the same thing.
If you're not comfortable or knowledgeable enough to make such modifications to the package directly, you need to either find someone that will do that for you or (even better) discuss it with the package author, since that is a feature that others would probably enjoy as well.
The first thing you need to know is, "What command in the plugin is the one that I need to execute to do what I want?". In some cases you may already know exactly what command you need to use because it's documented, or you have already made a custom key binding for it, and so on.
If you don't know the command you need to use, check the documentation on the package (if any) to see if it mentions them. In your particular case, the README on the package page specifically mentions a list of commands, of which load_session seems like the most appropriate fit.
Lacking any documentation, the next easiest thing to do would be to ask Sublime directly. To do this, select View > Show Console from the menu or press the keyboard shortcut associated with it, Ctrl+`. In the console that appears, enter the following command and press enter.
sublime.log_commands(True)
Now whenever you do anything, this console is going to show you exactly what command Sublime is executing, along with any arguments that it may be passing to the command. This remains in effect until you use the same command with False or restart Sublime.
With logging turned on, select the appropriate command from the command palette and see what the Console says.
For example, with this package installed, I get output like the following:
>>> sublime.log_commands(True)
command: show_overlay {"overlay": "command_palette"}
command: load_session
This is showing two commands; first I opened the command palette which uses the show_overlay command, and then I selected the SimpleSession: Load command, which is the load_session command with no arguments.
In order to get Sublime to execute the command from the command line, you use the --command command line argument to subl. So in order to get Sublime to run the load_session command, you can enter the following command in a command prompt/terminal in your OS. This is also the command you would set in your desktop shortcut.
subl --command "load_session"
This presumes that you've set up Sublime so that it's in the path (how you do that is OS specific). If running subl in a terminal gives you an error about a missing command, either add the Sublime install directory to the path or use a fully qualified file name in place of subl (e,g. "C:\Program Files\Sublime Text 3\subl" if you're on Windows); either requires you to know what location Sublime is installed in.
If you want to use a command that takes arguments you need to include the arguments in the command as well, in the same way as they were displayed in the console above.
It's important that the command name and the arguments all be considered one command line argument, which requires you to wrap the whole thing in quote characters, since otherwise the spaces will make it appear as multiple arguments.
If you forget this, Sublime will respond by opening files named after the different parts of the command and arguments that you tried to open under the mistaken belief that you're giving it files to open.
As a concrete example, to get Sublime to open the command palette from outside of Sublime, the command to do this would look like the following if you were on Linux/MacOS:
subl --command 'show_overlay {"overlay": "command_palette"}'
Note again that we are passing exactly what the console showed above, but the whole thing, command and arguments, are wrapped in single quotes so that the terminal knows that the entire value is one argument.
This makes things a little tricky on Windows, which doesn't allow single quotes. On that platform you need to use double quotes instead. This requires you to "quote" the internal double quotes with a leading \ character so that the command processor knows that they're part of the argument and not the double quote that ends the argument.
For the case of opening the command palette on Windows, the command thus looks like this:
subl --command "show_overlay {\"overlay\": \"command_palette\"}"
With this information in hand, you can set up something like a desktop shortcut to run the appropriate command, or potentially set up the file explorer that you're using to execute a command specifically when you double click on a file of your choosing.
Again, how you would do that is specific to the operating system that you're using, and so I'm not really covering that in depth here in this answer. Just keep in mind that regardless of the OS in question, the part that remains the same is that you need to use subl command like the above.
Now, in your particular case, if the package that you're using provided a command that would let it load the session directly without prompting you first, the command that you use would need to also include the name of the session file as one of the command arguments.
However, as I mentioned above, this package doesn't currently allow that at the moment.
Now, here is the GIANT CAVEAT with this whole thing; this only works if Sublime is already running.
The subl command talks to an existing running copy of Sublime and gives it commands to open a file, directory, run a command as we're doing here, and so on. If Sublime isn't already running, then subl will start Sublime first and then communicate these details to it.
Sublime starts and makes it's interface available to you to work right away, and then starts to load packages and plugins in the background. This is to get you in and working on your files without having to wait for all packages to load first.
An issue with this is that as soon as Sublime starts, subl passes off the appropriate commands and then quits, and since packages aren't loaded yet, the command that you want to execute doesn't exist yet (hasn't been loaded), so nothing actually happens.
Unfortunately there's not really a satisfactory way around this particular issue if you want to start Sublime and also execute commands.
A potential workaround would be use something like a script or batch file that would check to see if Sublime is already running, and if not Start it and delay a little bit to allow plugins to finish loading, then use subl to run the command.
However this would require you to basically guess how long it takes Sublime to finish loading, which is less than ideal.

Expand completions automatically in fish shell?

I wonder if its possible to automatically expand completions menu, which arrives if you hit <tab>? To basically check for autocompletion under cursor every time you enter character, and not only when you hit tab? Thx.
Internaly fish tab completions are done by a fish binding:
bind -k btab complete-and-search
The wildcard binding is bound to self-insert:
bind '' self-insert
self insert adds the captured char passed from bind '' to the current command,
so when a is pressed it inserts a.
The bind command accepts more than one command, so to do this you would need
to wrap __fish_complete_command (Or whatever internal completion fucntion)
and bind it something like this bind '' self-insert command_complete_wrapper
Because in reality, youd would not want to bind to every input, only
a sane subset.
Good luck.

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.

Get tab completion in custom comint mode

I usually try to start CLI's (might not be defining it properly) using commands like:
(make-comint-in-buffer "PUTTY" nil "./plink.exe" nil "dbserver")
(make-comint-in-buffer "Python" nil "c:/Python26/python.exe" nil "-i")
(make-comint-in-buffer "Python" nil "c:/Python27/python.exe" nil "-i")
(make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i")
Starting the above specially the first and the last in command prompt provides the facility of tab completion. But in comint-mode I don't seem to get this feature.
Entering tab adds a simple tab character under the point instead of passing it to the process and getting back the completion candidates. comint-dynamic-complete and C-qtab doesn't produce the desired result.
How can I utilize in above said feature in comint-mode running different processes?
Short answer
You need to write your own completion functions inside Emacs. These may pull info in from the external program, but you can't have direct access to the tab-completion provided by python or git etc.
Long answer:
When you run make-comint-in-buffer, you are setting up the most basic setup for interactively sending and receiving data from an external process. Whenever you press enter, Emacs sends the current line to the underlying process, and then prints back the output from the process. The external process doesn't know what you're doing until Emacs sends a full line to it - no single characters are passed directly.
This is different from running the external program directly in a terminal. When you run python in a terminal, it interprets every character as you type it (or at least it can). So when you hit tab it knows to try to complete something. When you run python inside Emacs, Emacs is processing all of your input until you hit enter. Which means when you hit tab, Emacs just inserts a tab character, and python doesn't know to try and complete something.
Emacs can provide tab-completion for comint modes, but you need to build the completion targets on the Emacs side, you can't rely on the native completion of the external program. To get an idea of how this works, take a look at the completion functions in shell.el, which you can open with M-x find-library shell.
This isn't something you can do with a line or two of elisp. It's an important part of major-modes written to interact with external processes - things like ESS for R http://ess.r-project.org/
That said, if you dig into the guts of shell.el you may find enough code you can modify to get you started.

How to view history of various commands in Emacs

Commands entered after pressing M-x can be viewed using the up/down arrow keys.
How can I get a list of all the commands including menu bar invocation, commands
triggered using mouse clicks, etc. in Emacs?
For a complete list of history, type C-h l (lowercase "L").
Note: this list is complete in the sense that it keeps all events and commands that happened recently, but it's not complete in the sense that it only keeps track of the last 300 or so events (and corresponding commands).
I've used mwe-log-commands to make screencasts. It shows events and the commands they trigger as you work in Emacs.
command-log-mode
I've just forked it and made it into a proper minor-mode and global-minor-mode along with some other improvements as command-log-mode.
Give it a shot and file issues against me if the documentation is unclear or if you find any bugs.
So you want the history of of all commands, regardless of where they are executed? I don't know if emacs provides this by default, but you can add your own function to post-command-hook which is executed after every command, so you can use it to collect all the executed commands.
M-x view-lossage
From emacs documentation
(view-lossage)
Display last few input keystrokes and the commands run. For
convenience this uses the same format as edit-last-kbd-macro. See
lossage-size to update the number of recorded keystrokes.
To record all your input, use open-dribble-file.
(open-dribble-file FILE)
Start writing input events to a dribble file called FILE. Any
previously open dribble file will be closed first. If FILE is nil,
just close the dribble file, if any. If the file is still open when
Emacs exits, it will be closed then.
The events written to the file include keyboard and mouse input
events, but not events from executing keyboard macros. The events are
written to the dribble file immediately without line buffering.
Be aware that this records all characters you type! This may include
sensitive information such as passwords.