From 42a4512f62322fcc12c0071037161d2079d98ba5 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 10 Jul 2015 17:56:23 +0200 Subject: [PATCH] patch 7.4.774 Problem: When using the CompleteDone autocommand event it's difficult to get to the completed items. Solution: Add the v:completed_items variable. (Shougo Matsu) --- runtime/doc/autocmd.txt | 2 ++ runtime/doc/eval.txt | 6 ++++++ src/edit.c | 24 ++++++++++++++++++++++++ src/eval.c | 32 ++++++++++++++++++++++++++++++++ src/macros.h | 3 +++ src/proto/eval.pro | 1 + src/version.c | 2 ++ src/vim.h | 3 ++- 8 files changed, 72 insertions(+), 1 deletion(-) diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index ff05fe5e687e6..2b7b987ede631 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -505,6 +505,8 @@ ColorScheme After loading a color scheme. |:colorscheme| CompleteDone After Insert mode completion is done. Either when something was completed or abandoning completion. |ins-completion| + The |v:completed_item| variable contains + information about the completed item. *CursorHold* CursorHold When the user doesn't press a key for the time diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index c416d773c6b91..d139b12e0a1b4 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1330,6 +1330,12 @@ v:cmdbang Set like v:cmdarg for a file read/write command. When a "!" can only be used in autocommands. For user commands || can be used. + *v:completed_item* *completed_item-variable* +v:completed_item + |Dictionary| containing the |complete-items| for the most + recently completed word after |CompleteDone|. The + |Dictionary| is empty if the completion failed. + *v:count* *count-variable* v:count The count given for the last Normal mode command. Can be used to get the count before a mapping. Read-only. Example: > diff --git a/src/edit.c b/src/edit.c index 76bfcfb9741ff..3e129cb62ba43 100644 --- a/src/edit.c +++ b/src/edit.c @@ -3372,6 +3372,8 @@ ins_compl_clear() vim_free(compl_orig_text); compl_orig_text = NULL; compl_enter_selects = FALSE; + /* clear v:completed_item */ + set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); } /* @@ -4606,17 +4608,39 @@ ins_compl_delete() /* TODO: is this sufficient for redrawing? Redrawing everything causes * flicker, thus we can't do that. */ changed_cline_bef_curs(); + /* clear v:completed_item */ + set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); } /* Insert the new text being completed. */ static void ins_compl_insert() { + dict_T *dict; + ins_bytes(compl_shown_match->cp_str + ins_compl_len()); if (compl_shown_match->cp_flags & ORIGINAL_TEXT) compl_used_match = FALSE; else compl_used_match = TRUE; + + /* Set completed item. */ + /* { word, abbr, menu, kind, info } */ + dict = dict_alloc(); + if (dict != NULL) + { + dict_add_nr_str(dict, "word", 0L, + EMPTY_IF_NULL(compl_shown_match->cp_str)); + dict_add_nr_str(dict, "abbr", 0L, + EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR])); + dict_add_nr_str(dict, "menu", 0L, + EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU])); + dict_add_nr_str(dict, "kind", 0L, + EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND])); + dict_add_nr_str(dict, "info", 0L, + EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO])); + } + set_vim_var_dict(VV_COMPLETED_ITEM, dict); } /* diff --git a/src/eval.c b/src/eval.c index 5869370f3cc2a..5804efa6e1c88 100644 --- a/src/eval.c +++ b/src/eval.c @@ -364,6 +364,7 @@ static struct vimvar {VV_NAME("oldfiles", VAR_LIST), 0}, {VV_NAME("windowid", VAR_NUMBER), VV_RO}, {VV_NAME("progpath", VAR_STRING), VV_RO}, + {VV_NAME("completed_item", VAR_DICT), VV_RO}, }; /* shorthand */ @@ -372,6 +373,7 @@ static struct vimvar #define vv_float vv_di.di_tv.vval.v_float #define vv_str vv_di.di_tv.vval.v_string #define vv_list vv_di.di_tv.vval.v_list +#define vv_dict vv_di.di_tv.vval.v_dict #define vv_tv vv_di.di_tv static dictitem_T vimvars_var; /* variable used for v: */ @@ -888,6 +890,7 @@ eval_init() } set_vim_var_nr(VV_SEARCHFORWARD, 1L); set_vim_var_nr(VV_HLSEARCH, 1L); + set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); set_reg_var(0); /* default for v:register is not 0 but '"' */ #ifdef EBCDIC @@ -20576,6 +20579,35 @@ set_vim_var_list(idx, val) ++val->lv_refcount; } +/* + * Set Dictionary v: variable to "val". + */ + void +set_vim_var_dict(idx, val) + int idx; + dict_T *val; +{ + int todo; + hashitem_T *hi; + + dict_unref(vimvars[idx].vv_dict); + vimvars[idx].vv_dict = val; + if (val != NULL) + { + ++val->dv_refcount; + + /* Set readonly */ + todo = (int)val->dv_hashtab.ht_used; + for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) + { + if (HASHITEM_EMPTY(hi)) + continue; + --todo; + HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; + } + } +} + /* * Set v:register if needed. */ diff --git a/src/macros.h b/src/macros.h index 01207d91b3f5a..773cffdf77bec 100644 --- a/src/macros.h +++ b/src/macros.h @@ -118,6 +118,9 @@ # define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || VIM_ISDIGIT(c)) #endif +/* Returns empty string if it is NULL. */ +#define EMPTY_IF_NULL(x) ((x) ? (x) : (u_char *)"") + /* macro version of chartab(). * Only works with values 0-255! * Doesn't work for UTF-8 mode with chars >= 0x80. */ diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 30416fb8782a5..22b8b189d1cea 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -91,6 +91,7 @@ void set_vim_var_char __ARGS((int c)); void set_vcount __ARGS((long count, long count1, int set_prevcount)); void set_vim_var_string __ARGS((int idx, char_u *val, int len)); void set_vim_var_list __ARGS((int idx, list_T *val)); +void set_vim_var_dict __ARGS((int idx, dict_T *val)); void set_reg_var __ARGS((int c)); char_u *v_exception __ARGS((char_u *oldval)); char_u *v_throwpoint __ARGS((char_u *oldval)); diff --git a/src/version.c b/src/version.c index 8ab862ac411b0..e194707844f28 100644 --- a/src/version.c +++ b/src/version.c @@ -741,6 +741,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 774, /**/ 773, /**/ diff --git a/src/vim.h b/src/vim.h index fe8f558288689..4e36f3d726abf 100644 --- a/src/vim.h +++ b/src/vim.h @@ -1897,7 +1897,8 @@ typedef int proftime_T; /* dummy for function prototypes */ #define VV_OLDFILES 55 #define VV_WINDOWID 56 #define VV_PROGPATH 57 -#define VV_LEN 58 /* number of v: vars */ +#define VV_COMPLETED_ITEM 58 +#define VV_LEN 59 /* number of v: vars */ #ifdef FEAT_CLIPBOARD