To: vim_dev@googlegroups.com Subject: Patch 9.0.1300 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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: %-(xxx%) => group, %= => middle marker, %< => truncation * Item: %-. All but 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: %-(xxx%) => group, %= => separation marker, %< => truncation * Item: %-. All but 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///