@@ -9,6 +9,8 @@ const cacheKey = "denops_std/buffer/decoration/vimDecorate/rs@1";
99
1010const  PREFIX  =  "denops_std:buffer:decoration:decorate" ; 
1111
12+ const  DEFAULT_DECORATION_PRIORITY  =  0 ; 
13+ 
1214export  type  DecorateOptions  =  { 
1315  /** 
1416   * Decoration namespace 
@@ -33,6 +35,11 @@ export interface Decoration {
3335   * Highlight name 
3436   */ 
3537  highlight : string ; 
38+   /** 
39+    * Priority for the decoration (higher numbers are displayed on top) 
40+    * Defaults to 0 if not specified 
41+    */ 
42+   priority ?: number ; 
3643} 
3744
3845/** 
@@ -53,6 +60,7 @@ export interface Decoration {
5360 *       column: 1, 
5461 *       length: 10, 
5562 *       highlight: "Special", 
63+  *       priority: 10, 
5664 *     }, 
5765 *     { 
5866 *       line: 2, 
@@ -157,41 +165,50 @@ export function listDecorations(
157165  } 
158166} 
159167
160- function  uniq < T > ( array : readonly  T [ ] ) : T [ ]  { 
161-   return  [ ...new  Set ( array ) ] ; 
162- } 
163- 
164168async  function  vimDecorate ( 
165169  denops : Denops , 
166170  bufnr : number , 
167171  decorations : readonly  Decoration [ ] , 
168172  options : Readonly < DecorateOptions >  =  { } , 
169173) : Promise < void >  { 
170174  const  prefix  =  options . namespace  ??  `${ PREFIX }  :${ denops . name }  ` ; 
171-   const  toPropType  =  ( n : string )  =>  `${ prefix }  :${ n }  ` ; 
175+   const  toPropTypeName  =  ( n : string ,  p : number  |  undefined )  => 
176+     `${ prefix }  :${ p  ??  DEFAULT_DECORATION_PRIORITY }  :${ n }  ` ; 
172177  const  rs  =  ( denops . context [ cacheKey ]  ??  new  Set ( ) )  as  Set < string > ; 
173178  denops . context [ cacheKey ]  =  rs ; 
174-   const  hs  =  uniq ( decorations . map ( ( v )  =>  v . highlight ) ) . filter ( ( v )  => 
175-     ! rs . has ( v ) 
176-   ) ; 
177-   const  decoMap  =  new  Map < string ,  Set < [ number ,  number ,  number ,  number ] > > ( ) ; 
179+   const  decosToUpdate  =  Array . from ( 
180+     new  Map ( 
181+       decorations 
182+         . map ( ( {  highlight,  priority } )  =>  ( {  highlight,  priority } ) ) 
183+         . map ( ( p )  =>  [ toPropTypeName ( p . highlight ,  p . priority ) ,  p ]  as  const ) , 
184+     ) . values ( ) , 
185+   ) . filter ( ( p )  =>  ! rs . has ( toPropTypeName ( p . highlight ,  p . priority ) ) ) ; 
186+ 
187+   const  propsByType  =  new  Map < string ,  Set < [ number ,  number ,  number ,  number ] > > ( ) ; 
178188  for  ( const  deco  of  decorations )  { 
179-     const  propType  =  toPropType ( deco . highlight ) ; 
180-     const  props  =  decoMap . get ( propType )  ??  new  Set ( ) ; 
189+     const  propTypeName  =  toPropTypeName ( deco . highlight ,   deco . priority ) ; 
190+     const  props  =  propsByType . get ( propTypeName )  ??  new  Set ( ) ; 
181191    props . add ( [ deco . line ,  deco . column ,  deco . line ,  deco . column  +  deco . length ] ) ; 
182-     decoMap . set ( propType ,  props ) ; 
192+     propsByType . set ( propTypeName ,  props ) ; 
183193  } 
194+ 
184195  await  batch ( denops ,  async  ( denops )  =>  { 
185-     for  ( const  highlight   of  hs )  { 
186-       const  propType  =  toPropType ( highlight ) ; 
187-       await   vimFn . prop_type_add ( denops ,   propType ,  { 
196+     for  ( const  {   highlight,  priority  }   of  decosToUpdate )  { 
197+       const  propTypeName  =  toPropTypeName ( highlight ,   priority ) ; 
198+       const   propOptions :  Record < string ,   unknown >   =  { 
188199        highlight, 
189200        combine : false , 
190-       } ) ; 
191-       rs . add ( highlight ) ; 
201+         priority : priority  ??  DEFAULT_DECORATION_PRIORITY , 
202+       } ; 
203+ 
204+       if  ( ! rs . has ( propTypeName ) )  { 
205+         await  vimFn . prop_type_add ( denops ,  propTypeName ,  propOptions ) ; 
206+       } 
207+       rs . add ( propTypeName ) ; 
192208    } 
209+ 
193210    let  id  =  1 ; 
194-     for  ( const  [ type ,  props ]  of  decoMap . entries ( ) )  { 
211+     for  ( const  [ type ,  props ]  of  propsByType . entries ( ) )  { 
195212      await  vimFn . prop_add_list ( denops ,  {  bufnr,  type,  id : id ++  } ,  [ ...props ] ) ; 
196213    } 
197214  } ) ; 
@@ -240,14 +257,22 @@ async function vimListDecorations(
240257    type : string ; 
241258    type_bufnr : number ; 
242259  } [ ] ; 
243-   return  props 
244-     . filter ( ( prop )  =>  prop . type . startsWith ( `${ prefix }  :` ) ) 
245-     . map ( ( prop )  =>  ( { 
246-       line : prop . lnum , 
247-       column : prop . col , 
248-       length : prop . length , 
249-       highlight : prop . type . split ( ":" ) . pop ( )  as  string , 
250-     } ) ) ; 
260+   return  Promise . all ( 
261+     props 
262+       . filter ( ( prop )  =>  prop . type . startsWith ( `${ prefix }  :` ) ) 
263+       . map ( async  ( prop )  =>  { 
264+         const  propType  =  await  vimFn . prop_type_get ( denops ,  prop . type )  as  { 
265+           priority : number ; 
266+         } ; 
267+         return  ( { 
268+           line : prop . lnum , 
269+           column : prop . col , 
270+           length : prop . length , 
271+           highlight : prop . type . split ( ":" ) . pop ( )  as  string , 
272+           priority : propType . priority , 
273+         } ) ; 
274+       } ) , 
275+   ) ; 
251276} 
252277
253278async  function  nvimDecorate ( 
@@ -270,6 +295,7 @@ async function nvimDecorate(
270295          { 
271296            end_col : deco . column  -  1  +  deco . length , 
272297            hl_group : deco . highlight , 
298+             priority : deco . priority  ??  DEFAULT_DECORATION_PRIORITY , 
273299          } , 
274300        ) ; 
275301      } 
@@ -323,5 +349,6 @@ async function nvimListDecorations(
323349    column : extmark [ 2 ]  +  1 , 
324350    length : extmark [ 3 ] . end_col  -  extmark [ 2 ] , 
325351    highlight : extmark [ 3 ] . hl_group , 
352+     priority : extmark [ 3 ] . priority  ??  DEFAULT_DECORATION_PRIORITY , 
326353  } ) ) ; 
327354} 
0 commit comments