diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2022-08-21 22:01:00 -0600 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2022-08-21 22:01:00 -0600 |
| commit | 5b0e381a261b1450735f4eddac55aeb956c13713 (patch) | |
| tree | c61f6f14f8b5dc9e2d2f8ed1f78f50179ae3b33a /src/nvim/eval | |
| parent | d5cc161deac2371a39821c94fd2de4f1c41b6eb9 (diff) | |
| download | rneovim-5b0e381a261b1450735f4eddac55aeb956c13713.tar.gz rneovim-5b0e381a261b1450735f4eddac55aeb956c13713.tar.bz2 rneovim-5b0e381a261b1450735f4eddac55aeb956c13713.zip | |
feat(userreg): Add user-defined registers to Neovim.
This change unlocks additional registers for Neovim by allowing a user
to define their own behavior for non-builtin registers.
This is accopmlished through a new option 'userregfunc'
The 'userregfunc' defines the function to call when handling a register
for which there is no builtin functionality.
The 'userregfunc' function should take 3 arguments:
action - Either "yank" or "put"
register - The character corresponding to the register
content - In the case of action == "yank", the dictionary describing
the yanked content, with the following keys:
{type} - Either "char", "line" or "block"
{lines} - The lines being yanked as a list
{width} - The width in case of "block" mode.
{additional_data} - Additional data (can be returned in
"put" mode)
In case of "put" this function should return the content to put. This
content can be either:
* A dictionary in the same template as content above.
* A list of strings. This will be assumed to be "line" mode.
* A string. This will be assumed to be "char" mode.
An example of a "null" 'userregfunc' that provides an implementation
identical to traditional vim registers would be:
let s:contents = {}
function! MyUserregFunction(action, register, content) abort
if a:action == "put"
return get(s:contents, a:register, "")
else
let s:contents[a:register] = a:content
endif
endfunction
set userregfun=MyUserregFunction
It is important to note that any valid unicode character can now be a
register, including something like @☺.
This change also addresses the multibyte parsing issues surrounding
let @a = 'xyz'
let @🔨 = 'hammer'
Diffstat (limited to 'src/nvim/eval')
| -rw-r--r-- | src/nvim/eval/funcs.c | 1 | ||||
| -rw-r--r-- | src/nvim/eval/vars.c | 14 |
2 files changed, 10 insertions, 5 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 9c3c859771..1e39042a53 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3673,6 +3673,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "winaltkeys", "writebackup", "nvim", + "userreg", }; // XXX: eval_has_provider() may shell out :( diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index b38849730a..73e84a8c1e 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -388,7 +388,7 @@ const char *skip_var_list(const char *arg, int *var_count, int *semicolon) static const char *skip_var_one(const char *arg) { if (*arg == '@' && arg[1] != NUL) { - return arg + 2; + return arg + 1 + utfc_ptr2len(arg + 1); } return (char *)find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); @@ -692,10 +692,14 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo return NULL; } arg++; + + int regname = utf_ptr2char(arg); + int mblen = utf_ptr2len(arg); + if (op != NULL && vim_strchr("+-*/%", *op) != NULL) { semsg(_(e_letwrong), op); } else if (endchars != NULL - && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) { + && vim_strchr(endchars, *skipwhite(arg + mblen)) == NULL) { emsg(_(e_letunexp)); } else { char *s; @@ -703,7 +707,7 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo char *ptofree = NULL; const char *p = tv_get_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { - s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); + s = get_reg_contents(*arg == '@' ? '"' : regname, kGRegExprSrc); if (s != NULL) { ptofree = (char *)concat_str((char_u *)s, (const char_u *)p); p = (const char *)ptofree; @@ -711,9 +715,9 @@ static char *ex_let_one(char *arg, typval_T *const tv, const bool copy, const bo } } if (p != NULL) { - write_reg_contents(*arg == '@' ? '"' : *arg, + write_reg_contents(*arg == '@' ? '"' : regname, (const char_u *)p, (ssize_t)STRLEN(p), false); - arg_end = arg + 1; + arg_end = arg + mblen; } xfree(ptofree); } |