Working on various GNU Readline-based CLIs and it would dramatically
speed me up if there was a way to have brackets and quotes
automatically closed when you type.
Thus typing a ' or ( on Bash (or other CLIs) would actually
append the closing quote or bracket '' or () and place the cursor
inbetween for writing.
I've looked around for quite some time trying to find out anything related
(e.g. ~/.inputrc setting), but didn't find anything and I wonder if that's
at all achievable. Any comments would be appreciated.
It's a bit tricky, but doable. As a bash command:
bind '"(" "\C-v()\e[D"'
bind '"\"" "\C-v\"\C-v\"\e[D"'
As a setting in .inputrc (so any program using readline gets the behavior):
"(": "\C-v()\e[D"
"\"": "\C-v\"\C-v\"\e[D"
You can prefix each key with Control-v to type "plain" quotes and left parentheses without triggering the auto-close behavior.
The above assumes Emacs keybindings. For vi bindings, use
bind '"(": "\C-v()\ei"'
bind '"\"" "\C-v\"\C-v\"\ei"'
or
"(": "\C-v()\ei"
"\"": "\C-v\"\C-v\"\ei"
Essentially, just replace the [D with i; instead of sending the escape sequence to move the cursor left, just send \e to drop back into command mode after inserting the parentheses/quotes, then re-enter insert mode, which should position the cursor inside the characters just typed.
Doing exactly what you want is impossible, but there is a work around.
Put this in inputrc:
"\C-x\"": "\"\"C-b"
Run:
info readline "comm" "readline init" "sample"
for the whole sample.
Related
When I use my Fish Shell on Linux Mint, using the Ctrl+Left or Ctrl+Right keys isn't moving the cursor to the previous or next word. It switches between an I and an N instead:
Here is the I and then the N:
I cannot do partial completion then, so it's really boring.
How can I fix this?
Glenn Jackman's comment is correct - you are using vi-mode.
Some third-party prompts (e.g. from Oh-My-Fish or similar) enable it for some reason.
To switch back, usually executing fish_default_key_bindings once interactively should suffice once you have deleted the offending line or package (search for fish_vi_key_bindings).
Or, if you like vi-mode, you can add a binding. Create a function called fish_user_key_bindings (e.g. with funced).
The content should look like this
function fish_user_key_bindings
bind -M $mode $sequence $command
end
where "$command" here would be "backward-word". $mode would be the vi-mode you want the binding to be valid for, e.g. "insert" or "default" (what vi would call "normal" mode).
"$sequence" would be the text sequence that the terminal sends to fish whenever this key combination is pressed. Unfortunately they aren't standardized, so you need to figure out which it is on your system.
fish_key_reader is useful here - execute it, press the combination and use what it tells you. On my terminal ctrl+left sends \e\[1\;5D (and ctrl+right sends the same with C instead of D).
I pushed a key and accidently the text is arraged. I like this way but I cannot know what key I pressed. These screens are captured with help of undo command('u' key).
Surely I tried 'q:' or 'history', but those command only shows the commands that started with colon(:).
You probably used line wrapping
gq
use it in combination with numbers as you would use 'y' or 'd' commands
for wrapping 4 lines: gq4gq OR 4gqgq
for wrapping from cursor to the end: gqG
etc
see more here:
http://vim.wikia.com/wiki/Automatic_word_wrapping
Looks like you've formatted the single long compiler command with gqq (or gql, or Ql if you have that mapping).
The gq command reformats lines; by default, that means inserting hard line breaks at the screen width or 'textwidth'; indeed, this makes the output easier to read.
Alternative
Your initial screenshot shows that you have soft wrapping enabled (:set wrap); with an additional :set linebreak, the wrapping would only occur on certain characters, not on the last fitting character, giving a similar effect as the reformatting, but without actually changing the text.
How do I search/navigate within the current line in zsh? For example, if the cursor is at the end of the line..
// [] indicates cursor position
user#hostname: vim /etx/apache2/sites-enabled/defaul[t]
In vi normal mode, I'd like to use backward-search (?), type etx and have the cursor move like so:
// [] indicates cursor position
user#hostname: vim /[e]tx/apache2/sites-enabled/default
However, / and ? are mapped to history search, not inline search.
I know I can just type 9b and get there, but I find searching and moving to the match is easier than counting the number of words to jump.
Not sure if this was clear at all, let me know if I need to clarify things.
I hope I understood you right. You want to in zsh command line, move your cursor faster when you type commands.
e.g.
user#hostname: vim /etx/apache2/sites-enabled/defaul[t]
You want to move to the first e
I don't use vi-binding, but f and F are your friends.
In that example, you could 5Fe move backwards to the 5th e . If you don't want to count, you could Fe, then press ;, till it moves to the right position.
check vim help for detail:
:h f
:h F
Also faster way would be 0fe, for this example. Moving cursor to beginning, then to e
If I misunderstood your question, please leave comment, I would remove the answer.
This script adds this functionality to zsh:
https://github.com/soheilpro/zsh-vi-search
Maybe the ~/.inputrc file has mapped these keys to something strange? Or you're not fully understanding how the search history works.
Let's start fresh:
Remap these keys with bindkey:
bindkey -M vicmd "?" history-incremental-search-backward
bindkey -M vicmd "/" history-incremental-search-forward
Now, when you press 'esc' (for vi normal mode) and '?' you'll get a bck-i-search command:
%user#hostname: vim /etx/apache2/sites-enabled/defaul[t]
bck-i-search:
At this point, you type what you want to search for, e.g. 'etx'. And, the cursor moves to that position in this line. Note: if it doesn't find that pattern in this current line, it keeps on searching your history. This behavior is considered a feature!
You might notice that you can not repeatedly search (like pressing 'N' in vim). In this case add a few isearch bindings:
bindkey -M isearch '^N' history-incremental-search-backward
bindkey -M isearch '^R' history-incremental-search-forward
Now, pressing control-N repeats your search, while pressing control-S reverses the direction of the repeated search (note: the default order of this keybinding is reversed from forward to backward, since one is more often looking from end of the history back).
In short: treat the current line as the 'top' of your history. Using the vicmd '/' or '?' searches the entirety of that history. The '?' searches top down, while '/' searches from wherever the cursor is currently located in your history towards the 'top'. Another way of thinking about this is to imagine your history as one big file, and the current line your on is at bottom of that file. If that helps you grok it, you may feel that '?' is more pertinent than '/'.
Type v when you are in command mode of your shell, you will be taken to real ViM editor itself. Upon saving & exiting, it will automatically get executed.
I had the same issue. I didn't manage to solve it as such but found a suitable workaroud: added a binding for the edit-command-line function, which drops me to $EDITOR with current line in buffer. There it's easy to navigate to the given pattern.
See /usr/share/zsh/functions/Zle/edit-command-line on how to bind the function.
Bash uses readline, and readline can delete the word to the right of the cursor with "kill-word".
The problem is in recognizing the keypress of control-delete. When I press them in bash, "5~" is output on the screen. I could just bind for this, but it would mean that one day I need to type "5~", and it deletes a word to the right instead! So I'd much rather discover the correct control sequence.
I have googled, and quite a few resources discuss the "delete" key, but none that I've found discuss "control-delete" key. I've experimented with many variations, but nothing works.
The worst is the hours I've spent on this tedious, mindless grind, when it really should be a non-problem.
EDIT: It's through X, so maybe there's a solution with xev and xmodmap
On my machine, pressing Ctrl-V, Ctrl-Delete outputs this:
^[[3;5~
The ^[ escape character can be replaced with \e, so you can then use bind like this for bash (in your ~/.bashrc for example):
bind '"\e[3;5~":kill-word'
Or, you can add the following to your ~/.inputrc so Ctrl-Delete does kill-word in any program that uses readline:
"\e[3;5~": kill-word
This will bind only the Ctrl-Delete key, you don't have to worry about what will happen if you need to type 5~.
What you see is not the whole truth. It's probably <ESC>5~ or something like that. Try Ctrl-V Ctrl-Delete. The Ctrl-V means "do not interpret the next thing".
So binding <ESC>5~ that should be pretty safe.
Alt+D deletes one word to the right of the cursor
Ctrl+W deletes one word to the left of the cursor
(both are based on Emacs, I believe)
If you type ^Q^V (that's Control-Q followed by Control-V, releasing the Control key between them is fine), and then press Control-Delete, do you get the output you mentioned? I just tried it, and at least using Putty I don't get a response at all. Perhaps the behvior is different on an actual Linux console, though.
For other keys, readline prints a longer sequence, often including a special "command sequence introduction" character, which is hard to type by mistake. Try it, and see if you get a longer sequence with the ^Q^V command (which is, btw, called quoted-insert).
For example, if I press ^Q^V and then Delete (without control held down), readline prints ^[[3~. This tells me I can bind stuff to the Delete key by saying \e[[3~. It seems highely likely that the CSI character is present for you, but you're not seeing it since you're not asking readline to quote the input properly.
Ctrl-W deletes words.
Ctrl-u deletes lines.
They're based on Emacs (M-w and M-u).
In Unix the ^ allows you to repeat a command with some text substituted for new text. For example:
csh% grep "stuff" file1 >> Results
grep "stuff" file1
csh% ^file1^file2^
grep "stuff" file2
csh%
Is there a Vim equivalent? There are a lot of times I find myself editing minor things on the command line over and over again.
Specifically for subsitutions: use & to repeat your last substitution on the current line from normal mode.
To repeat for all lines, type :%&
q: to enter the command-line window (:help cmdwin).
You can edit and reuse previously entered ex-style commands in this window.
Once you hit :, you can type a couple characters and up-arrow, and it will character-match what you typed. e.g. type :set and it will climb back through your "sets". This also works for search - just type / and up-arrow. And /abc up-arrow will feed you matching search strings counterchronologically.
There are 2 ways.
You simply hit the . key to perform an exact replay of the very last command (other than movement). For example, I type cw then hello to change a word to "hello". After moving my cursor to a different word, I hit . to do it again.
For more advanced commands like a replace, after you have performed the substition, simply hit the : key then the ↑ up arrow key, and it fills your command line with the same command.
To repeat the previous substition on all lines with all of the same flags you can use the mapping g&.
If you have made a substitution in either normal mode :s/A/B/g (the current line) or visual mode :'<,>'s/A/B/g (lines included in the current selection) and you want to repeat that last substitution, you can:
Move to another line (normal mode) and simply press &, or if you like, :-&-<CR> (looks like :&), to affect the current line without highlighting, or
Highlight a range (visual mode) and press :-&-<CR> (looks like :'<,'>&) to affect the range of lines in the selection.
With my limited knowledge of Vim, this solves several problems. For one, the last visual substitution :'<,'>s/A/B/g is available as the last command (:-<UP>) from both normal and visual mode, but always produces an error from normal mode. (It still refers to the last selection from visual mode - not to the empty selection at the cursor like I assumed - and my example substitution exhausts every match in one pass.) Meanwhile, the last normal mode substitution starts with :s, not :'<,'>s, so you would need to modify it to use in visual mode. Finally, & is available directly from normal mode and so it accepts repetitions and other alternatives to selections, like 2& for the next two lines, and as user ruohola said, g& for the entire file.
In both versions, pressing : then & works as if you had pressed : and then retyped s/A/B/, so the mode you were in last time is irrelevant and only the current cursor line or selection determines the line(s) to be affected. (Note that the trailing flags like g are cleared too, but come next in this syntax too, as in :&g/: '<,'>&g. This is a mixed blessing in my opinion, as you can/must re-specify flags here, and standalone & doesn't seem to take flags at all. I must be missing something.)
I welcome suggestions and corrections. Most of this comes from experimentation just now so I'm sure there's a lot more to it, but hopefully it helps anyway.
Take a look at this: http://vim.wikia.com/wiki/Using_command-line_history for explanation.