Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export Macros Plain Text #14732

Open
W4RH4WK opened this issue Jun 6, 2021 · 11 comments
Open

Export Macros Plain Text #14732

W4RH4WK opened this issue Jun 6, 2021 · 11 comments
Labels
enhancement feature request macros

Comments

@W4RH4WK
Copy link

W4RH4WK commented Jun 6, 2021

Macros stored in registers can already be pasted, modified, and loaded. However, special keys like escape or enter are not represented as printable characters. This makes it hard to store macros in text files.

IIRC there are escape sequences like \<CR> one can use, but there doesn't seem to be a way to convert the original macro representation to one that uses only printable characters.

Can we improve upon this somehow such that macros can be exported to plain text files without messing up the file?

Edit: I also want to load a macro from this plain text representation.

@W4RH4WK W4RH4WK added the enhancement feature request label Jun 6, 2021
@andymass
Copy link
Contributor

andymass commented Jun 6, 2021

What about "=strtrans(@q)<cr>p ?

@W4RH4WK
Copy link
Author

W4RH4WK commented Jun 6, 2021

What about "=strtrans(@q)<cr>p ?

This translates a literal ^[ to ^ [ making it printable, but how would I load the macro now. Even if there'd be a reverse strtrans, a sequence of ^ followed by [ needs to be escaped by strtrans to make it work. Otherwise the reverse strtrans cannot distinguish between ^ followed by [ and a literal ^[.

@PascalZh
Copy link

PascalZh commented Jun 8, 2021

Strongly agree! When I am recording a complex long macro, it's very disturbing when I misspell just single word and has to redo this complex macro.

@W4RH4WK
Copy link
Author

W4RH4WK commented Jun 8, 2021

Strongly agree! When I am recording a complex long macro, it's very disturbing when I misspell just single word and has to redo this complex macro.

You can just paste from the register, modify the macro and load it back. See https://thoughtbot.com/blog/how-to-edit-an-existing-vim-macro.

This works fine when quickly editing a macro, but as you may notice, special characters (like escape) are stored literally, which works fine inside Vim, but does not play nice with regular text files / text processing tools.

@bew
Copy link
Sponsor Contributor

bew commented Jun 8, 2021

Edit: @W4RH4WK basically said what I've written in this message.. Feel free to skip it. Also, sorry it isn't a solution for you, since you know this method but want a plain text version..


@PascalZh To edit a macro you can paste it somewhere in a buffer, edit it, and copy it back into the register, to be applied:

-- record a macro in register a
qa
Afunny^[IDo somtnig^[
q

-- paste it in a buffer
"ap

-- edit it, change somtnig to something

-- copy it back
^"ay$
-- or
^v$"ay
-- can also use d instead of y, to remove it from the buffer

-- apply it where you want!
@a

You can also share macros (really, registers) by saving them in a file, with the syntax:

let @a = 'paste your macro here'

All special characters like Escape (^[) and ^ then [ will be saved and restored correctly.

Note that to paste a register literally from insert mode (if you ever want that), use <C-r><C-o>a instead of <C-r>a (to avoid interpretation of the register content, or bypass vim's auto formatting system)

@bew
Copy link
Sponsor Contributor

bew commented Jun 8, 2021

Regarding plain text, I think a translation can be to encode all non-printable inside < & >:

Escape is: <^[> or <esc>
Enter is: <cr> or <enter>
etc...

With an exception for <, which would be encoded as <<>

Can be done in a few lines of vimscript or C or Lua (not including the translation mappings), would be nice to have it builtin 👍

@PascalZh
Copy link

PascalZh commented Jun 9, 2021

Regarding plain text, I think a translation can be to encode all non-printable inside < & >:

Escape is: <^[> or <esc>
Enter is: <cr> or <enter>
etc...

With an exception for <, which would be encoded as <<>

Can be done in a few lines of vimscript or C or Lua (not including the translation mappings), would be nice to have it builtin 👍

I think some plugin would be better than having it built in. Anybody could give a recommendation?

@andymass
Copy link
Contributor

andymass commented Jun 9, 2021

Maybe it can be done (for example) with something like this:

function! EscReg(reg) abort
  let lhs = '<sid>(_tmp)'
  call nvim_set_keymap('n', lhs, getreg(a:reg), {})
  let res = maparg(lhs)
  call nvim_del_keymap('n', lhs)
  return res
endfunction

nnoremap <silent> \p "=EscReg(nr2char(getchar()))<cr>p

@zeertzjq
Copy link
Member

zeertzjq commented Feb 5, 2022

This seems to be also achievable using FFI:

local ffi = require('ffi')

ffi.cdef([[
char *str2special_save(const char *str, bool replace_spaces, bool replace_lt);
void xfree(void *ptr);
]])

function _G.Str2special(src)
  local ptr = ffi.C.str2special_save(src, true, true)
  local str = ffi.string(ptr)
  ffi.C.xfree(ptr)
  return str
end

These can then be converted back using nvim_replace_termcodes() API.

For example, to turn register a into plain text:

let @a = v:lua.Str2special(@a)

To turn it back into a macro:

let @a = nvim_replace_termcodes(@a, v:false, v:true, v:true)

@W4RH4WK
Copy link
Author

W4RH4WK commented Feb 6, 2022

Btw, other people have pointed out Marvim to me.

@zeertzjq
Copy link
Member

Maybe it can be done (for example) with something like this:

function! EscReg(reg) abort
  let lhs = '<sid>(_tmp)'
  call nvim_set_keymap('n', lhs, getreg(a:reg), {})
  let res = maparg(lhs)
  call nvim_del_keymap('n', lhs)
  return res
endfunction

nnoremap <silent> \p "=EscReg(nr2char(getchar()))<cr>p

keytrans() (#20168) will do what EscReg() does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature request macros
Projects
None yet
Development

No branches or pull requests

6 participants