aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/tag.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/tag.c')
-rw-r--r--src/nvim/tag.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 264f961b43..e38fbb7da9 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -114,10 +114,49 @@ static char *tagmatchname = NULL; // name of last used tag
static taggy_T ptag_entry = { NULL, INIT_FMARK, 0, 0, NULL };
static int tfu_in_use = false; // disallow recursive call of tagfunc
+static Callback tfu_cb; // 'tagfunc' callback function
// Used instead of NUL to separate tag fields in the growarrays.
#define TAG_SEP 0x02
+/// Reads the 'tagfunc' option value and convert that to a callback value.
+/// Invoked when the 'tagfunc' option is set. The option value can be a name of
+/// a function (string), or function(<name>) or funcref(<name>) or a lambda.
+int set_tagfunc_option(void)
+{
+ callback_free(&tfu_cb);
+ callback_free(&curbuf->b_tfu_cb);
+
+ if (*curbuf->b_p_tfu == NUL) {
+ return OK;
+ }
+
+ if (option_set_callback_func(curbuf->b_p_tfu, &tfu_cb) == FAIL) {
+ return FAIL;
+ }
+
+ callback_copy(&curbuf->b_tfu_cb, &tfu_cb);
+
+ return OK;
+}
+
+#if defined(EXITFREE)
+void free_tagfunc_option(void)
+{
+ callback_free(&tfu_cb);
+}
+#endif
+
+/// Copy the global 'tagfunc' callback function to the buffer-local 'tagfunc'
+/// callback for 'buf'.
+void buf_set_tfu_callback(buf_T *buf)
+{
+ callback_free(&buf->b_tfu_cb);
+ if (tfu_cb.data.funcref != NULL && *tfu_cb.data.funcref != NUL) {
+ callback_copy(&buf->b_tfu_cb, &tfu_cb);
+ }
+}
+
/// Jump to tag; handling of tag commands and tag stack
///
/// *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
@@ -1129,7 +1168,7 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
flags & TAG_REGEXP ? "r": "");
save_pos = curwin->w_cursor;
- result = call_vim_function(curbuf->b_p_tfu, 3, args, &rettv);
+ result = callback_call(&curbuf->b_tfu_cb, 3, args, &rettv);
curwin->w_cursor = save_pos; // restore the cursor position
d->dv_refcount--;