what is the vim native key comb that will show what is received on next input? - vim

I forgot the key combination for this functionality and I tried to search a bit unfortunately to no avail.
I think it was actually a super simple combination of control or shift with a letter key. The next input in the editor will show the received key.

In command-line mode and insert mode, Ctrl-V is used to insert the next non-numeric keypress literally (i.e. not as a Vim movement or mapping, for example), or to enter a character by its numerical value. E.g.
Ctrl-VEnter will input a CR character (which Vim typically displays as ^M)
Ctrl-VTab will input a Tab character, even if the expandtabs option is set
Ctrl-VRight will input the text <Right>, since there is no one character associated with the right arrow key
Ctrl-V065 will input A, whose ASCII value is 65
Ctrl-VU1F4A9 will insert a poop emoji after you have typed a non-hex-digit
More info at :help i_CTRL-V, :help i_CTRL-V_digit, and equivalent command-line mode topic :help c_CTRL-V.

Related

How to convert visual selection from unicode to the corresponding character in vim command?

I'm trying to convert multiple instances of Unicode codes to their corresponding characters.
I have some text with this format:
U+00A9
And I want to generate the following next to it:
©
I have tried to select the code in visual mode and use the selection range '<,'> in command mode as input for i_CTRL_V but I don't know how to use special keys on a command.
I haven't found anything useful in the manual with :help command-mode . I could solve this problem using other tools but I want to improve my vim knowledge. Any hint is appreciated.
Edit:
As #m_mlvx has pointed out my goal is to visually select, then run some command that looks up the Unicode and does the substitution. Manually input a substitution like :s/U+00A9/U+00A9 ©/g is not what I'm interested in as it would require manually typing each of the special characters on every substitution.
Any hint is appreciated.
Here are a whole lot of them…
:help i_ctrl-v is about insert mode and ranges matter in command-line mode so :help command-mode is totally irrelevant.
When they work on text, Ex commands only work on lines, not arbitrary text. This makes ranges like '<,'> irrelevant in this case.
After carefully reading :help i_ctrl-v_digit, linked from :help i_ctrl-v, we can conclude that it is supposed to be used:
with a lowercase u,
without the +,
without worrying about the case of the value.
So both of these should be correct:
<C-v>u00a9
<C-v>u00A9
But your input is U+00A9 so, even if you somehow manage to "capture" that U+00A9, you won't be able to use it as-is: it must be sanitized first. I would go with a substitution but, depending on how you want to use that value in the end, there are probably dozens of methods:
substitute('U+00A9', '\(\a\)+\(.*\)', '\L\1\2', '')
Explanation:
\(\a\) captures an alphabetic character.
+ matches a literal +.
\(.*\) captures the rest.
\L lowercases everything that comes after it.
\1\2 reuses the two capture groups above.
From there, we can imagine a substitution-based method. Assuming "And I want to generate the following next to it" means that you want to obtain:
U+00A9©
you could do:
v<motion>
y
:call feedkeys("'>a\<C-v>" . substitute(#", '\(\a\)+\(.*\)', '\L\1\2', '') . "\<Esc>")<CR>
Explanation:
v<motion> visually selects the text covered by <motion>.
y yanks it to the "unnamed register" #".
:help feedkeys() is used as low-level way to send a complex series of characters to Vim's input queue. It allows us to build the macro programatically before executing it.
'> moves the cursor to the end of the visual selection.
a starts insert mode after the cursor.
<C-v> + the output of the substitution inserts the appropriate character.
That snippet begs for being turned into a mapping, though.
In case you would like to just convert unicodes to corresponding characters, you could use such nr2char function:
:%s/U+\(\x\{4\}\)/\=nr2char('0x'.submatch(1))/g
Brief explanation
U+\(\x\{4\}\) - search for a specific pattern (U+ and four hexadecimal characters which are stored in group 1)
\= - substitute with result of expression
'0x'.submatch(1) - append 0x to our group (U+00A9 -> 0x00A9)
In case you would like to have unicode character next to text you need to modify slightly right side (use submatch(0) to get full match and . to append)
In case someone wonders how to compose the substitution command:
'<,'>s/\<[uU]+\(\x\+\)\>/\=submatch(0)..' '..nr2char(str2nr(submatch(1), 16), 1)/g
The regex is:
word start
Letter "U" or "u"
Literal "plus"
One or more hex digits (put into "capture group")
word end
Then substituted by (:h sub-replace-expression) concatenation of:
the whole matched string
single space
character by UTF-8 hex code taken from "capture group"
This is to be executed in Visual/command mode and works over selected line range.

vim - surround text with function call

I want to wrap some code :
myObj.text;
with a function call where the code is passed as an argument.
console.log(myObj.text);
I've thought about using surround.vim to do that but didn't manage to do it.
Any idea if it's possible ? I
With Surround in normal mode:
ysiwfconsole.log<CR>
With Surround in visual mode:
Sfconsole.log<CR>
Without Surround in normal mode:
ciwconsole.log(<C-r>")<Esc>
Without Surround in visual mode:
cconsole.log(<C-r>")<Esc>
But that's not very scalable. A mapping would certainly be more useful since you will almost certainly need to do it often:
xnoremap <key> cconsole.log(<C-r>")<Esc>
nnoremap <key> ciwconsole.log(<C-r>")<Esc>
which brings us back to Surround, which already does that—and more—very elegantly.
I know and use two different ways to accomplish this:
Variant 1:
Select the text you want to wrap in visual mode (hit v followed by whatever movements are appropriate).
Replace that text by hitting c, then type your function call console.log(). (The old text is not gone, it's just moved into a register, from where it will be promptly retrieved in step 3.) Hit <esc> while you are behind the closing parenthese, that should leave you on the ) character.
Paste the replaced text into the parentheses by hitting P (this inserts before the character you are currently on, so right between the ( and the )).
The entire sequence is v<movement>c<functionName>()<esc>P.
Variant 2:
Alternatively to leaving insert mode and pasting from normal mode, you can just as well paste directly from insertion mode by hitting <ctrl>R followed by ".
The entire sequence is v<movement>c<functionName>(<ctrl>R")<esc>.
You can use substitution instruction combined with visual mode
To change bar to foo(bar):
press v and select text you want (plus one more character) to surround with function call (^v$ will select whole text on current line including the newline character at the end)
type :s/\%V.*\%V/foo\(&\)/<CR>
Explanation:
s/a/b/g means 'substitute first match of a with b on current line'
\%V.*\%V matches visual selection without last character
& means 'matched text' (bar in this case)
foo\(&\) gives 'matched text surrounded with foo(...) '
<CR> means 'press enter'
Notes
For this to work you have to visually select also next character after bar (^v$ selects also the newline character at the end, so it's fine)
might be some problems with multiline selections, haven't checked it yet
when I press : in visual mode, it puts '<,'> in command line, but that doesn't interfere with rest of the command (it even prevents substitution, when selected text appears also somewhere earlier on current line) - :'<,'>s/... still works

what is the "count" in vim?

Seeing the help of vim I have problem to understand what refers the word count I see it many times while reading the manual:
i Insert text before the cursor [count] times
It would be awesome if you give an example for it.
Vim's "Count" allows you to repeat an operator or command several times. For example, if you are on the first cursor of this line:
Hello world, how are you?
And you type dw you will have
world, how are you?
Rather than typing dwdwdwdw, you may simply type 4dw or d4w and you will have
are you?
More specific to your example, you may type something like 5ihello<esc> and this will insert
hellohellohellohellohello
Like Kevin said in a comment, you can read up more in the help docs with :h count, which says:
*count* *[count]*
[count] An optional number that may precede the command to multiply
or iterate the command. If no number is given, a count of one
is used, unless otherwise noted. Note that in this manual the
[count] is not mentioned in the description of the command,
but only in the explanation. This was done to make the
commands easier to look up. If the 'showcmd' option is on,
the (partially) entered count is shown at the bottom of the
window. You can use <Del> to erase the last digit (|N<Del>|).
Just in case somebody is wondering how count plus insert works, you have to type a number before pressing i, then it will enter in insert mode, where you can type what you want, after you press esc to go back to normal mode, it will repeat count times what you typed.
Can you provide a link to the place in the documentation where you are confused? I would have posted this as a comment instead of an answer, but my reputation is not high enough. In attempting to answer your question without clarification:
Usually [count] can be substituted with a number.
For example; consider the delete command d. If you position your cursor in the middle of a text line and type :d[count] (ex: :d4) then press an arrow key (left or right arrow); you will end up deleting [count] (e.g. 4 characters) in the corresponding direction of the arrow key.
In the case of insert I am not sure to what the argumentcount is referring.
EDIT: I forgot to mention that you must hit the enter key after :d4. Then press the left arrow key. Of course, in order for VIM to realize that you are entering a command you must exit insert mode by pressing the esc key prior to entering the command :d4.

Is there a typeahead buffer for key presses in Linux terminal?

Does Linux buffer keys typed in terminal so that you can read them later one key at a time?
I am asking because I want to catch ESC and arrow key presses and can't find a way to reliably read the codes. I put terminal in non-canonical mode and want program to block if there is no input, but if there is, I want to fetch only one key press for processing.
Update 2: Arrow keys is just an example. I need to identify key presses even for the keys with unknown escape sequences for my program.
There are two conflicting cases:
read(1) returns one character. For both function keys and ESC key this character will be 0x1b. To check if it was an arrow key, you need to read(1), which will block if only single ESC is pressed.
Solution: blocked read(1), non-blocked read(1)
Problem: if second read didn't match any function key, it may mean that it was buffered ESC followed by some sequence, or an unknown function key. How to detect unknown function key press?
read(4) returns at most 4 characters, but if you press ESC four times to let it buffer, you'll get a string of four 0x1b. The same problem to find out if there is an unknown function key press as above.
Can anybody explain how to deal with these problems in Linux terminal, or at least post a proof that Linux just doesn't have input buffer for keys?
You should read up on VT100 escape sequences.
You've discovered that the character code for the escape button (which is sent as a real character, but tends to be used almost exclusively for signalling the beginning of an escape sequence) is 0x1b.
To move the cursor UP: <ESC>[{COUNT}A
To move the cursor DOWN: <ESC>[{COUNT}B
To move the cursor RIGHT: <ESC>[{COUNT}C
To move the cursor LEFT: <ESC>[{COUNT}D
You can test these yourself by typing them into the terminal. Just type the keys one after another. My terminal does not recognize the count argument, but will work successfully if I type <ESC>[X (for X in A,B,C,D).
If your terminal isn't in VT100 mode, look up the escape sequences for whichever mode it's in. You might realize that depending too much on terminal specific escape codes restricts your program to one specific terminal type.

Vim: how to make the text I've just typed uppercase?

Use case: I've just entered insert mode, and typed some text. Now I want to make it uppercase.
It can be done via gUmotion. However, I can't find the motion over the text entered in the recent input session. It's somewhat strange and the concept of such motion is buggy (where to move if you've deleted text, for example?), but it may solve my problem.
Or, are there other ways of making uppercase the text you've recently inputted?
The motion you're looking for is:
`[
(backtick, open-square-bracket). To do a simple motion, you'd use:
gU`[
However, you'll find that the last character probably won't be included due to the way the motion works (I could be wrong). A simple solution would then be to do:
v`[U
Which is to say "go to visual mode, select from the current position to the start of the last changed text, make it upper case". For more information, see:
:help '[
:help mark-motions
Note the difference in :help mark-motions between a backtick and a single-quote.
Type the word in the lower case in the
vim.
Then press Esc key.
Then move the cursor to starting
character of the typed words.
Then press the ~ key.
It will replace the lower case to
upper case.
If the input is upper case it will
replace the lower case.
You can also use the "inner word" motion along with gU
After typing a word press <Esc> and type gUiw. This should work without having to switch to visual mode.
I simply select the text in visual mode and use ~ to change the case, U to uppercase or u to lowercase the selected text.
Edit: See comments below.
Sublime Text Vintage Mode
For those using Vintage Mode in Sublime Text.
Uppercase: g U
Lowercase: g u
Swap case: g ~
More info here.

Resources