How to fine-tune Macros after having recorded it through recording in Vim?

102 Views Asked by At

Specific question

Description

After recording the desired action to registrar o, I pasted the whole macro to my ~/.vimrc and assigned it as follows (directly pasting the mappings are not displayed properly) enter image description here

Expected behavior

I would like to use this macro to get myself a new "comment line" that leads a new section of script, formatted such that the name of the section is centered. After populating the "section title", I would like to enter insert mode in a new line.

In the following screen-record, I have tested both @o and @p$ on the word "time". The second attempt with@p` worked as desired.

enter image description here

The problem (on Windows machine specifically)

As you see, the @o mapping gets me junk phrases which had been part of my definition for the macro. Does this have to do with the ^M operator? And, how can I fix the @o mapping, which uses * to populate the line?

The two mapping worked just fine on Linux system. (Don't know why, as I have recorded and pasted the macro-definition on Windows machine.) This also does not appear to be a problem on Mac with MacVim.

Generalized question

  1. Is there a way to properly substitute the ^M operator (for <CR>, or "Enter"-key)?
  2. Is there a way to properly substitute the ^[ operator (for <ESC>, or the "Escape"-key)?
  3. Is there a systematic list of mappings from these weird representation of keystrokes, as recorded by the "recording" function through q.

Solution

Substitute the ^M marks in the macro-definition with \r. And, substitute ^[ to be \x1b, for the ESC key. The mappings are fixed as follows:

let @o = ":center\ri\r\x1bkV:s/ /\*/g\rJx50A\*\x1b80d|o"
let @p = ":center\ri\r\x1bkV:s/ /\"/g\rJx50A\"\x1b80d|o"

Complete list of key-codes/mappings? Approach 1: through hex code.

Thanks to Zbynek Vyskovsky, the picture is clear. For whatever key one may think of, Vim takes its ASCII value at the "face value". (The trick is to use a escape clause starting with \x, where x serves as the leader key/string/character connecting to the hex values.) Thus, the correspondence list (incomplete yet), goes as follows:

  • Enter --- \x0d --- \r
  • ESC --- \x1b --- \e

Solution native to Vim

By chance, :help expr-quote gives the following list of special characters. This shall serve as the definite answer to the original question in general form.

string                  *string* *String* *expr-string* *E114*
------
"string"        string constant     *expr-quote*

Note that double quotes are used.

A string constant accepts these special characters:
\...    three-digit octal number (e.g., "\316")
\.. two-digit octal number (must be followed by non-digit)
\.  one-digit octal number (must be followed by non-digit)
\x..    byte specified with two hex numbers (e.g., "\x1f")
\x. byte specified with one hex number (must be followed by non-hex char)
\X..    same as \x..
\X. same as \x.
\u....  character specified with up to 4 hex numbers, stored according to the
    current value of 'encoding' (e.g., "\u02a4")
\U....  same as \u but allows up to 8 hex numbers.
\b  backspace <BS>
\e  escape <Esc>
\f  formfeed <FF>
\n  newline <NL>
\r  return <CR>
\t  tab <Tab>
\\  backslash
\"  double quote
\<xxx>  Special key named "xxx".  e.g. "\<C-W>" for CTRL-W.  This is for use
    in mappings, the 0x80 byte is escaped.
    To use the double quote character it must be escaped: "<M-\">".
    Don't use <Char-xxxx> to get a utf-8 character, use \uxxxx as
    mentioned above.

Note that "\xff" is stored as the byte 255, which may be invalid in some
encodings.  Use "\u00ff" to store character 255 according to the current value
of 'encoding'.

Note that "\000" and "\x00" force the end of the string.
1

There are 1 best solutions below

3
On BEST ANSWER

As you use assigning to register using vim expression language, it's definitely possible in platform independent way. The strings in vim expressions understand the standard escape sequences, therefore it's best to replace ^M with \r and Esc with \x1b:

let @o = ":center\riSomeInsertedString\x1b"

There is no list of of special characters to be translated as far as I know but you can simply take all control characters (ASCII below 32) and translate them to corresponding escape sequence "\xHexValue" where HexValue is the value of the character. Even \r (or ^M) can be translated to \x0d as its ASCII value is 13 (0x0d hex).