2

Cross-posting from Stackoverflow because I keep forgetting about this site...

Have a macro where a visually selected text will be made a markdown link and once the macro executes it leaves Vim in INSERT mode:

| - VISUAL selection i - cursor position in INSERT mode @l - invoke macro in "l" register Some |text| saying stuff. = @l => Some [text]() saying stuff. i 

Register l holds the following:

:registers l Type Name Content c "l S]%a()^Ohq<80>kb 

Created it the following way:

  1. Visually select some text
  2. q then l
  3. S then ] (S is a visual selection command in vim-surround)
    ^ - normal mode cursor position |text| =S]=> [text] ^ 
  4. % (jump to closing bracket)
  5. a and then type ()
  6. CTRL-O
  7. h
  8. CTRL-O then q (to finish the macro but to remain in INSERT mode)

So I selected this definition with the mouse (i.e., * register), and did let @l = "S]%a()^Ohq<80>kb" in the other Vim instance, resulting in

Some |text| saying stuff. = @l => Some [text]()^Ohq<80>kb saying stuff. i 

It works if Vim is built with clipboard support (:let @+ = @l in one Vim instance, and :let @l = @+ in another), but I would like to learn the fundamentals of deciphering these representations.

UPDATE: There is a slight difference between the Vim representations of the recorded & clipboard-copied macros and the ones that are pasted manually: the sequences ^O and <80> are highlighted as special in the former case, but the string is shown with uniform color in the latter.

The l is the original recorded macro, + is created by :let @+ = @l, and c content has been typed in verbatim:

enter image description here


Found a couple other Stackoverflow threads with a similar premise, but they weren't helpful:

VIM macro editing

Tried to convert the ^O to <C-O> but it didn't work, and have no clue what <80>kb is.

Based on the creation steps above, I would have expected something like S]%a()^Oh^Oq instead of S]%a()^Ohq<80>kb anyway.

Reliable solution to copy/paste Vim macros

No replies, and based on what I understood, it is not applicable in my case.

Saving vim macros

Chewed my way through the answers and comments, but no joy.

2 Answers 2

3

The first Control-o has to be done with <C-v><C-o>; no idea about where the other bytes came from, but you can input the <80> with <C-v>x80.

On the other hand, macros in vim tend to be better-suited to interactive tasks. Once you want to start saving them, you'll need to either

  • let them be saved via viminfo files (this is done automatically if you use the default 'viminfo' setting, but you may need to set viminfofile?).
  • create a mapping/function/etc., which is a little more robust for automation tasks, especially persistent tasks (I treat macros a little more ephemerally, since they can be clobbered by using the register for other things.)

So personally I would add the following to ~/.vim/after/ftplugin/markdown.vim (since it looks you're creating markdown links):

xmap <buffer> <localleader>l S]%a()<C-o>h 
  • xmap for visual-mode excluding select-mode (map instead of noremap for recursive mappings—S is a plugin-provided mapping that we want to re-use here)
  • <buffer> to keep it local
  • <localleader>l how to invoke it (probably \l with a default configuration)
  • S]%a()<C-o>h your mapping, without all the macro stuff in the way (and, benefit: it's easier to edit and read)
0
3

The explanation

D. Ben Knoble has given you a good alternative solution, and explained one way of setting the exact register contents with a :let command, but as you said you wanted to learn the fundamentals, I thought I'd add a little extra explanation.

As you noted, in the recorded macro, the ^O and <80> are highlighted. This is because they are not simple sequences of multiple characters, but instead Vim's representation of "special characters". The ^O is the ASCII SI (shift in) character, which can also be represented or typed as CTRL-O or the hex code 0x0f.

<80> is hex 0x80, but Vim in this instance Vim is using this as the first byte of <80>kb, which is its internal representation of a backspace.

You can add these to strings either by inserting them directly either by using Ctrl-V (as suggested by Ben), or by using Vim's backslash escapes:

:echo "\<C-O>" :echo "\x0f" :echo "\<BS>" :echo "\x80kb" 

Like Ben, I'm very unclear why there are a q and a backspace in your recorded macro (I can't reproduce this when recording my own macro: could be something to do with your configuration). Regardless, it's obviously not necessary for your macro to insert a q and then immediately delete it, so one way of achieving your goal would be with the following :let command:

The solution

:let @l = "S]%a()\<C-O>h" 
2
  • 1
    Why there's a "q" => User wanted to end macro recording in Insert mode, so they typed "q" but that inserted a literal "q", then they used backspace to fix it (remove the "q") and finally used Ctrl-O + q to end the macro recording. That's my hypothesis. Yes, cleaning the macro not to include those two would be a great way to make the problem go away. Commented May 27, 2021 at 15:00
  • 1
    @filbranden :oooooh-emoji: Commented May 27, 2021 at 15:20

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.