patch 9.0.1397: highlight for popupmenu kind and extra cannot be set

Problem:    Highlight for popupmenu kind and extra cannot be set.
Solution:   Add PmenuKind, PmenuKindSel, PmenuExtra and PmenuExtraSel
            highlight groups and use them. (Gianmaria Bajo, closes #12114)
diff --git a/src/highlight.c b/src/highlight.c
index 6716da0..3773ddf 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -164,6 +164,10 @@
     "default link CursorLineSign SignColumn",
     "default link CursorLineFold FoldColumn",
     "default link CurSearch Search",
+    "default link PmenuKind Pmenu",
+    "default link PmenuKindSel PmenuSel",
+    "default link PmenuExtra Pmenu",
+    "default link PmenuExtraSel PmenuSel",
     CENT("Normal cterm=NONE", "Normal gui=NONE"),
     NULL
 };
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 5bd82fc..aeb3b57 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -294,7 +294,7 @@
 # define ISP_LATIN1 (char_u *)"@,161-255"
 #endif
 
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
 
 // Default python version for pyx* commands
 #if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
diff --git a/src/popupmenu.c b/src/popupmenu.c
index a28b3e2..f2e9f50 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -420,11 +420,10 @@
 {
     int		row = pum_row;
     int		col;
-    int		attr_norm = highlight_attr[HLF_PNI];
-    int		attr_select = highlight_attr[HLF_PSI];
     int		attr_scroll = highlight_attr[HLF_PSB];
     int		attr_thumb = highlight_attr[HLF_PST];
     int		attr;
+    int		*attrs; // array used for highlights
     int		i;
     int		idx;
     char_u	*s;
@@ -435,6 +434,11 @@
     int		round;
     int		n;
 
+    int *ha = highlight_attr;
+    //			 "word"		"kind"		"extra text"
+    int	attrsNorm[3] = { ha[HLF_PNI],	ha[HLF_PNK],	ha[HLF_PNX] };
+    int	attrsSel[3] =  { ha[HLF_PSI],	ha[HLF_PSK],	ha[HLF_PSX] };
+
     if (call_update_screen)
     {
 	call_update_screen = FALSE;
@@ -468,7 +472,8 @@
     for (i = 0; i < pum_height; ++i)
     {
 	idx = i + pum_first;
-	attr = (idx == pum_selected) ? attr_select : attr_norm;
+	attrs = (idx == pum_selected) ? attrsSel : attrsNorm;
+	attr = attrs[0]; // start with "word" highlight
 
 	// prepend a space if there is room
 #ifdef FEAT_RIGHTLEFT
@@ -483,18 +488,22 @@
 		screen_putchar(' ', row, pum_col - 1, attr);
 
 	// Display each entry, use two spaces for a Tab.
-	// Do this 3 times: For the main text, kind and extra info
+	// Do this 3 times:
+	// 0 - main text
+	// 1 - kind
+	// 2 - extra info
 	col = pum_col;
 	totwidth = 0;
-	for (round = 1; round <= 3; ++round)
+	for (round = 0; round < 3; ++round)
 	{
+	    attr = attrs[round];
 	    width = 0;
 	    s = NULL;
 	    switch (round)
 	    {
-		case 1: p = pum_array[idx].pum_text; break;
-		case 2: p = pum_array[idx].pum_kind; break;
-		case 3: p = pum_array[idx].pum_extra; break;
+		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;
 	    }
 	    if (p != NULL)
 		for ( ; ; MB_PTR_ADV(p))
@@ -607,15 +616,15 @@
 			width += w;
 		}
 
-	    if (round > 1)
+	    if (round > 0)
 		n = pum_kind_width + 1;
 	    else
 		n = 1;
 
 	    // Stop when there is nothing more to display.
-	    if (round == 3
-		    || (round == 2 && pum_array[idx].pum_extra == NULL)
-		    || (round == 1 && pum_array[idx].pum_kind == NULL
+	    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)
 		    || pum_base_width + n >= pum_width)
 		break;
diff --git a/src/testdir/dumps/Test_pum_highlights_01.dump b/src/testdir/dumps/Test_pum_highlights_01.dump
new file mode 100644
index 0000000..df214f3
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_01.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|1> @68
+|a+0#0000001#e0e0e08|w|o|r|d|1| |W| |e|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52
+|a+0#0000001#ffd7ff255|w|o|r|d|2| |W| |e|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52
+|a+0#0000001#ffd7ff255|w|o|r|d|3| |W| |e|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_pum_highlights_02.dump b/src/testdir/dumps/Test_pum_highlights_02.dump
new file mode 100644
index 0000000..2926d84
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_highlights_02.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|w|o|r|d|1> @68
+|a+0#0000001#e0e0e08|w|o|r|d|1| |W+0#e000002&| |e+0#0000001&|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@52
+|a+0#0000001#ffd7ff255|w|o|r|d|2| |W+0#e000002&| |e+0#767676255&|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@52
+|a+0#0000001#ffd7ff255|w|o|r|d|3| |W+0#e000002&| |e+0#767676255&|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index 1401e55..1b091e3 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -1250,4 +1250,66 @@
   call StopVimInTerminal(buf)
 endfunc
 
+" Test default highlight groups for popup menu
+func Test_pum_highlights_default()
+  CheckScreendump
+  let lines =<< trim END
+    func CompleteFunc( findstart, base )
+      if a:findstart
+        return 0
+      endif
+      return {
+            \ 'words': [
+            \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', },
+            \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', },
+            \ { 'word': 'aword3', 'menu': 'extra text 3', 'kind': 'W', },
+            \]}
+    endfunc
+    set completeopt=menu
+    set completefunc=CompleteFunc
+  END
+  call writefile(lines, 'Xscript', 'D')
+  let buf = RunVimInTerminal('-S Xscript', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "iaw\<C-X>\<C-u>")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_01', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
+" Test custom highlight groups for popup menu
+func Test_pum_highlights_custom()
+  CheckScreendump
+  let lines =<< trim END
+    func CompleteFunc( findstart, base )
+      if a:findstart
+        return 0
+      endif
+      return {
+            \ 'words': [
+            \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', },
+            \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', },
+            \ { 'word': 'aword3', 'menu': 'extra text 3', 'kind': 'W', },
+            \]}
+    endfunc
+    set completeopt=menu
+    set completefunc=CompleteFunc
+    hi PmenuKind      ctermfg=1 ctermbg=225
+    hi PmenuKindSel   ctermfg=1 ctermbg=7
+    hi PmenuExtra     ctermfg=243 ctermbg=225
+    hi PmenuExtraSel  ctermfg=0 ctermbg=7
+  END
+  call writefile(lines, 'Xscript', 'D')
+  let buf = RunVimInTerminal('-S Xscript', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "iaw\<C-X>\<C-u>")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_02', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 24c6fa3..b81b38d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1397,
+/**/
     1396,
 /**/
     1395,
diff --git a/src/vim.h b/src/vim.h
index 5193d59..49b7814 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1418,8 +1418,8 @@
 
 /*
  * Values for index in highlight_attr[].
- * When making changes, also update HL_FLAGS below!  And update the default
- * value of 'highlight' in option.c.
+ * When making changes, also update HL_FLAGS below!
+ * And update the default value of 'highlight': HIGHLIGHT_INIT in optiondefs.h
  */
 typedef enum
 {
@@ -1465,6 +1465,10 @@
     , HLF_SPL	    // SpellLocal
     , HLF_PNI	    // popup menu normal item
     , HLF_PSI	    // popup menu selected item
+    , HLF_PNK	    // popup menu normal item "kind"
+    , HLF_PSK	    // popup menu selected item "kind"
+    , HLF_PNX	    // popup menu normal item "menu" (extra text)
+    , HLF_PSX	    // popup menu selected item "menu" (extra text)
     , HLF_PSB	    // popup menu scrollbar
     , HLF_PST	    // popup menu scrollbar thumb
     , HLF_TP	    // tabpage line
@@ -1485,7 +1489,8 @@
 		  'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
 		  'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
 		  'B', 'P', 'R', 'L', \
-		  '+', '=', 'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', \
+		  '+', '=', '[', ']', '{', '}', 'x', 'X', \
+		  '*', '#', '_', '!', '.', 'o', 'q', \
 		  'z', 'Z'}
 
 /*