Patch 8.1.1734
Problem:    The evalfunc.c file is too big.
Solution:   Move some functions to other files.
Files:      src/evalfunc.c, src/proto/evalfunc.pro, src/json.c,
            src/proto/json.pro src/window.c, src/proto/window.pro,
            src/highlight.c, src/proto/highlight.pro, src/globals.h


*** ../vim-8.1.1733/src/evalfunc.c      2019-07-14 14:55:20.368881426 +0200
--- src/evalfunc.c      2019-07-22 22:34:05.646370098 +0200
***************
*** 24,33 ****
  # include <time.h>    /* for time_t */
  #endif
  
- static char *e_listarg = N_("E686: Argument of %s must be a List");
  static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
  static char *e_stringreq = N_("E928: String required");
- static char *e_invalwindow = N_("E957: Invalid window number");
  
  #ifdef FEAT_FLOAT
  static void f_abs(typval_T *argvars, typval_T *rettv);
--- 24,31 ----
***************
*** 164,170 ****
  static void f_getjumplist(typval_T *argvars, typval_T *rettv);
  static void f_getline(typval_T *argvars, typval_T *rettv);
  static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED);
- static void f_getmatches(typval_T *argvars, typval_T *rettv);
  static void f_getpid(typval_T *argvars, typval_T *rettv);
  static void f_getcurpos(typval_T *argvars, typval_T *rettv);
  static void f_getpos(typval_T *argvars, typval_T *rettv);
--- 162,167 ----
***************
*** 213,222 ****
  #endif
  static void f_items(typval_T *argvars, typval_T *rettv);
  static void f_join(typval_T *argvars, typval_T *rettv);
- static void f_js_decode(typval_T *argvars, typval_T *rettv);
- static void f_js_encode(typval_T *argvars, typval_T *rettv);
- static void f_json_decode(typval_T *argvars, typval_T *rettv);
- static void f_json_encode(typval_T *argvars, typval_T *rettv);
  static void f_keys(typval_T *argvars, typval_T *rettv);
  static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv);
  static void f_len(typval_T *argvars, typval_T *rettv);
--- 210,215 ----
***************
*** 238,247 ****
  static void f_maparg(typval_T *argvars, typval_T *rettv);
  static void f_mapcheck(typval_T *argvars, typval_T *rettv);
  static void f_match(typval_T *argvars, typval_T *rettv);
- static void f_matchadd(typval_T *argvars, typval_T *rettv);
- static void f_matchaddpos(typval_T *argvars, typval_T *rettv);
- static void f_matcharg(typval_T *argvars, typval_T *rettv);
- static void f_matchdelete(typval_T *argvars, typval_T *rettv);
  static void f_matchend(typval_T *argvars, typval_T *rettv);
  static void f_matchlist(typval_T *argvars, typval_T *rettv);
  static void f_matchstr(typval_T *argvars, typval_T *rettv);
--- 231,236 ----
***************
*** 2202,2208 ****
        rettv->vval.v_number = -1;
  }
  
!     static win_T *
  get_optional_window(typval_T *argvars, int idx)
  {
      win_T   *win = curwin;
--- 2191,2197 ----
        rettv->vval.v_number = -1;
  }
  
!     win_T *
  get_optional_window(typval_T *argvars, int idx)
  {
      win_T   *win = curwin;
***************
*** 5285,5358 ****
  }
  
  /*
-  * "getmatches()" function
-  */
-     static void
- f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_SEARCH_EXTRA
-     dict_T    *dict;
-     matchitem_T       *cur;
-     int               i;
-     win_T     *win = get_optional_window(argvars, 0);
- 
-     if (rettv_list_alloc(rettv) == FAIL || win == NULL)
-       return;
- 
-     cur = win->w_match_head;
-     while (cur != NULL)
-     {
-       dict = dict_alloc();
-       if (dict == NULL)
-           return;
-       if (cur->match.regprog == NULL)
-       {
-           /* match added with matchaddpos() */
-           for (i = 0; i < MAXPOSMATCH; ++i)
-           {
-               llpos_T *llpos;
-               char    buf[30];  // use 30 to avoid compiler warning
-               list_T  *l;
- 
-               llpos = &cur->pos.pos[i];
-               if (llpos->lnum == 0)
-                   break;
-               l = list_alloc();
-               if (l == NULL)
-                   break;
-               list_append_number(l, (varnumber_T)llpos->lnum);
-               if (llpos->col > 0)
-               {
-                   list_append_number(l, (varnumber_T)llpos->col);
-                   list_append_number(l, (varnumber_T)llpos->len);
-               }
-               sprintf(buf, "pos%d", i + 1);
-               dict_add_list(dict, buf, l);
-           }
-       }
-       else
-       {
-           dict_add_string(dict, "pattern", cur->pattern);
-       }
-       dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
-       dict_add_number(dict, "priority", (long)cur->priority);
-       dict_add_number(dict, "id", (long)cur->id);
- # if defined(FEAT_CONCEAL)
-       if (cur->conceal_char)
-       {
-           char_u buf[MB_MAXBYTES + 1];
- 
-           buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
-           dict_add_string(dict, "conceal", (char_u *)&buf);
-       }
- # endif
-       list_append_dict(rettv->vval.v_list, dict);
-       cur = cur->next;
-     }
- #endif
- }
- 
- /*
   * "getpid()" function
   */
      static void
--- 5274,5279 ----
***************
*** 7385,7439 ****
  }
  
  /*
-  * "js_decode()" function
-  */
-     static void
- f_js_decode(typval_T *argvars, typval_T *rettv)
- {
-     js_read_T reader;
- 
-     reader.js_buf = tv_get_string(&argvars[0]);
-     reader.js_fill = NULL;
-     reader.js_used = 0;
-     if (json_decode_all(&reader, rettv, JSON_JS) != OK)
-       emsg(_(e_invarg));
- }
- 
- /*
-  * "js_encode()" function
-  */
-     static void
- f_js_encode(typval_T *argvars, typval_T *rettv)
- {
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = json_encode(&argvars[0], JSON_JS);
- }
- 
- /*
-  * "json_decode()" function
-  */
-     static void
- f_json_decode(typval_T *argvars, typval_T *rettv)
- {
-     js_read_T reader;
- 
-     reader.js_buf = tv_get_string(&argvars[0]);
-     reader.js_fill = NULL;
-     reader.js_used = 0;
-     json_decode_all(&reader, rettv, 0);
- }
- 
- /*
-  * "json_encode()" function
-  */
-     static void
- f_json_encode(typval_T *argvars, typval_T *rettv)
- {
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = json_encode(&argvars[0], 0);
- }
- 
- /*
   * "keys()" function
   */
      static void
--- 7306,7311 ----
***************
*** 8071,8255 ****
      find_some_match(argvars, rettv, MATCH_MATCH);
  }
  
- #ifdef FEAT_SEARCH_EXTRA
-     static int
- matchadd_dict_arg(typval_T *tv, char_u **conceal_char, win_T **win)
- {
-     dictitem_T *di;
- 
-     if (tv->v_type != VAR_DICT)
-     {
-       emsg(_(e_dictreq));
-       return FAIL;
-     }
- 
-     if (dict_find(tv->vval.v_dict, (char_u *)"conceal", -1) != NULL)
-       *conceal_char = dict_get_string(tv->vval.v_dict,
-                                                  (char_u *)"conceal", FALSE);
- 
-     if ((di = dict_find(tv->vval.v_dict, (char_u *)"window", -1)) != NULL)
-     {
-       *win = find_win_by_nr_or_id(&di->di_tv);
-       if (*win == NULL)
-       {
-           emsg(_(e_invalwindow));
-           return FAIL;
-       }
-     }
- 
-     return OK;
- }
- #endif
- 
- /*
-  * "matchadd()" function
-  */
-     static void
- f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_SEARCH_EXTRA
-     char_u    buf[NUMBUFLEN];
-     char_u    *grp = tv_get_string_buf_chk(&argvars[0], buf); /* group */
-     char_u    *pat = tv_get_string_buf_chk(&argvars[1], buf); /* pattern */
-     int               prio = 10;      /* default priority */
-     int               id = -1;
-     int               error = FALSE;
-     char_u    *conceal_char = NULL;
-     win_T     *win = curwin;
- 
-     rettv->vval.v_number = -1;
- 
-     if (grp == NULL || pat == NULL)
-       return;
-     if (argvars[2].v_type != VAR_UNKNOWN)
-     {
-       prio = (int)tv_get_number_chk(&argvars[2], &error);
-       if (argvars[3].v_type != VAR_UNKNOWN)
-       {
-           id = (int)tv_get_number_chk(&argvars[3], &error);
-           if (argvars[4].v_type != VAR_UNKNOWN
-               && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL)
-               return;
-       }
-     }
-     if (error == TRUE)
-       return;
-     if (id >= 1 && id <= 3)
-     {
-       semsg(_("E798: ID is reserved for \":match\": %d"), id);
-       return;
-     }
- 
-     rettv->vval.v_number = match_add(win, grp, pat, prio, id, NULL,
-                                                               conceal_char);
- #endif
- }
- 
- /*
-  * "matchaddpos()" function
-  */
-     static void
- f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_SEARCH_EXTRA
-     char_u    buf[NUMBUFLEN];
-     char_u    *group;
-     int               prio = 10;
-     int               id = -1;
-     int               error = FALSE;
-     list_T    *l;
-     char_u    *conceal_char = NULL;
-     win_T     *win = curwin;
- 
-     rettv->vval.v_number = -1;
- 
-     group = tv_get_string_buf_chk(&argvars[0], buf);
-     if (group == NULL)
-       return;
- 
-     if (argvars[1].v_type != VAR_LIST)
-     {
-       semsg(_(e_listarg), "matchaddpos()");
-       return;
-     }
-     l = argvars[1].vval.v_list;
-     if (l == NULL)
-       return;
- 
-     if (argvars[2].v_type != VAR_UNKNOWN)
-     {
-       prio = (int)tv_get_number_chk(&argvars[2], &error);
-       if (argvars[3].v_type != VAR_UNKNOWN)
-       {
-           id = (int)tv_get_number_chk(&argvars[3], &error);
- 
-           if (argvars[4].v_type != VAR_UNKNOWN
-               && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL)
-               return;
-       }
-     }
-     if (error == TRUE)
-       return;
- 
-     /* id == 3 is ok because matchaddpos() is supposed to substitute :3match 
*/
-     if (id == 1 || id == 2)
-     {
-       semsg(_("E798: ID is reserved for \":match\": %d"), id);
-       return;
-     }
- 
-     rettv->vval.v_number = match_add(win, group, NULL, prio, id, l,
-                                                               conceal_char);
- #endif
- }
- 
- /*
-  * "matcharg()" function
-  */
-     static void
- f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     if (rettv_list_alloc(rettv) == OK)
-     {
- #ifdef FEAT_SEARCH_EXTRA
-       int         id = (int)tv_get_number(&argvars[0]);
-       matchitem_T *m;
- 
-       if (id >= 1 && id <= 3)
-       {
-           if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
-           {
-               list_append_string(rettv->vval.v_list,
-                                               syn_id2name(m->hlg_id), -1);
-               list_append_string(rettv->vval.v_list, m->pattern, -1);
-           }
-           else
-           {
-               list_append_string(rettv->vval.v_list, NULL, -1);
-               list_append_string(rettv->vval.v_list, NULL, -1);
-           }
-       }
- #endif
-     }
- }
- 
- /*
-  * "matchdelete()" function
-  */
-     static void
- f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
- {
- #ifdef FEAT_SEARCH_EXTRA
-     win_T   *win = get_optional_window(argvars, 1);
- 
-     if (win == NULL)
-       rettv->vval.v_number = -1;
-     else
-       rettv->vval.v_number = match_delete(win,
-                                      (int)tv_get_number(&argvars[0]), TRUE);
- #endif
- }
- 
  /*
   * "matchend()" function
   */
--- 7943,7948 ----
*** ../vim-8.1.1733/src/proto/evalfunc.pro      2019-06-29 07:56:26.042876840 
+0200
--- src/proto/evalfunc.pro      2019-07-22 22:32:35.018842500 +0200
***************
*** 7,12 ****
--- 7,13 ----
  buf_T *buflist_find_by_name(char_u *name, int curtab_only);
  buf_T *tv_get_buf(typval_T *tv, int curtab_only);
  buf_T *get_buf_arg(typval_T *arg);
+ win_T *get_optional_window(typval_T *argvars, int idx);
  void execute_redir_str(char_u *value, int value_len);
  void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
  float_T vim_round(float_T f);
*** ../vim-8.1.1733/src/json.c  2019-05-27 20:01:38.117491996 +0200
--- src/json.c  2019-07-22 22:16:18.643827525 +0200
***************
*** 1127,1129 ****
--- 1127,1178 ----
      return ret;
  }
  #endif
+ 
+ /*
+  * "js_decode()" function
+  */
+     void
+ f_js_decode(typval_T *argvars, typval_T *rettv)
+ {
+     js_read_T reader;
+ 
+     reader.js_buf = tv_get_string(&argvars[0]);
+     reader.js_fill = NULL;
+     reader.js_used = 0;
+     if (json_decode_all(&reader, rettv, JSON_JS) != OK)
+       emsg(_(e_invarg));
+ }
+ 
+ /*
+  * "js_encode()" function
+  */
+     void
+ f_js_encode(typval_T *argvars, typval_T *rettv)
+ {
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = json_encode(&argvars[0], JSON_JS);
+ }
+ 
+ /*
+  * "json_decode()" function
+  */
+     void
+ f_json_decode(typval_T *argvars, typval_T *rettv)
+ {
+     js_read_T reader;
+ 
+     reader.js_buf = tv_get_string(&argvars[0]);
+     reader.js_fill = NULL;
+     reader.js_used = 0;
+     json_decode_all(&reader, rettv, 0);
+ }
+ 
+ /*
+  * "json_encode()" function
+  */
+     void
+ f_json_encode(typval_T *argvars, typval_T *rettv)
+ {
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = json_encode(&argvars[0], 0);
+ }
*** ../vim-8.1.1733/src/proto/json.pro  2018-05-17 13:52:41.000000000 +0200
--- src/proto/json.pro  2019-07-22 22:17:19.803453591 +0200
***************
*** 4,7 ****
--- 4,11 ----
  int json_decode_all(js_read_T *reader, typval_T *res, int options);
  int json_decode(js_read_T *reader, typval_T *res, int options);
  int json_find_end(js_read_T *reader, int options);
+ void f_js_decode(typval_T *argvars, typval_T *rettv);
+ void f_js_encode(typval_T *argvars, typval_T *rettv);
+ void f_json_decode(typval_T *argvars, typval_T *rettv);
+ void f_json_encode(typval_T *argvars, typval_T *rettv);
  /* vim: set ft=c : */
*** ../vim-8.1.1733/src/window.c        2019-06-30 22:16:06.931821750 +0200
--- src/window.c        2019-07-22 22:22:56.545521038 +0200
***************
*** 4589,4595 ****
        redraw_later(VALID);    /* causes status line redraw */
  
      /* set window height to desired minimal value */
!     if (curwin->w_height < p_wh && !curwin->w_p_wfh)
        win_setheight((int)p_wh);
      else if (curwin->w_height == 0)
        win_setheight(1);
--- 4589,4599 ----
        redraw_later(VALID);    /* causes status line redraw */
  
      /* set window height to desired minimal value */
!     if (curwin->w_height < p_wh && !curwin->w_p_wfh
! #ifdef FEAT_TEXT_PROP
!           && !popup_is_popup(curwin)
! #endif
!           )
        win_setheight((int)p_wh);
      else if (curwin->w_height == 0)
        win_setheight(1);
***************
*** 6669,6968 ****
  }
  #endif
  
- #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
- /*
-  * Add match to the match list of window 'wp'.  The pattern 'pat' will be
-  * highlighted with the group 'grp' with priority 'prio'.
-  * Optionally, a desired ID 'id' can be specified (greater than or equal to 
1).
-  * If no particular ID is desired, -1 must be specified for 'id'.
-  * Return ID of added match, -1 on failure.
-  */
-     int
- match_add(
-     win_T     *wp,
-     char_u    *grp,
-     char_u    *pat,
-     int               prio,
-     int               id,
-     list_T    *pos_list,
-     char_u      *conceal_char UNUSED) /* pointer to conceal replacement char 
*/
- {
-     matchitem_T       *cur;
-     matchitem_T       *prev;
-     matchitem_T       *m;
-     int               hlg_id;
-     regprog_T *regprog = NULL;
-     int               rtype = SOME_VALID;
- 
-     if (*grp == NUL || (pat != NULL && *pat == NUL))
-       return -1;
-     if (id < -1 || id == 0)
-     {
-       semsg(_("E799: Invalid ID: %d (must be greater than or equal to 1)"), 
id);
-       return -1;
-     }
-     if (id != -1)
-     {
-       cur = wp->w_match_head;
-       while (cur != NULL)
-       {
-           if (cur->id == id)
-           {
-               semsg(_("E801: ID already taken: %d"), id);
-               return -1;
-           }
-           cur = cur->next;
-       }
-     }
-     if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
-     {
-       semsg(_(e_nogroup), grp);
-       return -1;
-     }
-     if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
-     {
-       semsg(_(e_invarg2), pat);
-       return -1;
-     }
- 
-     /* Find available match ID. */
-     while (id == -1)
-     {
-       cur = wp->w_match_head;
-       while (cur != NULL && cur->id != wp->w_next_match_id)
-           cur = cur->next;
-       if (cur == NULL)
-           id = wp->w_next_match_id;
-       wp->w_next_match_id++;
-     }
- 
-     /* Build new match. */
-     m = ALLOC_CLEAR_ONE(matchitem_T);
-     m->id = id;
-     m->priority = prio;
-     m->pattern = pat == NULL ? NULL : vim_strsave(pat);
-     m->hlg_id = hlg_id;
-     m->match.regprog = regprog;
-     m->match.rmm_ic = FALSE;
-     m->match.rmm_maxcol = 0;
- # if defined(FEAT_CONCEAL)
-     m->conceal_char = 0;
-     if (conceal_char != NULL)
-       m->conceal_char = (*mb_ptr2char)(conceal_char);
- # endif
- 
-     /* Set up position matches */
-     if (pos_list != NULL)
-     {
-       linenr_T        toplnum = 0;
-       linenr_T        botlnum = 0;
-       listitem_T      *li;
-       int             i;
- 
-       for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
-                                                       i++, li = li->li_next)
-       {
-           linenr_T    lnum = 0;
-           colnr_T     col = 0;
-           int         len = 1;
-           list_T      *subl;
-           listitem_T  *subli;
-           int         error = FALSE;
- 
-           if (li->li_tv.v_type == VAR_LIST)
-           {
-               subl = li->li_tv.vval.v_list;
-               if (subl == NULL)
-                   goto fail;
-               subli = subl->lv_first;
-               if (subli == NULL)
-                   goto fail;
-               lnum = tv_get_number_chk(&subli->li_tv, &error);
-               if (error == TRUE)
-                   goto fail;
-               if (lnum == 0)
-               {
-                   --i;
-                   continue;
-               }
-               m->pos.pos[i].lnum = lnum;
-               subli = subli->li_next;
-               if (subli != NULL)
-               {
-                   col = tv_get_number_chk(&subli->li_tv, &error);
-                   if (error == TRUE)
-                       goto fail;
-                   subli = subli->li_next;
-                   if (subli != NULL)
-                   {
-                       len = tv_get_number_chk(&subli->li_tv, &error);
-                       if (error == TRUE)
-                           goto fail;
-                   }
-               }
-               m->pos.pos[i].col = col;
-               m->pos.pos[i].len = len;
-           }
-           else if (li->li_tv.v_type == VAR_NUMBER)
-           {
-               if (li->li_tv.vval.v_number == 0)
-               {
-                   --i;
-                   continue;
-               }
-               m->pos.pos[i].lnum = li->li_tv.vval.v_number;
-               m->pos.pos[i].col = 0;
-               m->pos.pos[i].len = 0;
-           }
-           else
-           {
-               emsg(_("List or number required"));
-               goto fail;
-           }
-           if (toplnum == 0 || lnum < toplnum)
-               toplnum = lnum;
-           if (botlnum == 0 || lnum >= botlnum)
-               botlnum = lnum + 1;
-       }
- 
-       /* Calculate top and bottom lines for redrawing area */
-       if (toplnum != 0)
-       {
-           if (wp->w_buffer->b_mod_set)
-           {
-               if (wp->w_buffer->b_mod_top > toplnum)
-                   wp->w_buffer->b_mod_top = toplnum;
-               if (wp->w_buffer->b_mod_bot < botlnum)
-                   wp->w_buffer->b_mod_bot = botlnum;
-           }
-           else
-           {
-               wp->w_buffer->b_mod_set = TRUE;
-               wp->w_buffer->b_mod_top = toplnum;
-               wp->w_buffer->b_mod_bot = botlnum;
-               wp->w_buffer->b_mod_xlines = 0;
-           }
-           m->pos.toplnum = toplnum;
-           m->pos.botlnum = botlnum;
-           rtype = VALID;
-       }
-     }
- 
-     /* Insert new match.  The match list is in ascending order with regard to
-      * the match priorities. */
-     cur = wp->w_match_head;
-     prev = cur;
-     while (cur != NULL && prio >= cur->priority)
-     {
-       prev = cur;
-       cur = cur->next;
-     }
-     if (cur == prev)
-       wp->w_match_head = m;
-     else
-       prev->next = m;
-     m->next = cur;
- 
-     redraw_later(rtype);
-     return id;
- 
- fail:
-     vim_free(m);
-     return -1;
- }
- 
- /*
-  * Delete match with ID 'id' in the match list of window 'wp'.
-  * Print error messages if 'perr' is TRUE.
-  */
-     int
- match_delete(win_T *wp, int id, int perr)
- {
-     matchitem_T       *cur = wp->w_match_head;
-     matchitem_T       *prev = cur;
-     int               rtype = SOME_VALID;
- 
-     if (id < 1)
-     {
-       if (perr == TRUE)
-           semsg(_("E802: Invalid ID: %d (must be greater than or equal to 
1)"),
-                                                                         id);
-       return -1;
-     }
-     while (cur != NULL && cur->id != id)
-     {
-       prev = cur;
-       cur = cur->next;
-     }
-     if (cur == NULL)
-     {
-       if (perr == TRUE)
-           semsg(_("E803: ID not found: %d"), id);
-       return -1;
-     }
-     if (cur == prev)
-       wp->w_match_head = cur->next;
-     else
-       prev->next = cur->next;
-     vim_regfree(cur->match.regprog);
-     vim_free(cur->pattern);
-     if (cur->pos.toplnum != 0)
-     {
-       if (wp->w_buffer->b_mod_set)
-       {
-           if (wp->w_buffer->b_mod_top > cur->pos.toplnum)
-               wp->w_buffer->b_mod_top = cur->pos.toplnum;
-           if (wp->w_buffer->b_mod_bot < cur->pos.botlnum)
-               wp->w_buffer->b_mod_bot = cur->pos.botlnum;
-       }
-       else
-       {
-           wp->w_buffer->b_mod_set = TRUE;
-           wp->w_buffer->b_mod_top = cur->pos.toplnum;
-           wp->w_buffer->b_mod_bot = cur->pos.botlnum;
-           wp->w_buffer->b_mod_xlines = 0;
-       }
-       rtype = VALID;
-     }
-     vim_free(cur);
-     redraw_later(rtype);
-     return 0;
- }
- 
- /*
-  * Delete all matches in the match list of window 'wp'.
-  */
-     void
- clear_matches(win_T *wp)
- {
-     matchitem_T *m;
- 
-     while (wp->w_match_head != NULL)
-     {
-       m = wp->w_match_head->next;
-       vim_regfree(wp->w_match_head->match.regprog);
-       vim_free(wp->w_match_head->pattern);
-       vim_free(wp->w_match_head);
-       wp->w_match_head = m;
-     }
-     redraw_later(SOME_VALID);
- }
- 
- /*
-  * Get match from ID 'id' in window 'wp'.
-  * Return NULL if match not found.
-  */
-     matchitem_T *
- get_match(win_T *wp, int id)
- {
-     matchitem_T *cur = wp->w_match_head;
- 
-     while (cur != NULL && cur->id != id)
-       cur = cur->next;
-     return cur;
- }
- #endif
- 
  #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
      int
  get_win_number(win_T *wp, win_T *first_win)
--- 6673,6678 ----
*** ../vim-8.1.1733/src/proto/window.pro        2019-06-13 23:59:46.788290732 
+0200
--- src/proto/window.pro        2019-07-22 22:27:12.684427335 +0200
***************
*** 84,93 ****
  void switch_buffer(bufref_T *save_curbuf, buf_T *buf);
  void restore_buffer(bufref_T *save_curbuf);
  int win_hasvertsplit(void);
- int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T 
*pos_list, char_u *conceal_char);
- int match_delete(win_T *wp, int id, int perr);
- void clear_matches(win_T *wp);
- matchitem_T *get_match(win_T *wp, int id);
  int get_win_number(win_T *wp, win_T *first_win);
  int get_tab_number(tabpage_T *tp);
  int win_getid(typval_T *argvars);
--- 84,89 ----
*** ../vim-8.1.1733/src/highlight.c     2019-07-15 22:40:19.061741740 +0200
--- src/highlight.c     2019-07-22 22:33:59.650401624 +0200
***************
*** 8,14 ****
   */
  
  /*
!  * Highlighting stuff
   */
  
  #include "vim.h"
--- 8,15 ----
   */
  
  /*
!  * Highlighting stuff.
!  * Includes highlighting matches.
   */
  
  #include "vim.h"
***************
*** 3653,3655 ****
--- 3654,4196 ----
  # endif
  }
  #endif
+ 
+ 
+ #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
+ /*
+  * Add match to the match list of window 'wp'.  The pattern 'pat' will be
+  * highlighted with the group 'grp' with priority 'prio'.
+  * Optionally, a desired ID 'id' can be specified (greater than or equal to 
1).
+  * If no particular ID is desired, -1 must be specified for 'id'.
+  * Return ID of added match, -1 on failure.
+  */
+     int
+ match_add(
+     win_T     *wp,
+     char_u    *grp,
+     char_u    *pat,
+     int               prio,
+     int               id,
+     list_T    *pos_list,
+     char_u      *conceal_char UNUSED) /* pointer to conceal replacement char 
*/
+ {
+     matchitem_T       *cur;
+     matchitem_T       *prev;
+     matchitem_T       *m;
+     int               hlg_id;
+     regprog_T *regprog = NULL;
+     int               rtype = SOME_VALID;
+ 
+     if (*grp == NUL || (pat != NULL && *pat == NUL))
+       return -1;
+     if (id < -1 || id == 0)
+     {
+       semsg(_("E799: Invalid ID: %d (must be greater than or equal to 1)"), 
id);
+       return -1;
+     }
+     if (id != -1)
+     {
+       cur = wp->w_match_head;
+       while (cur != NULL)
+       {
+           if (cur->id == id)
+           {
+               semsg(_("E801: ID already taken: %d"), id);
+               return -1;
+           }
+           cur = cur->next;
+       }
+     }
+     if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
+     {
+       semsg(_(e_nogroup), grp);
+       return -1;
+     }
+     if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
+     {
+       semsg(_(e_invarg2), pat);
+       return -1;
+     }
+ 
+     /* Find available match ID. */
+     while (id == -1)
+     {
+       cur = wp->w_match_head;
+       while (cur != NULL && cur->id != wp->w_next_match_id)
+           cur = cur->next;
+       if (cur == NULL)
+           id = wp->w_next_match_id;
+       wp->w_next_match_id++;
+     }
+ 
+     /* Build new match. */
+     m = ALLOC_CLEAR_ONE(matchitem_T);
+     m->id = id;
+     m->priority = prio;
+     m->pattern = pat == NULL ? NULL : vim_strsave(pat);
+     m->hlg_id = hlg_id;
+     m->match.regprog = regprog;
+     m->match.rmm_ic = FALSE;
+     m->match.rmm_maxcol = 0;
+ # if defined(FEAT_CONCEAL)
+     m->conceal_char = 0;
+     if (conceal_char != NULL)
+       m->conceal_char = (*mb_ptr2char)(conceal_char);
+ # endif
+ 
+     /* Set up position matches */
+     if (pos_list != NULL)
+     {
+       linenr_T        toplnum = 0;
+       linenr_T        botlnum = 0;
+       listitem_T      *li;
+       int             i;
+ 
+       for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
+                                                       i++, li = li->li_next)
+       {
+           linenr_T    lnum = 0;
+           colnr_T     col = 0;
+           int         len = 1;
+           list_T      *subl;
+           listitem_T  *subli;
+           int         error = FALSE;
+ 
+           if (li->li_tv.v_type == VAR_LIST)
+           {
+               subl = li->li_tv.vval.v_list;
+               if (subl == NULL)
+                   goto fail;
+               subli = subl->lv_first;
+               if (subli == NULL)
+                   goto fail;
+               lnum = tv_get_number_chk(&subli->li_tv, &error);
+               if (error == TRUE)
+                   goto fail;
+               if (lnum == 0)
+               {
+                   --i;
+                   continue;
+               }
+               m->pos.pos[i].lnum = lnum;
+               subli = subli->li_next;
+               if (subli != NULL)
+               {
+                   col = tv_get_number_chk(&subli->li_tv, &error);
+                   if (error == TRUE)
+                       goto fail;
+                   subli = subli->li_next;
+                   if (subli != NULL)
+                   {
+                       len = tv_get_number_chk(&subli->li_tv, &error);
+                       if (error == TRUE)
+                           goto fail;
+                   }
+               }
+               m->pos.pos[i].col = col;
+               m->pos.pos[i].len = len;
+           }
+           else if (li->li_tv.v_type == VAR_NUMBER)
+           {
+               if (li->li_tv.vval.v_number == 0)
+               {
+                   --i;
+                   continue;
+               }
+               m->pos.pos[i].lnum = li->li_tv.vval.v_number;
+               m->pos.pos[i].col = 0;
+               m->pos.pos[i].len = 0;
+           }
+           else
+           {
+               emsg(_("List or number required"));
+               goto fail;
+           }
+           if (toplnum == 0 || lnum < toplnum)
+               toplnum = lnum;
+           if (botlnum == 0 || lnum >= botlnum)
+               botlnum = lnum + 1;
+       }
+ 
+       /* Calculate top and bottom lines for redrawing area */
+       if (toplnum != 0)
+       {
+           if (wp->w_buffer->b_mod_set)
+           {
+               if (wp->w_buffer->b_mod_top > toplnum)
+                   wp->w_buffer->b_mod_top = toplnum;
+               if (wp->w_buffer->b_mod_bot < botlnum)
+                   wp->w_buffer->b_mod_bot = botlnum;
+           }
+           else
+           {
+               wp->w_buffer->b_mod_set = TRUE;
+               wp->w_buffer->b_mod_top = toplnum;
+               wp->w_buffer->b_mod_bot = botlnum;
+               wp->w_buffer->b_mod_xlines = 0;
+           }
+           m->pos.toplnum = toplnum;
+           m->pos.botlnum = botlnum;
+           rtype = VALID;
+       }
+     }
+ 
+     /* Insert new match.  The match list is in ascending order with regard to
+      * the match priorities. */
+     cur = wp->w_match_head;
+     prev = cur;
+     while (cur != NULL && prio >= cur->priority)
+     {
+       prev = cur;
+       cur = cur->next;
+     }
+     if (cur == prev)
+       wp->w_match_head = m;
+     else
+       prev->next = m;
+     m->next = cur;
+ 
+     redraw_later(rtype);
+     return id;
+ 
+ fail:
+     vim_free(m);
+     return -1;
+ }
+ 
+ /*
+  * Delete match with ID 'id' in the match list of window 'wp'.
+  * Print error messages if 'perr' is TRUE.
+  */
+     int
+ match_delete(win_T *wp, int id, int perr)
+ {
+     matchitem_T       *cur = wp->w_match_head;
+     matchitem_T       *prev = cur;
+     int               rtype = SOME_VALID;
+ 
+     if (id < 1)
+     {
+       if (perr == TRUE)
+           semsg(_("E802: Invalid ID: %d (must be greater than or equal to 
1)"),
+                                                                         id);
+       return -1;
+     }
+     while (cur != NULL && cur->id != id)
+     {
+       prev = cur;
+       cur = cur->next;
+     }
+     if (cur == NULL)
+     {
+       if (perr == TRUE)
+           semsg(_("E803: ID not found: %d"), id);
+       return -1;
+     }
+     if (cur == prev)
+       wp->w_match_head = cur->next;
+     else
+       prev->next = cur->next;
+     vim_regfree(cur->match.regprog);
+     vim_free(cur->pattern);
+     if (cur->pos.toplnum != 0)
+     {
+       if (wp->w_buffer->b_mod_set)
+       {
+           if (wp->w_buffer->b_mod_top > cur->pos.toplnum)
+               wp->w_buffer->b_mod_top = cur->pos.toplnum;
+           if (wp->w_buffer->b_mod_bot < cur->pos.botlnum)
+               wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+       }
+       else
+       {
+           wp->w_buffer->b_mod_set = TRUE;
+           wp->w_buffer->b_mod_top = cur->pos.toplnum;
+           wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+           wp->w_buffer->b_mod_xlines = 0;
+       }
+       rtype = VALID;
+     }
+     vim_free(cur);
+     redraw_later(rtype);
+     return 0;
+ }
+ 
+ /*
+  * Delete all matches in the match list of window 'wp'.
+  */
+     void
+ clear_matches(win_T *wp)
+ {
+     matchitem_T *m;
+ 
+     while (wp->w_match_head != NULL)
+     {
+       m = wp->w_match_head->next;
+       vim_regfree(wp->w_match_head->match.regprog);
+       vim_free(wp->w_match_head->pattern);
+       vim_free(wp->w_match_head);
+       wp->w_match_head = m;
+     }
+     redraw_later(SOME_VALID);
+ }
+ 
+ /*
+  * Get match from ID 'id' in window 'wp'.
+  * Return NULL if match not found.
+  */
+     matchitem_T *
+ get_match(win_T *wp, int id)
+ {
+     matchitem_T *cur = wp->w_match_head;
+ 
+     while (cur != NULL && cur->id != id)
+       cur = cur->next;
+     return cur;
+ }
+ 
+     static int
+ matchadd_dict_arg(typval_T *tv, char_u **conceal_char, win_T **win)
+ {
+     dictitem_T *di;
+ 
+     if (tv->v_type != VAR_DICT)
+     {
+       emsg(_(e_dictreq));
+       return FAIL;
+     }
+ 
+     if (dict_find(tv->vval.v_dict, (char_u *)"conceal", -1) != NULL)
+       *conceal_char = dict_get_string(tv->vval.v_dict,
+                                                  (char_u *)"conceal", FALSE);
+ 
+     if ((di = dict_find(tv->vval.v_dict, (char_u *)"window", -1)) != NULL)
+     {
+       *win = find_win_by_nr_or_id(&di->di_tv);
+       if (*win == NULL)
+       {
+           emsg(_(e_invalwindow));
+           return FAIL;
+       }
+     }
+ 
+     return OK;
+ }
+ #endif
+ 
+ /*
+  * "getmatches()" function
+  */
+     void
+ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+ {
+ #ifdef FEAT_SEARCH_EXTRA
+     dict_T    *dict;
+     matchitem_T       *cur;
+     int               i;
+     win_T     *win = get_optional_window(argvars, 0);
+ 
+     if (rettv_list_alloc(rettv) == FAIL || win == NULL)
+       return;
+ 
+     cur = win->w_match_head;
+     while (cur != NULL)
+     {
+       dict = dict_alloc();
+       if (dict == NULL)
+           return;
+       if (cur->match.regprog == NULL)
+       {
+           /* match added with matchaddpos() */
+           for (i = 0; i < MAXPOSMATCH; ++i)
+           {
+               llpos_T *llpos;
+               char    buf[30];  // use 30 to avoid compiler warning
+               list_T  *l;
+ 
+               llpos = &cur->pos.pos[i];
+               if (llpos->lnum == 0)
+                   break;
+               l = list_alloc();
+               if (l == NULL)
+                   break;
+               list_append_number(l, (varnumber_T)llpos->lnum);
+               if (llpos->col > 0)
+               {
+                   list_append_number(l, (varnumber_T)llpos->col);
+                   list_append_number(l, (varnumber_T)llpos->len);
+               }
+               sprintf(buf, "pos%d", i + 1);
+               dict_add_list(dict, buf, l);
+           }
+       }
+       else
+       {
+           dict_add_string(dict, "pattern", cur->pattern);
+       }
+       dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
+       dict_add_number(dict, "priority", (long)cur->priority);
+       dict_add_number(dict, "id", (long)cur->id);
+ # if defined(FEAT_CONCEAL)
+       if (cur->conceal_char)
+       {
+           char_u buf[MB_MAXBYTES + 1];
+ 
+           buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
+           dict_add_string(dict, "conceal", (char_u *)&buf);
+       }
+ # endif
+       list_append_dict(rettv->vval.v_list, dict);
+       cur = cur->next;
+     }
+ #endif
+ }
+ 
+ /*
+  * "matchadd()" function
+  */
+     void
+ f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+ {
+ #ifdef FEAT_SEARCH_EXTRA
+     char_u    buf[NUMBUFLEN];
+     char_u    *grp = tv_get_string_buf_chk(&argvars[0], buf); /* group */
+     char_u    *pat = tv_get_string_buf_chk(&argvars[1], buf); /* pattern */
+     int               prio = 10;      /* default priority */
+     int               id = -1;
+     int               error = FALSE;
+     char_u    *conceal_char = NULL;
+     win_T     *win = curwin;
+ 
+     rettv->vval.v_number = -1;
+ 
+     if (grp == NULL || pat == NULL)
+       return;
+     if (argvars[2].v_type != VAR_UNKNOWN)
+     {
+       prio = (int)tv_get_number_chk(&argvars[2], &error);
+       if (argvars[3].v_type != VAR_UNKNOWN)
+       {
+           id = (int)tv_get_number_chk(&argvars[3], &error);
+           if (argvars[4].v_type != VAR_UNKNOWN
+               && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL)
+               return;
+       }
+     }
+     if (error == TRUE)
+       return;
+     if (id >= 1 && id <= 3)
+     {
+       semsg(_("E798: ID is reserved for \":match\": %d"), id);
+       return;
+     }
+ 
+     rettv->vval.v_number = match_add(win, grp, pat, prio, id, NULL,
+                                                               conceal_char);
+ #endif
+ }
+ 
+ /*
+  * "matchaddpos()" function
+  */
+     void
+ f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+ {
+ #ifdef FEAT_SEARCH_EXTRA
+     char_u    buf[NUMBUFLEN];
+     char_u    *group;
+     int               prio = 10;
+     int               id = -1;
+     int               error = FALSE;
+     list_T    *l;
+     char_u    *conceal_char = NULL;
+     win_T     *win = curwin;
+ 
+     rettv->vval.v_number = -1;
+ 
+     group = tv_get_string_buf_chk(&argvars[0], buf);
+     if (group == NULL)
+       return;
+ 
+     if (argvars[1].v_type != VAR_LIST)
+     {
+       semsg(_(e_listarg), "matchaddpos()");
+       return;
+     }
+     l = argvars[1].vval.v_list;
+     if (l == NULL)
+       return;
+ 
+     if (argvars[2].v_type != VAR_UNKNOWN)
+     {
+       prio = (int)tv_get_number_chk(&argvars[2], &error);
+       if (argvars[3].v_type != VAR_UNKNOWN)
+       {
+           id = (int)tv_get_number_chk(&argvars[3], &error);
+ 
+           if (argvars[4].v_type != VAR_UNKNOWN
+               && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL)
+               return;
+       }
+     }
+     if (error == TRUE)
+       return;
+ 
+     /* id == 3 is ok because matchaddpos() is supposed to substitute :3match 
*/
+     if (id == 1 || id == 2)
+     {
+       semsg(_("E798: ID is reserved for \":match\": %d"), id);
+       return;
+     }
+ 
+     rettv->vval.v_number = match_add(win, group, NULL, prio, id, l,
+                                                               conceal_char);
+ #endif
+ }
+ 
+ /*
+  * "matcharg()" function
+  */
+     void
+ f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+     if (rettv_list_alloc(rettv) == OK)
+     {
+ #ifdef FEAT_SEARCH_EXTRA
+       int         id = (int)tv_get_number(&argvars[0]);
+       matchitem_T *m;
+ 
+       if (id >= 1 && id <= 3)
+       {
+           if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
+           {
+               list_append_string(rettv->vval.v_list,
+                                               syn_id2name(m->hlg_id), -1);
+               list_append_string(rettv->vval.v_list, m->pattern, -1);
+           }
+           else
+           {
+               list_append_string(rettv->vval.v_list, NULL, -1);
+               list_append_string(rettv->vval.v_list, NULL, -1);
+           }
+       }
+ #endif
+     }
+ }
+ 
+ /*
+  * "matchdelete()" function
+  */
+     void
+ f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+ {
+ #ifdef FEAT_SEARCH_EXTRA
+     win_T   *win = get_optional_window(argvars, 1);
+ 
+     if (win == NULL)
+       rettv->vval.v_number = -1;
+     else
+       rettv->vval.v_number = match_delete(win,
+                                      (int)tv_get_number(&argvars[0]), TRUE);
+ #endif
+ }
*** ../vim-8.1.1733/src/proto/highlight.pro     2019-07-15 22:40:19.061741740 
+0200
--- src/proto/highlight.pro     2019-07-22 22:34:09.478349929 +0200
***************
*** 43,46 ****
--- 43,55 ----
  char_u *get_highlight_name(expand_T *xp, int idx);
  char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
  void free_highlight_fonts(void);
+ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T 
*pos_list, char_u *conceal_char);
+ int match_delete(win_T *wp, int id, int perr);
+ void clear_matches(win_T *wp);
+ matchitem_T *get_match(win_T *wp, int id);
+ void f_getmatches(typval_T *argvars, typval_T *rettv);
+ void f_matchadd(typval_T *argvars, typval_T *rettv);
+ void f_matchaddpos(typval_T *argvars, typval_T *rettv);
+ void f_matcharg(typval_T *argvars, typval_T *rettv);
+ void f_matchdelete(typval_T *argvars, typval_T *rettv);
  /* vim: set ft=c : */
*** ../vim-8.1.1733/src/globals.h       2019-07-21 19:25:16.654609424 +0200
--- src/globals.h       2019-07-22 22:30:53.003362161 +0200
***************
*** 1615,1622 ****
  EXTERN char e_dirnotf[]       INIT(= N_("E919: Directory not found in '%s': 
\"%s\""));
  EXTERN char e_au_recursive[]  INIT(= N_("E952: Autocommand caused recursive 
behavior"));
  #ifdef FEAT_MENU
! EXTERN char e_menuothermode[] INIT(= N_("E328: Menu only exists in another 
mode"));
  #endif
  
  #ifdef FEAT_GUI_MAC
  EXTERN short disallow_gui     INIT(= FALSE);
--- 1615,1624 ----
  EXTERN char e_dirnotf[]       INIT(= N_("E919: Directory not found in '%s': 
\"%s\""));
  EXTERN char e_au_recursive[]  INIT(= N_("E952: Autocommand caused recursive 
behavior"));
  #ifdef FEAT_MENU
! EXTERN char e_menuothermode[] INIT(= N_("E328: Menu only exists in another 
mode"));
  #endif
+ EXTERN char e_invalwindow[]   INIT(= N_("E957: Invalid window number"));
+ EXTERN char e_listarg[]               INIT(= N_("E686: Argument of %s must be 
a List"));
  
  #ifdef FEAT_GUI_MAC
  EXTERN short disallow_gui     INIT(= FALSE);
*** ../vim-8.1.1733/src/version.c       2019-07-22 22:08:54.294523746 +0200
--- src/version.c       2019-07-22 23:03:05.686486480 +0200
***************
*** 779,780 ****
--- 779,782 ----
  {   /* Add new patch number below this line */
+ /**/
+     1734,
  /**/

-- 
System administrators are just like women: You can't live with them and you
can't live without them.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201907222104.x6ML4ESX008042%40masaka.moolenaar.net.

Raspunde prin e-mail lui