aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorglepnir <glephunter@gmail.com>2024-10-03 06:45:01 +0800
committerGitHub <noreply@github.com>2024-10-03 06:45:01 +0800
commit6a2f8958e832aebc20cf42d8ade4cb58fe33df9e (patch)
treee2d5750f75a126a32cc7128ab9c5d1e869b5437a /src
parentd3b4772ddcd4c890dc5bc38e1f1b36a08aed0c04 (diff)
downloadrneovim-6a2f8958e832aebc20cf42d8ade4cb58fe33df9e.tar.gz
rneovim-6a2f8958e832aebc20cf42d8ade4cb58fe33df9e.tar.bz2
rneovim-6a2f8958e832aebc20cf42d8ade4cb58fe33df9e.zip
vim-patch:9.1.0754: fixed order of items in insert-mode completion menu (#30619)
Problem: fixed order of items in insert-mode completion menu Solution: Introduce the 'completeitemalign' option with default value "abbr,kind,menu" (glepnir). Adding an new option `completeitemalign` abbr is `cia` to custom the complete-item order in popupmenu. closes: vim/vim#14006 closes: vim/vim#15760 https://github.com/vim/vim/commit/6a89c94a9eeee53481ced1a1260a177bffde4c0f
Diffstat (limited to 'src')
-rw-r--r--src/nvim/insexpand.c7
-rw-r--r--src/nvim/insexpand.h9
-rw-r--r--src/nvim/option_vars.h2
-rw-r--r--src/nvim/options.lua20
-rw-r--r--src/nvim/optionstr.c45
-rw-r--r--src/nvim/popupmenu.c78
6 files changed, 122 insertions, 39 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index c17bd27daa..84dd55fa78 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -151,13 +151,6 @@ static char *ctrl_x_mode_names[] = {
"cmdline",
};
-// Array indexes used for cp_text[].
-#define CPT_ABBR 0 ///< "abbr"
-#define CPT_MENU 1 ///< "menu"
-#define CPT_KIND 2 ///< "kind"
-#define CPT_INFO 3 ///< "info"
-#define CPT_COUNT 4 ///< Number of entries
-
/// Structure used to store one match for insert completion.
typedef struct compl_S compl_T;
struct compl_S {
diff --git a/src/nvim/insexpand.h b/src/nvim/insexpand.h
index b880e64ea4..8c05590b79 100644
--- a/src/nvim/insexpand.h
+++ b/src/nvim/insexpand.h
@@ -8,3 +8,12 @@
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "insexpand.h.generated.h"
#endif
+
+/// Array indexes used for cp_text[].
+typedef enum {
+ CPT_ABBR, ///< "abbr"
+ CPT_KIND, ///< "kind"
+ CPT_MENU, ///< "menu"
+ CPT_INFO, ///< "info"
+ CPT_COUNT, ///< Number of entries
+} cpitem_T;
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index b9c61160e1..8be437e477 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -429,6 +429,8 @@ EXTERN char *p_cms; ///< 'commentstring'
EXTERN char *p_cpt; ///< 'complete'
EXTERN OptInt p_columns; ///< 'columns'
EXTERN int p_confirm; ///< 'confirm'
+EXTERN char *p_cia; ///< 'completeitemalign'
+EXTERN unsigned cia_flags; ///< order flags of 'completeitemalign'
EXTERN char *p_cot; ///< 'completeopt'
EXTERN unsigned cot_flags; ///< flags from 'completeopt'
// Keep in sync with p_cot_values in optionstr.c
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 825bde5c85..0da954d052 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1427,6 +1427,26 @@ return {
varname = 'p_cfu',
},
{
+ abbreviation = 'cia',
+ cb = 'did_set_completeitemalign',
+ defaults = { if_true = 'abbr,kind,menu' },
+ deny_duplicates = true,
+ desc = [=[
+ A comma-separated list of |complete-items| that controls the alignment
+ and display order of items in the popup menu during Insert mode
+ completion. The supported values are abbr, kind, and menu. These
+ options allow to customize how the completion items are shown in the
+ popup menu. Note: must always contain those three values in any
+ order.
+ ]=],
+ full_name = 'completeitemalign',
+ list = 'onecomma',
+ scope = { 'global' },
+ short_desc = N_('Insert mode completion item align order'),
+ type = 'string',
+ varname = 'p_cia',
+ },
+ {
abbreviation = 'cot',
cb = 'did_set_completeopt',
defaults = { if_true = 'menu,preview' },
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index a9651084b7..c8f19d7ccf 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -995,6 +995,51 @@ int expand_set_complete(optexpand_T *args, int *numMatches, char ***matches)
matches);
}
+/// The 'completeitemalign' option is changed.
+const char *did_set_completeitemalign(optset_T *args)
+{
+ char *p = p_cia;
+ unsigned new_cia_flags = 0;
+ bool seen[3] = { false, false, false };
+ int count = 0;
+ char buf[10];
+ while (*p) {
+ copy_option_part(&p, buf, sizeof(buf), ",");
+ if (count >= 3) {
+ return e_invarg;
+ }
+ if (strequal(buf, "abbr")) {
+ if (seen[CPT_ABBR]) {
+ return e_invarg;
+ }
+ new_cia_flags = new_cia_flags * 10 + CPT_ABBR;
+ seen[CPT_ABBR] = true;
+ count++;
+ } else if (strequal(buf, "kind")) {
+ if (seen[CPT_KIND]) {
+ return e_invarg;
+ }
+ new_cia_flags = new_cia_flags * 10 + CPT_KIND;
+ seen[CPT_KIND] = true;
+ count++;
+ } else if (strequal(buf, "menu")) {
+ if (seen[CPT_MENU]) {
+ return e_invarg;
+ }
+ new_cia_flags = new_cia_flags * 10 + CPT_MENU;
+ seen[CPT_MENU] = true;
+ count++;
+ } else {
+ return e_invarg;
+ }
+ }
+ if (new_cia_flags == 0 || count != 3) {
+ return e_invarg;
+ }
+ cia_flags = new_cia_flags;
+ return NULL;
+}
+
/// The 'completeopt' option is changed.
const char *did_set_completeopt(optset_T *args FUNC_ATTR_UNUSED)
{
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index f836a1bf17..b7892da867 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -525,6 +525,27 @@ static void pum_grid_puts_with_attrs(int col, int cells, const char *text, int t
}
}
+static inline void pum_align_order(int *order)
+{
+ bool is_default = cia_flags == 0;
+ order[0] = is_default ? CPT_ABBR : cia_flags / 100;
+ order[1] = is_default ? CPT_KIND : (cia_flags / 10) % 10;
+ order[2] = is_default ? CPT_MENU : cia_flags % 10;
+}
+
+static inline char *pum_get_item(int index, int type)
+{
+ switch (type) {
+ case CPT_ABBR:
+ return pum_array[index].pum_text;
+ case CPT_KIND:
+ return pum_array[index].pum_kind;
+ case CPT_MENU:
+ return pum_array[index].pum_extra;
+ }
+ return NULL;
+}
+
/// Redraw the popup menu, using "pum_first" and "pum_selected".
void pum_redraw(void)
{
@@ -621,34 +642,27 @@ void pum_redraw(void)
}
// Display each entry, use two spaces for a Tab.
- // Do this 3 times:
- // 0 - main text
- // 1 - kind
- // 2 - extra info
+ // Do this 3 times and order from p_cia
int grid_col = col_off;
int totwidth = 0;
-
- for (int round = 0; round < 3; round++) {
- hlf = hlfs[round];
+ int order[3];
+ int items_width_array[3] = { pum_base_width, pum_kind_width, pum_extra_width };
+ pum_align_order(order);
+ int basic_width = items_width_array[order[0]]; // first item width
+ bool last_isabbr = order[2] == CPT_ABBR;
+ for (int j = 0; j < 3; j++) {
+ int item_type = order[j];
+ hlf = hlfs[item_type];
attr = win_hl_attr(curwin, (int)hlf);
if (pum_array[idx].pum_user_hlattr > 0) {
attr = hl_combine_attr(attr, pum_array[idx].pum_user_hlattr);
}
- if (round == 1 && pum_array[idx].pum_user_kind_hlattr > 0) {
+ if (item_type == CPT_KIND && pum_array[idx].pum_user_kind_hlattr > 0) {
attr = hl_combine_attr(attr, pum_array[idx].pum_user_kind_hlattr);
}
int width = 0;
char *s = NULL;
-
- switch (round) {
- case 0:
- p = pum_array[idx].pum_text; break;
- case 1:
- p = pum_array[idx].pum_kind; break;
- case 2:
- p = pum_array[idx].pum_extra; break;
- }
-
+ p = pum_get_item(idx, item_type);
if (p != NULL) {
for (;; MB_PTR_ADV(p)) {
if (s == NULL) {
@@ -737,31 +751,31 @@ void pum_redraw(void)
}
}
- if (round > 0) {
- n = pum_kind_width + 1;
+ if (j > 0) {
+ n = items_width_array[order[1]] + (last_isabbr ? 0 : 1);
} else {
- n = 1;
+ n = order[j] == CPT_ABBR ? 1 : 0;
}
+ bool next_isempty = false;
+ if (j + 1 < 3) {
+ next_isempty = pum_get_item(idx, order[j + 1]) == NULL;
+ }
// Stop when there is nothing more to display.
- if ((round == 2)
- || ((round == 1)
- && (pum_array[idx].pum_extra == NULL))
- || ((round == 0)
- && (pum_array[idx].pum_kind == NULL)
- && (pum_array[idx].pum_extra == NULL))
+ if ((j == 2)
+ || (next_isempty && (j == 1 || (j == 0 && pum_get_item(idx, order[j + 2]) == NULL)))
|| (pum_base_width + n >= pum_width)) {
break;
}
if (pum_rl) {
- grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, schar_from_ascii(' '), attr);
- grid_col = col_off - pum_base_width - n;
+ grid_line_fill(col_off - basic_width - n + 1, grid_col + 1, schar_from_ascii(' '), attr);
+ grid_col = col_off - basic_width - n;
} else {
- grid_line_fill(grid_col, col_off + pum_base_width + n, schar_from_ascii(' '), attr);
- grid_col = col_off + pum_base_width + n;
+ grid_line_fill(grid_col, col_off + basic_width + n, schar_from_ascii(' '), attr);
+ grid_col = col_off + basic_width + n;
}
- totwidth = pum_base_width + n;
+ totwidth = basic_width + n;
}
if (pum_rl) {