aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/edit.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-03-30 21:30:16 +0100
committerJustin M. Keyes <justinkz@gmail.com>2019-03-30 21:30:16 +0100
commita8783012e47e94c6037e49c0a91abc69c8cb29ff (patch)
treed39bd7ecc25f0a5fc30ee92efe92a656867f7313 /src/nvim/edit.c
parentdfb7f6b3492edfd60583f76ee064ac76b1b913d8 (diff)
parent2d63b6d2c17906fafcbbfe7111202cf4c5d392af (diff)
downloadrneovim-a8783012e47e94c6037e49c0a91abc69c8cb29ff.tar.gz
rneovim-a8783012e47e94c6037e49c0a91abc69c8cb29ff.tar.bz2
rneovim-a8783012e47e94c6037e49c0a91abc69c8cb29ff.zip
Merge #9815 'vim-patch:8.1.1068: complete_info()'
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r--src/nvim/edit.c128
1 files changed, 122 insertions, 6 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index a0dce5ff7d..ad7a507ba0 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -58,9 +58,10 @@
#include "nvim/os/input.h"
#include "nvim/os/time.h"
-/*
- * definitions used for CTRL-X submode
- */
+// Definitions used for CTRL-X submode.
+// Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[]
+// and ctrl_x_mode_names[].
+
#define CTRL_X_WANT_IDENT 0x100
#define CTRL_X_NOT_DEFINED_YET 1
@@ -83,17 +84,18 @@
#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
#define CTRL_X_MODE_LINE_OR_EVAL(m) (m == CTRL_X_WHOLE_LINE || m == CTRL_X_EVAL)
+// Message for CTRL-X mode, index is ctrl_x_mode.
static char *ctrl_x_msgs[] =
{
- N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */
+ N_(" Keyword completion (^N^P)"), // CTRL_X_NORMAL, ^P/^N compl.
N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
- NULL,
+ NULL, // CTRL_X_SCROLL: depends on state
N_(" Whole line completion (^L^N^P)"),
N_(" File name completion (^F^N^P)"),
N_(" Tag completion (^]^N^P)"),
N_(" Path pattern completion (^N^P)"),
N_(" Definition completion (^D^N^P)"),
- NULL,
+ NULL, // CTRL_X_FINISHED
N_(" Dictionary completion (^K^N^P)"),
N_(" Thesaurus completion (^T^N^P)"),
N_(" Command-line completion (^V^N^P)"),
@@ -104,6 +106,26 @@ static char *ctrl_x_msgs[] =
NULL, // CTRL_X_EVAL doesn't use msg.
};
+static char *ctrl_x_mode_names[] = {
+ "keyword",
+ "ctrl_x",
+ "unknown", // CTRL_X_SCROLL
+ "whole_line",
+ "files",
+ "tags",
+ "path_patterns",
+ "path_defines",
+ "unknown", // CTRL_X_FINISHED
+ "dictionary",
+ "thesaurus",
+ "cmdline",
+ "function",
+ "omni",
+ "spell",
+ NULL, // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs"
+ "eval"
+};
+
static char e_hitend[] = N_("Hit end of paragraph");
static char e_complwin[] = N_("E839: Completion function changed window");
static char e_compldel[] = N_("E840: Completion function deleted text");
@@ -2980,6 +3002,100 @@ bool ins_compl_active(void)
return compl_started;
}
+// Get complete information
+void get_complete_info(list_T *what_list, dict_T *retdict)
+{
+ int ret = OK;
+#define CI_WHAT_MODE 0x01
+#define CI_WHAT_PUM_VISIBLE 0x02
+#define CI_WHAT_ITEMS 0x04
+#define CI_WHAT_SELECTED 0x08
+#define CI_WHAT_INSERTED 0x10
+#define CI_WHAT_ALL 0xff
+ int what_flag;
+
+ if (what_list == NULL) {
+ what_flag = CI_WHAT_ALL;
+ } else {
+ what_flag = 0;
+ for (listitem_T *item = TV_LIST_ITEM_NEXT(what_list,
+ tv_list_first(what_list))
+ ; item != NULL
+ ; item = TV_LIST_ITEM_NEXT(what_list, item)) {
+ const char *what = tv_get_string(TV_LIST_ITEM_TV(item));
+
+ if (STRCMP(what, "mode") == 0) {
+ what_flag |= CI_WHAT_MODE;
+ } else if (STRCMP(what, "pum_visible") == 0) {
+ what_flag |= CI_WHAT_PUM_VISIBLE;
+ } else if (STRCMP(what, "items") == 0) {
+ what_flag |= CI_WHAT_ITEMS;
+ } else if (STRCMP(what, "selected") == 0) {
+ what_flag |= CI_WHAT_SELECTED;
+ } else if (STRCMP(what, "inserted") == 0) {
+ what_flag |= CI_WHAT_INSERTED;
+ }
+ }
+ }
+
+ if (ret == OK && (what_flag & CI_WHAT_MODE)) {
+ ret = tv_dict_add_str(retdict, S_LEN("mode"),
+ (const char *)ins_compl_mode());
+ }
+
+ if (ret == OK && (what_flag & CI_WHAT_PUM_VISIBLE)) {
+ ret = tv_dict_add_nr(retdict, S_LEN("pum_visible"), pum_visible());
+ }
+
+ if (ret == OK && (what_flag & CI_WHAT_ITEMS)) {
+ list_T *li = tv_list_alloc(ins_compl_len());
+
+ ret = tv_dict_add_list(retdict, S_LEN("items"), li);
+ if (ret == OK && compl_first_match != NULL) {
+ compl_T *match = compl_first_match;
+ do {
+ if (!(match->cp_flags & ORIGINAL_TEXT)) {
+ dict_T *di = tv_dict_alloc();
+
+ tv_list_append_dict(li, di);
+ tv_dict_add_str(di, S_LEN("word"),
+ (const char *)match->cp_str);
+ tv_dict_add_str(di, S_LEN("abbr"),
+ (const char *)match->cp_text[CPT_ABBR]);
+ tv_dict_add_str(di, S_LEN("menu"),
+ (const char *)match->cp_text[CPT_MENU]);
+ tv_dict_add_str(di, S_LEN("kind"),
+ (const char *)match->cp_text[CPT_KIND]);
+ tv_dict_add_str(di, S_LEN("info"),
+ (const char *)match->cp_text[CPT_INFO]);
+ tv_dict_add_str(di, S_LEN("user_data"),
+ (const char *)match->cp_text[CPT_USER_DATA]);
+ }
+ match = match->cp_next;
+ } while (match != NULL && match != compl_first_match);
+ }
+ }
+
+ if (ret == OK && (what_flag & CI_WHAT_SELECTED)) {
+ ret = tv_dict_add_nr(retdict, S_LEN("selected"),
+ (compl_curr_match != NULL)
+ ? compl_curr_match->cp_number - 1 : -1);
+ }
+
+ // TODO(vim):
+ // if (ret == OK && (what_flag & CI_WHAT_INSERTED))
+}
+
+// Return Insert completion mode name string
+static char_u * ins_compl_mode(void)
+{
+ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || compl_started) {
+ return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT];
+ }
+ return (char_u *)"";
+}
+
+
/*
* Delete one character before the cursor and show the subset of the matches
* that match the word that is now before the cursor.