aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-08-21 22:01:00 -0600
committerJosh Rahm <joshuarahm@gmail.com>2022-08-21 22:01:00 -0600
commit5b0e381a261b1450735f4eddac55aeb956c13713 (patch)
treec61f6f14f8b5dc9e2d2f8ed1f78f50179ae3b33a /src/nvim/eval
parentd5cc161deac2371a39821c94fd2de4f1c41b6eb9 (diff)
downloadrneovim-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.c1
-rw-r--r--src/nvim/eval/vars.c14
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);
}