Patch 9.0.1300
Problem:    'statusline' only supports one "%=" item.
Solution:   Add support for multiple "%=" items. (TJ DeVries, Yegappan
            Lakshmanan, closes #11970, closes #11965)
Files:      runtime/doc/options.txt, src/buffer.c, src/option.h,
            src/optionstr.c, src/testdir/test_statusline.vim


*** ../vim-9.0.1299/runtime/doc/options.txt     2023-01-10 12:37:33.249580669 
+0000
--- runtime/doc/options.txt     2023-02-11 11:07:19.731036241 +0000
***************
*** 7725,7731 ****
              mark.  This information is used for mouse clicks.
        < -   Where to truncate line if too long.  Default is at the start.
              No width fields allowed.
!       = -   Separation point between left and right aligned items.
              No width fields allowed.
        # -   Set highlight group.  The name must follow and then a # again.
              Thus use %#HLname# for highlight group HLname.  The same
--- 7776,7785 ----
              mark.  This information is used for mouse clicks.
        < -   Where to truncate line if too long.  Default is at the start.
              No width fields allowed.
!       = -   Separation point between alignment sections.  Each section will
!             be separated by an equal number of spaces.  With one %= what
!             comes after it will be right-aligned.  With two %= there is a
!             middle part, with white space left and right of it.
              No width fields allowed.
        # -   Set highlight group.  The name must follow and then a # again.
              Thus use %#HLname# for highlight group HLname.  The same
*** ../vim-9.0.1299/src/buffer.c        2023-01-09 19:04:19.296528376 +0000
--- src/buffer.c        2023-02-11 11:11:55.435104406 +0000
***************
*** 4179,4185 ****
        Normal,
        Empty,
        Group,
!       Middle,
        Highlight,
        TabPage,
        Trunc
--- 4179,4185 ----
        Normal,
        Empty,
        Group,
!       Separate,
        Highlight,
        TabPage,
        Trunc
***************
*** 4191,4196 ****
--- 4191,4197 ----
  static int           *stl_groupitem = NULL;
  static stl_hlrec_T     *stl_hltab = NULL;
  static stl_hlrec_T     *stl_tabtab = NULL;
+ static int            *stl_separator_locations = NULL;
  
  /*
   * Build a string from the status line items in "fmt".
***************
*** 4200,4206 ****
   * is "curwin".
   *
   * Items are drawn interspersed with the text that surrounds it
!  * Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
   * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
   *
   * If maxwidth is not zero, the string will be filled at any middle marker
--- 4201,4207 ----
   * is "curwin".
   *
   * Items are drawn interspersed with the text that surrounds it
!  * Specials: %-<wid>(xxx%) => group, %= => separation marker, %< => truncation
   * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
   *
   * If maxwidth is not zero, the string will be filled at any middle marker
***************
*** 4282,4287 ****
--- 4283,4290 ----
        // end of the list.
        stl_hltab  = ALLOC_MULT(stl_hlrec_T, stl_items_len + 1);
        stl_tabtab = ALLOC_MULT(stl_hlrec_T, stl_items_len + 1);
+ 
+       stl_separator_locations = ALLOC_MULT(int, stl_items_len);
      }
  
  #ifdef FEAT_EVAL
***************
*** 4350,4368 ****
        if (curitem == (int)stl_items_len)
        {
            size_t      new_len = stl_items_len * 3 / 2;
-           stl_item_T  *new_items;
-           int         *new_groupitem;
-           stl_hlrec_T *new_hlrec;
  
!           new_items = vim_realloc(stl_items, sizeof(stl_item_T) * new_len);
            if (new_items == NULL)
                break;
            stl_items = new_items;
!           new_groupitem = vim_realloc(stl_groupitem, sizeof(int) * new_len);
            if (new_groupitem == NULL)
                break;
            stl_groupitem = new_groupitem;
!           new_hlrec = vim_realloc(stl_hltab,
                                          sizeof(stl_hlrec_T) * (new_len + 1));
            if (new_hlrec == NULL)
                break;
--- 4353,4372 ----
        if (curitem == (int)stl_items_len)
        {
            size_t      new_len = stl_items_len * 3 / 2;
  
!           stl_item_T *new_items =
!                         vim_realloc(stl_items, sizeof(stl_item_T) * new_len);
            if (new_items == NULL)
                break;
            stl_items = new_items;
! 
!           int *new_groupitem =
!                            vim_realloc(stl_groupitem, sizeof(int) * new_len);
            if (new_groupitem == NULL)
                break;
            stl_groupitem = new_groupitem;
! 
!           stl_hlrec_T *new_hlrec = vim_realloc(stl_hltab,
                                          sizeof(stl_hlrec_T) * (new_len + 1));
            if (new_hlrec == NULL)
                break;
***************
*** 4372,4377 ****
--- 4376,4388 ----
            if (new_hlrec == NULL)
                break;
            stl_tabtab = new_hlrec;
+ 
+           int *new_separator_locs = vim_realloc(stl_separator_locations,
+                                           sizeof(int) * new_len);
+           if (new_separator_locs == NULL)
+               break;
+           stl_separator_locations = new_separator_locs;;
+ 
            stl_items_len = new_len;
        }
  
***************
*** 4400,4411 ****
            prevchar_isflag = prevchar_isitem = FALSE;
            continue;
        }
!       if (*s == STL_MIDDLEMARK)
        {
            s++;
            if (groupdepth > 0)
                continue;
!           stl_items[curitem].stl_type = Middle;
            stl_items[curitem++].stl_start = p;
            continue;
        }
--- 4411,4423 ----
            prevchar_isflag = prevchar_isitem = FALSE;
            continue;
        }
!       // STL_SEPARATE: Separation between items, filled with white space.
!       if (*s == STL_SEPARATE)
        {
            s++;
            if (groupdepth > 0)
                continue;
!           stl_items[curitem].stl_type = Separate;
            stl_items[curitem++].stl_start = p;
            continue;
        }
***************
*** 5121,5139 ****
      }
      else if (width < maxwidth && STRLEN(out) + maxwidth - width + 1 < outlen)
      {
!       // Apply STL_MIDDLE if any
        for (l = 0; l < itemcnt; l++)
-           if (stl_items[l].stl_type == Middle)
-               break;
-       if (l < itemcnt)
        {
!           int middlelength = (maxwidth - width) * MB_CHAR2LEN(fillchar);
!           p = stl_items[l].stl_start + middlelength;
!           STRMOVE(p, stl_items[l].stl_start);
!           for (s = stl_items[l].stl_start; s < p;)
!               MB_CHAR2BYTES(fillchar, s);
!           for (l++; l < itemcnt; l++)
!               stl_items[l].stl_start += middlelength;
            width = maxwidth;
        }
      }
--- 5133,5177 ----
      }
      else if (width < maxwidth && STRLEN(out) + maxwidth - width + 1 < outlen)
      {
!       // Find how many separators there are, which we will use when
!       // figuring out how many groups there are.
!       int num_separators = 0;
! 
        for (l = 0; l < itemcnt; l++)
        {
!           if (stl_items[l].stl_type == Separate)
!           {
!               // Create an array of the start location for each separator
!               // mark.
!               stl_separator_locations[num_separators] = l;
!               num_separators++;
!           }
!       }
! 
!       // If we have separated groups, then we deal with it now
!       if (num_separators)
!       {
!           int standard_spaces;
!           int final_spaces;
! 
!           standard_spaces = (maxwidth - width) / num_separators;
!           final_spaces = (maxwidth - width) -
!                                       standard_spaces * (num_separators - 1);
!           for (l = 0; l < num_separators; l++)
!           {
!               int dislocation = (l == (num_separators - 1)) ?
!                                       final_spaces : standard_spaces;
!               dislocation *= MB_CHAR2LEN(fillchar);
!               char_u *start = stl_items[stl_separator_locations[l]].stl_start;
!               char_u *seploc = start + dislocation;
!               STRMOVE(seploc, start);
!               for (s = start; s < seploc;)
!                   MB_CHAR2BYTES(fillchar, s);
! 
!               for (int i = stl_separator_locations[l] + 1; i < itemcnt; i++)
!                   stl_items[i].stl_start += dislocation;
!           }
! 
            width = maxwidth;
        }
      }
*** ../vim-9.0.1299/src/option.h        2022-12-16 16:41:19.208714806 +0000
--- src/option.h        2023-02-11 10:57:54.547153067 +0000
***************
*** 347,353 ****
  #define STL_PAGENUM   'N'             // page number (when printing)
  #define STL_SHOWCMD   'S'             // 'showcmd' buffer
  #define STL_VIM_EXPR  '{'             // start of expression to substitute
! #define STL_MIDDLEMARK        '='             // separation between left and 
right
  #define STL_TRUNCMARK '<'             // truncation mark if line is too long
  #define STL_USER_HL   '*'             // highlight from (User)1..9 or 0
  #define STL_HIGHLIGHT '#'             // highlight name
--- 347,354 ----
  #define STL_PAGENUM   'N'             // page number (when printing)
  #define STL_SHOWCMD   'S'             // 'showcmd' buffer
  #define STL_VIM_EXPR  '{'             // start of expression to substitute
! #define STL_SEPARATE  '='             // separation between alignment
!                                       // sections
  #define STL_TRUNCMARK '<'             // truncation mark if line is too long
  #define STL_USER_HL   '*'             // highlight from (User)1..9 or 0
  #define STL_HIGHLIGHT '#'             // highlight name
*** ../vim-9.0.1299/src/optionstr.c     2023-02-02 16:34:07.741513245 +0000
--- src/optionstr.c     2023-02-11 10:57:54.547153067 +0000
***************
*** 587,593 ****
        if (!*s)
            break;
        s++;
!       if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK)
        {
            s++;
            continue;
--- 587,593 ----
        if (!*s)
            break;
        s++;
!       if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_SEPARATE)
        {
            s++;
            continue;
*** ../vim-9.0.1299/src/testdir/test_statusline.vim     2023-01-28 
19:18:56.733720607 +0000
--- src/testdir/test_statusline.vim     2023-02-11 10:57:54.547153067 +0000
***************
*** 231,236 ****
--- 231,240 ----
    " %=: Separation point between left and right aligned items.
    set statusline=foo%=bar
    call assert_match('^foo\s\+bar\s*$', s:get_statusline())
+   set statusline=foo%=bar%=baz
+   call assert_match('^foo\s\+bar\s\+baz\s*$', s:get_statusline())
+   set statusline=foo%=bar%=baz%=qux
+   call assert_match('^foo\s\+bar\s\+baz\s\+qux\s*$', s:get_statusline())
  
    " Test min/max width, leading zeroes, left/right justify.
    set statusline=%04B
*** ../vim-9.0.1299/src/version.c       2023-02-11 10:34:01.963398185 +0000
--- src/version.c       2023-02-11 11:00:42.235025698 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1300,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
114. You are counting items, you go "0,1,2,3,4,5,6,7,8,9,A,B,C,D...".

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20230211111621.E22991C0830%40moolenaar.net.

Raspunde prin e-mail lui