-
-
Save h-east/3158492 to your computer and use it in GitHub Desktop.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt | |
index 2e58c854e..2220cfb2c 100644 | |
--- a/runtime/doc/eval.txt | |
+++ b/runtime/doc/eval.txt | |
@@ -9485,6 +9485,7 @@ multi_byte Compiled with support for 'encoding' | |
multi_byte_encoding 'encoding' is set to a multi-byte encoding. | |
multi_byte_ime Compiled with support for IME input method. | |
multi_lang Compiled with support for multiple languages. | |
+multi_statusline Compiled with 'statuslineheight' support. | |
mzscheme Compiled with MzScheme interface |mzscheme|. | |
netbeans_enabled Compiled with support for |netbeans| and connected. | |
netbeans_intg Compiled with support for |netbeans|. | |
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt | |
index 0db2d465f..932db3cfa 100644 | |
--- a/runtime/doc/options.txt | |
+++ b/runtime/doc/options.txt | |
@@ -7553,6 +7553,9 @@ A jump table for the options with a short description can be found at |Q_op|. | |
The difference between User{N} and StatusLine will be applied | |
to StatusLineNC for the statusline of non-current windows. | |
The number N must be between 1 and 9. See |hl-User1..9| | |
+ @ - To the next line to be set. | |
+ This item available when compiled with the |+multi_statusline| | |
+ feature. | |
When displaying a flag, Vim removes the leading comma, if any, when | |
that flag comes right after plaintext. This will make a nice display | |
@@ -7609,6 +7612,16 @@ A jump table for the options with a short description can be found at |Q_op|. | |
: if exists(a:var) | return a:val | else | return '' | endif | |
:endfunction | |
< | |
+ | |
+ *'statuslineheight'* *'stlh'* | |
+'statuslineheight' 'stlh' number (default 1) | |
+ global or local to window |global-local| | |
+ {not in Vi} | |
+ {not available when compiled without the | |
+ |+multi_statusline| feature} | |
+ Number of screen lines to use for the status line. | |
+ Also see 'statusline' and |status-line|. | |
+ | |
*'suffixes'* *'su'* | |
'suffixes' 'su' string (default ".bak,~,.o,.h,.info,.swp,.obj") | |
global | |
diff --git a/src/buffer.c b/src/buffer.c | |
index cbccc7026..5b33aa5fe 100644 | |
--- a/src/buffer.c | |
+++ b/src/buffer.c | |
@@ -3623,7 +3623,7 @@ maketitle(void) | |
# endif | |
called_emsg = FALSE; | |
build_stl_str_hl(curwin, title_str, sizeof(buf), | |
- p_titlestring, use_sandbox, | |
+ p_titlestring, 0, use_sandbox, | |
0, maxlen, NULL, NULL); | |
if (called_emsg) | |
set_string_option_direct((char_u *)"titlestring", -1, | |
@@ -3756,8 +3756,8 @@ maketitle(void) | |
# endif | |
called_emsg = FALSE; | |
build_stl_str_hl(curwin, icon_str, sizeof(buf), | |
- p_iconstring, use_sandbox, | |
- 0, 0, NULL, NULL); | |
+ p_iconstring, 0, use_sandbox, | |
+ 0, 0, NULL, NULL); | |
if (called_emsg) | |
set_string_option_direct((char_u *)"iconstring", -1, | |
(char_u *)"", OPT_FREE, SID_ERROR); | |
@@ -3864,6 +3864,7 @@ build_stl_str_hl( | |
char_u *out, /* buffer to write into != NameBuff */ | |
size_t outlen, /* length of out[] */ | |
char_u *fmt, | |
+ int stl_row UNUSED, /* statusline row (0~) */ | |
int use_sandbox UNUSED, /* "fmt" was set insecurely, use sandbox */ | |
int fillchar, | |
int maxwidth, | |
@@ -3922,6 +3923,9 @@ build_stl_str_hl( | |
struct stl_hlrec *sp; | |
int save_must_redraw = must_redraw; | |
int save_redr_type = curwin->w_redr_type; | |
+#ifdef FEAT_STL_MULTI | |
+ int target_stl_row = 0; | |
+#endif | |
#ifdef FEAT_EVAL | |
/* | |
@@ -3986,7 +3990,16 @@ build_stl_str_hl( | |
* Handle up to the next '%' or the end. | |
*/ | |
while (*s != NUL && *s != '%' && p + 1 < out + outlen) | |
+ { | |
+#ifdef FEAT_STL_MULTI | |
+ if (target_stl_row == stl_row) | |
+ *p++ = *s++; | |
+ else | |
+ s++; | |
+#else | |
*p++ = *s++; | |
+#endif | |
+ } | |
if (*s == NUL || p + 1 >= out + outlen) | |
break; | |
@@ -3996,6 +4009,19 @@ build_stl_str_hl( | |
s++; | |
if (*s == NUL) /* ignore trailing % */ | |
break; | |
+#ifdef FEAT_STL_MULTI | |
+ if (*s == STL_NEXT_STATUSLINE) | |
+ { | |
+ s++; | |
+ target_stl_row++; | |
+ if (target_stl_row > stl_row) | |
+ break; | |
+ else | |
+ continue; | |
+ } | |
+ if (target_stl_row < stl_row) | |
+ continue; | |
+#endif | |
if (*s == '%') | |
{ | |
if (p + 1 >= out + outlen) | |
diff --git a/src/evalfunc.c b/src/evalfunc.c | |
index 82ea05af3..20035655e 100644 | |
--- a/src/evalfunc.c | |
+++ b/src/evalfunc.c | |
@@ -6318,6 +6318,9 @@ f_has(typval_T *argvars, typval_T *rettv) | |
#ifdef FEAT_MULTI_LANG | |
"multi_lang", | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ "multi_statusline", | |
+#endif | |
#ifdef FEAT_MZSCHEME | |
#ifndef DYNAMIC_MZSCHEME | |
"mzscheme", | |
diff --git a/src/ex_docmd.c b/src/ex_docmd.c | |
index d00ca5689..3113ab67f 100644 | |
--- a/src/ex_docmd.c | |
+++ b/src/ex_docmd.c | |
@@ -8428,6 +8428,9 @@ ex_splitview(exarg_T *eap) | |
else | |
do_check_scrollbind(FALSE); | |
do_exedit(eap, old_curwin); | |
+#ifdef FEAT_STL_MULTI | |
+ frame_change_statusline_height(); | |
+#endif | |
} | |
# ifdef FEAT_BROWSE | |
diff --git a/src/feature.h b/src/feature.h | |
index 6ae3ac23f..c1466d3dc 100644 | |
--- a/src/feature.h | |
+++ b/src/feature.h | |
@@ -439,6 +439,7 @@ | |
* +title 'title' and 'icon' options | |
* +statusline 'statusline', 'rulerformat' and special format of | |
* 'titlestring' and 'iconstring' options. | |
+ * +multi_statusline 'statuslineheight' options | |
* +byte_offset '%o' in 'statusline' and builtin functions line2byte() | |
* and byte2line(). | |
* Note: Required for Macintosh. | |
@@ -449,6 +450,7 @@ | |
#ifdef FEAT_NORMAL | |
# define FEAT_STL_OPT | |
+# define FEAT_STL_MULTI | |
# ifndef FEAT_CMDL_INFO | |
# define FEAT_CMDL_INFO /* 'ruler' is required for 'statusline' */ | |
# endif | |
diff --git a/src/gui.c b/src/gui.c | |
index 1341d505d..c1a2cee3e 100644 | |
--- a/src/gui.c | |
+++ b/src/gui.c | |
@@ -3765,7 +3765,7 @@ get_tabline_label( | |
curbuf = curwin->w_buffer; | |
/* Can't use NameBuff directly, build_stl_str_hl() uses it. */ | |
- build_stl_str_hl(curwin, res, MAXPATHL, *opt, use_sandbox, | |
+ build_stl_str_hl(curwin, res, MAXPATHL, *opt, 0, use_sandbox, | |
0, (int)Columns, NULL, NULL); | |
STRCPY(NameBuff, res); | |
@@ -4962,13 +4962,15 @@ xy2win(int x UNUSED, int y UNUSED) | |
else | |
update_mouseshape(SHAPE_IDX_MORE); | |
} | |
- else if (row > wp->w_height) /* below status line */ | |
+ else if (row >= wp->w_height + wp->w_status_height) // below status line | |
update_mouseshape(SHAPE_IDX_CLINE); | |
else if (!(State & CMDLINE) && wp->w_vsep_width > 0 && col == wp->w_width | |
- && (row != wp->w_height || !stl_connected(wp)) && msg_scrolled == 0) | |
+ && (!(row >= wp->w_height && row < wp->w_height | |
+ + wp->w_status_height) || !stl_connected(wp)) && msg_scrolled == 0) | |
update_mouseshape(SHAPE_IDX_VSEP); | |
else if (!(State & CMDLINE) && wp->w_status_height > 0 | |
- && row == wp->w_height && msg_scrolled == 0) | |
+ && row >= wp->w_height && row < wp->w_height + wp->w_status_height | |
+ && msg_scrolled == 0) | |
update_mouseshape(SHAPE_IDX_STATUS); | |
else | |
update_mouseshape(-2); | |
diff --git a/src/hardcopy.c b/src/hardcopy.c | |
index 486ae7d3d..761958533 100644 | |
--- a/src/hardcopy.c | |
+++ b/src/hardcopy.c | |
@@ -492,7 +492,7 @@ prt_header( | |
use_sandbox = was_set_insecurely((char_u *)"printheader", 0); | |
# endif | |
build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE), | |
- p_header, use_sandbox, | |
+ p_header, 0, use_sandbox, | |
' ', width, NULL, NULL); | |
/* Reset line numbers */ | |
diff --git a/src/misc1.c b/src/misc1.c | |
index 820f8f994..11f0bcc1c 100644 | |
--- a/src/misc1.c | |
+++ b/src/misc1.c | |
@@ -3383,7 +3383,7 @@ check_status(buf_T *buf) | |
win_T *wp; | |
FOR_ALL_WINDOWS(wp) | |
- if (wp->w_buffer == buf && wp->w_status_height) | |
+ if (wp->w_buffer == buf && wp->w_status_height > 0) | |
{ | |
wp->w_redr_status = TRUE; | |
if (must_redraw < VALID) | |
diff --git a/src/option.c b/src/option.c | |
index f238abe84..ae61d22ed 100644 | |
--- a/src/option.c | |
+++ b/src/option.c | |
@@ -244,6 +244,9 @@ | |
#ifdef FEAT_STL_OPT | |
# define PV_STL OPT_BOTH(OPT_WIN(WV_STL)) | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+# define PV_STLH OPT_BOTH(OPT_WIN(WV_STLH)) | |
+#endif | |
#define PV_UL OPT_BOTH(OPT_BUF(BV_UL)) | |
# define PV_WFH OPT_WIN(WV_WFH) | |
# define PV_WFW OPT_WIN(WV_WFW) | |
@@ -2646,6 +2649,13 @@ static struct vimoption options[] = | |
(char_u *)NULL, PV_NONE, | |
#endif | |
{(char_u *)"", (char_u *)0L} SCTX_INIT}, | |
+ {"statuslineheight" ,"stlh", P_NUM|P_VI_DEF|P_RALL, | |
+#ifdef FEAT_STL_MULTI | |
+ (char_u *)&p_stlh, PV_STLH, | |
+#else | |
+ (char_u *)NULL, PV_NONE, | |
+#endif | |
+ {(char_u *)1L, (char_u *)1L} SCTX_INIT}, | |
{"suffixes", "su", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, | |
(char_u *)&p_su, PV_NONE, | |
{(char_u *)".bak,~,.o,.h,.info,.swp,.obj", | |
@@ -3585,6 +3595,10 @@ set_init_1(int clean_arg) | |
curbuf->b_p_ar = -1; /* no local 'autoread' value */ | |
curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; | |
check_buf_options(curbuf); | |
+#ifdef FEAT_STL_MULTI | |
+ curwin->w_p_stlh = -1; // no local 'statuslineheight' value | |
+ curwin->w_allbuf_opt.wo_stlh = -1; | |
+#endif | |
check_win_options(curwin); | |
check_options(); | |
@@ -4775,6 +4789,20 @@ do_set( | |
? VI_DEFAULT : VIM_DEFAULT]; | |
else if (nextchar == '<') | |
{ | |
+#ifdef FEAT_STL_MULTI | |
+ // For 'statuslineheight' -1 means to use global | |
+ // value. | |
+ if ((long *)varp == &curwin->w_p_stlh) | |
+ { | |
+ if (opt_flags != OPT_LOCAL) | |
+ { | |
+ curwin->w_p_stlh = -1; | |
+ varp = (char_u *)&p_stlh; | |
+ } | |
+ value = p_stlh; | |
+ } | |
+ else | |
+#endif | |
/* For 'undolevels' NO_LOCAL_UNDOLEVEL means to | |
* use the global value. */ | |
if ((long *)varp == &curbuf->b_p_ul | |
@@ -5852,6 +5880,9 @@ insecure_flag(int opt_idx, int opt_flags) | |
#ifdef FEAT_STL_OPT | |
case PV_STL: return &curwin->w_p_stl_flags; | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ case PV_STLH: return &curwin->w_p_stlh_flags; | |
+#endif | |
#ifdef FEAT_EVAL | |
# ifdef FEAT_FOLDING | |
case PV_FDE: return &curwin->w_p_fde_flags; | |
@@ -7158,7 +7189,7 @@ did_set_string_option( | |
errmsg = e_invarg; | |
else | |
{ | |
- if (curwin->w_status_height) | |
+ if (curwin->w_status_height > 0) | |
{ | |
curwin->w_redr_status = TRUE; | |
redraw_later(VALID); | |
@@ -8020,7 +8051,11 @@ check_stl_option(char_u *s) | |
s++; | |
if (*s != '%' && *s != ')') | |
++itemcnt; | |
- if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK) | |
+ if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK | |
+#ifdef FEAT_STL_MULTI | |
+ || *s == STL_NEXT_STATUSLINE | |
+#endif | |
+ ) | |
{ | |
s++; | |
continue; | |
@@ -9210,6 +9245,45 @@ set_num_option( | |
command_height(); | |
} | |
+#ifdef FEAT_STL_MULTI | |
+ /* when 'statuslineheight' changed, change the status line height */ | |
+ else if (pp == &curwin->w_p_stlh) | |
+ { | |
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) | |
+ { | |
+ p_stlh = curwin->w_p_stlh; | |
+ curwin->w_p_stlh = -1; | |
+ if (p_stlh < 1) | |
+ { | |
+ errmsg = e_positive; | |
+ p_stlh = 1; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ if (curwin->w_p_stlh < 1) | |
+ { | |
+ errmsg = e_positive; | |
+ curwin->w_p_stlh = 1; | |
+ } | |
+ } | |
+ fitting_statusline_height_value(); | |
+ frame_change_statusline_height(); | |
+ } | |
+ else if (pp == &p_stlh) | |
+ { | |
+ if (p_stlh < 1) | |
+ { | |
+ errmsg = e_positive; | |
+ p_stlh = 1; | |
+ } | |
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) | |
+ curwin->w_p_stlh = -1; | |
+ fitting_statusline_height_value(); | |
+ frame_change_statusline_height(); | |
+ } | |
+#endif | |
+ | |
/* when 'updatecount' changes from zero to non-zero, open swap files */ | |
else if (pp == &p_uc) | |
{ | |
@@ -10755,6 +10829,9 @@ get_varp_scope(struct vimoption *p, int opt_flags) | |
#endif | |
#ifdef FEAT_STL_OPT | |
case PV_STL: return (char_u *)&(curwin->w_p_stl); | |
+#endif | |
+#ifdef FEAT_STL_MULTI | |
+ case PV_STLH: return (char_u *)&(curwin->w_p_stlh); | |
#endif | |
case PV_UL: return (char_u *)&(curbuf->b_p_ul); | |
#ifdef FEAT_LISP | |
@@ -10832,6 +10909,10 @@ get_varp(struct vimoption *p) | |
#ifdef FEAT_STL_OPT | |
case PV_STL: return *curwin->w_p_stl != NUL | |
? (char_u *)&(curwin->w_p_stl) : p->var; | |
+#endif | |
+#ifdef FEAT_STL_MULTI | |
+ case PV_STLH: return curwin->w_p_stlh >= 0 | |
+ ? (char_u *)&(curwin->w_p_stlh) : p->var; | |
#endif | |
case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL | |
? (char_u *)&(curbuf->b_p_ul) : p->var; | |
@@ -11075,6 +11156,9 @@ copy_winopt(winopt_T *from, winopt_T *to) | |
#endif | |
#ifdef FEAT_STL_OPT | |
to->wo_stl = vim_strsave(from->wo_stl); | |
+#endif | |
+#ifdef FEAT_STL_MULTI | |
+ to->wo_stlh = from->wo_stlh; | |
#endif | |
to->wo_wrap = from->wo_wrap; | |
#ifdef FEAT_DIFF | |
@@ -11212,6 +11296,9 @@ clear_winopt(winopt_T *wop UNUSED) | |
#ifdef FEAT_STL_OPT | |
clear_string_option(&wop->wo_stl); | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ wop->wo_stlh = -1; | |
+#endif | |
#ifdef FEAT_SYN_HL | |
clear_string_option(&wop->wo_cc); | |
#endif | |
diff --git a/src/option.h b/src/option.h | |
index 5df7f2147..7225041c3 100644 | |
--- a/src/option.h | |
+++ b/src/option.h | |
@@ -288,6 +288,9 @@ | |
#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 */ | |
+#ifdef FEAT_STL_MULTI | |
+# define STL_NEXT_STATUSLINE '@' /* next status-line */ | |
+#endif | |
#define STL_TABPAGENR 'T' /* tab page label nr */ | |
#define STL_TABCLOSENR 'X' /* tab page close nr */ | |
#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#") | |
@@ -791,6 +794,9 @@ EXTERN int p_ssl; /* 'shellslash' */ | |
#ifdef FEAT_STL_OPT | |
EXTERN char_u *p_stl; /* 'statusline' */ | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+EXTERN long p_stlh; /* 'statuslineheight' */ | |
+#endif | |
EXTERN int p_sr; /* 'shiftround' */ | |
EXTERN char_u *p_shm; /* 'shortmess' */ | |
#ifdef FEAT_LINEBREAK | |
@@ -1189,6 +1195,9 @@ enum | |
#endif | |
#ifdef FEAT_STL_OPT | |
, WV_STL | |
+#endif | |
+#ifdef FEAT_STL_MULTI | |
+ , WV_STLH | |
#endif | |
, WV_WFH | |
, WV_WFW | |
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro | |
index 6820d9734..494678be5 100644 | |
--- a/src/proto/buffer.pro | |
+++ b/src/proto/buffer.pro | |
@@ -46,7 +46,7 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol); | |
void maketitle(void); | |
void resettitle(void); | |
void free_titles(void); | |
-int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, int fillchar, int maxwidth, struct stl_hlrec *hltab, struct stl_hlrec *tabtab); | |
+int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int stl_row, int use_sandbox, int fillchar, int maxwidth, struct stl_hlrec *hltab, struct stl_hlrec *tabtab); | |
void get_rel_pos(win_T *wp, char_u *buf, int buflen); | |
char_u *fix_fname(char_u *fname); | |
void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname); | |
diff --git a/src/proto/window.pro b/src/proto/window.pro | |
index 4527a37f4..d5fb3684f 100644 | |
--- a/src/proto/window.pro | |
+++ b/src/proto/window.pro | |
@@ -64,6 +64,9 @@ void win_new_width(win_T *wp, int width); | |
void win_comp_scroll(win_T *wp); | |
void command_height(void); | |
void last_status(int morewin); | |
+void fitting_statusline_height_value(void); | |
+void frame_change_statusline_height(void); | |
+int statusline_height(win_T *wp); | |
int tabline_height(void); | |
char_u *grab_file_name(long count, linenr_T *file_lnum); | |
char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum); | |
diff --git a/src/screen.c b/src/screen.c | |
index 69f755844..86df97eb9 100644 | |
--- a/src/screen.c | |
+++ b/src/screen.c | |
@@ -6899,6 +6899,7 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) | |
{ | |
int row; | |
char_u *p; | |
+ int i; | |
int len; | |
int fillchar; | |
int attr; | |
@@ -7021,6 +7022,9 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) | |
screen_puts(p, row, wp->w_wincol, attr); | |
screen_fill(row, row + 1, len + wp->w_wincol, | |
this_ru_col + wp->w_wincol, fillchar, fillchar, attr); | |
+ for (i = 1; i < wp->w_status_height; i++) | |
+ screen_fill(row + i, row + 1 + i, wp->w_wincol, | |
+ this_ru_col + wp->w_wincol, fillchar, fillchar, attr); | |
if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL) | |
&& (int)(this_ru_col - len) > (int)(STRLEN(NameBuff) + 1)) | |
@@ -7035,14 +7039,15 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) | |
/* | |
* May need to draw the character below the vertical separator. | |
*/ | |
- if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) | |
+ if (wp->w_vsep_width != 0 && wp->w_status_height > 0 && redrawing()) | |
{ | |
if (stl_connected(wp)) | |
fillchar = fillchar_status(&attr, wp); | |
else | |
fillchar = fillchar_vsep(&attr); | |
- screen_putchar(fillchar, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp), | |
- attr); | |
+ for (len=0; len < wp->w_status_height; len++) | |
+ screen_putchar(fillchar, W_WINROW(wp) + wp->w_height + len, | |
+ W_ENDCOL(wp), attr); | |
} | |
busy = FALSE; | |
} | |
@@ -7174,8 +7179,10 @@ win_redr_custom( | |
int col = 0; | |
int maxwidth; | |
int width; | |
+ int i; | |
int n; | |
int len; | |
+ int stlh_cnt; | |
int fillchar; | |
char_u buf[MAXPATHL]; | |
char_u *stl; | |
@@ -7265,67 +7272,72 @@ win_redr_custom( | |
ewp = wp == NULL ? curwin : wp; | |
p_crb_save = ewp->w_p_crb; | |
ewp->w_p_crb = FALSE; | |
+ stlh_cnt = stl == p_tal ? 1 : wp->w_status_height; | |
/* Make a copy, because the statusline may include a function call that | |
* might change the option value and free the memory. */ | |
stl = vim_strsave(stl); | |
- width = build_stl_str_hl(ewp, buf, sizeof(buf), | |
- stl, use_sandbox, | |
- fillchar, maxwidth, hltab, tabtab); | |
- vim_free(stl); | |
- ewp->w_p_crb = p_crb_save; | |
- | |
- /* Make all characters printable. */ | |
- p = transstr(buf); | |
- if (p != NULL) | |
+ for (i = 0; i < stlh_cnt; i++) | |
{ | |
- vim_strncpy(buf, p, sizeof(buf) - 1); | |
- vim_free(p); | |
- } | |
+ vim_memset(buf, 0, sizeof(buf)); | |
+ width = build_stl_str_hl(ewp, buf, sizeof(buf), | |
+ stl, i, use_sandbox, | |
+ fillchar, maxwidth, hltab, tabtab); | |
+ ewp->w_p_crb = p_crb_save; | |
- /* fill up with "fillchar" */ | |
- len = (int)STRLEN(buf); | |
- while (width < maxwidth && len < (int)sizeof(buf) - 1) | |
- { | |
+ /* Make all characters printable. */ | |
+ p = transstr(buf); | |
+ if (p != NULL) | |
+ { | |
+ vim_strncpy(buf, p, sizeof(buf) - 1); | |
+ vim_free(p); | |
+ } | |
+ | |
+ /* fill up with "fillchar" */ | |
+ len = (int)STRLEN(buf); | |
+ while (width < maxwidth && len < (int)sizeof(buf) - 1) | |
+ { | |
#ifdef FEAT_MBYTE | |
- len += (*mb_char2bytes)(fillchar, buf + len); | |
+ len += (*mb_char2bytes)(fillchar, buf + len); | |
#else | |
- buf[len++] = fillchar; | |
+ buf[len++] = fillchar; | |
#endif | |
- ++width; | |
- } | |
- buf[len] = NUL; | |
+ ++width; | |
+ } | |
+ buf[len] = NUL; | |
- /* | |
- * Draw each snippet with the specified highlighting. | |
- */ | |
- curattr = attr; | |
- p = buf; | |
- for (n = 0; hltab[n].start != NULL; n++) | |
- { | |
- len = (int)(hltab[n].start - p); | |
- screen_puts_len(p, len, row, col, curattr); | |
- col += vim_strnsize(p, len); | |
- p = hltab[n].start; | |
- | |
- if (hltab[n].userhl == 0) | |
- curattr = attr; | |
- else if (hltab[n].userhl < 0) | |
- curattr = syn_id2attr(-hltab[n].userhl); | |
+ /* | |
+ * Draw each snippet with the specified highlighting. | |
+ */ | |
+ curattr = attr; | |
+ p = buf; | |
+ for (n = 0; hltab[n].start != NULL; n++) | |
+ { | |
+ len = (int)(hltab[n].start - p); | |
+ screen_puts_len(p, len, row, col, curattr); | |
+ col += vim_strnsize(p, len); | |
+ p = hltab[n].start; | |
+ | |
+ if (hltab[n].userhl == 0) | |
+ curattr = attr; | |
+ else if (hltab[n].userhl < 0) | |
+ curattr = syn_id2attr(-hltab[n].userhl); | |
#ifdef FEAT_TERMINAL | |
- else if (wp != NULL && wp != curwin && bt_terminal(wp->w_buffer) | |
- && wp->w_status_height != 0) | |
- curattr = highlight_stltermnc[hltab[n].userhl - 1]; | |
- else if (wp != NULL && bt_terminal(wp->w_buffer) | |
- && wp->w_status_height != 0) | |
- curattr = highlight_stlterm[hltab[n].userhl - 1]; | |
-#endif | |
- else if (wp != NULL && wp != curwin && wp->w_status_height != 0) | |
- curattr = highlight_stlnc[hltab[n].userhl - 1]; | |
- else | |
- curattr = highlight_user[hltab[n].userhl - 1]; | |
+ else if (wp != NULL && wp != curwin && bt_terminal(wp->w_buffer) | |
+ && wp->w_status_height != 0) | |
+ curattr = highlight_stltermnc[hltab[n].userhl - 1]; | |
+ else if (wp != NULL && bt_terminal(wp->w_buffer) | |
+ && wp->w_status_height != 0) | |
+ curattr = highlight_stlterm[hltab[n].userhl - 1]; | |
+#endif | |
+ else if (wp != NULL && wp != curwin && wp->w_status_height != 0) | |
+ curattr = highlight_stlnc[hltab[n].userhl - 1]; | |
+ else | |
+ curattr = highlight_user[hltab[n].userhl - 1]; | |
+ } | |
+ screen_puts(p, row + i, col, curattr); | |
} | |
- screen_puts(p, row, col, curattr); | |
+ vim_free(stl); | |
if (wp == NULL) | |
{ | |
diff --git a/src/structs.h b/src/structs.h | |
index a0c06b5f2..2e9524dfd 100644 | |
--- a/src/structs.h | |
+++ b/src/structs.h | |
@@ -255,7 +255,11 @@ typedef struct | |
#endif | |
#ifdef FEAT_STL_OPT | |
char_u *wo_stl; | |
-#define w_p_stl w_onebuf_opt.wo_stl /* 'statusline' */ | |
+# define w_p_stl w_onebuf_opt.wo_stl /* 'statusline' */ | |
+#ifdef FEAT_STL_MULTI | |
+ long wo_stlh; | |
+# define w_p_stlh w_onebuf_opt.wo_stlh /* 'statuslineheight' */ | |
+#endif | |
#endif | |
int wo_scb; | |
#define w_p_scb w_onebuf_opt.wo_scb /* 'scrollbind' */ | |
@@ -2741,7 +2745,11 @@ struct window_S | |
int w_winrow; /* first row of window in screen */ | |
int w_height; /* number of rows in window, excluding | |
status/command/winbar line(s) */ | |
- int w_status_height; /* number of status lines (0 or 1) */ | |
+ int w_status_height; // number of status lines. If | |
+ // 'statuslineheight' was changed, this | |
+ // member will be the previous value until | |
+ // call function | |
+ // frame_change_statusline_height(). | |
int w_wincol; /* Leftmost column of window in screen. */ | |
int w_width; /* Width of window, excluding separation. */ | |
int w_vsep_width; /* Number of separator columns (0 or 1). */ | |
@@ -2870,6 +2878,9 @@ struct window_S | |
#ifdef FEAT_STL_OPT | |
long_u w_p_stl_flags; /* flags for 'statusline' */ | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ long_u w_p_stlh_flags; /* flags for 'statuslineheight' */ | |
+#endif | |
#ifdef FEAT_EVAL | |
long_u w_p_fde_flags; /* flags for 'foldexpr' */ | |
long_u w_p_fdt_flags; /* flags for 'foldtext' */ | |
diff --git a/src/version.c b/src/version.c | |
index 9d700e2ba..fc7c5fd5c 100644 | |
--- a/src/version.c | |
+++ b/src/version.c | |
@@ -470,6 +470,11 @@ static char *(features[]) = | |
#else | |
"-multi_lang", | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ "+multi_statusline", | |
+#else | |
+ "-multi_statusline", | |
+#endif | |
#ifdef FEAT_MZSCHEME | |
# ifdef DYNAMIC_MZSCHEME | |
"+mzscheme/dyn", | |
diff --git a/src/vim.h b/src/vim.h | |
index 7a66ab0e2..80d39722c 100644 | |
--- a/src/vim.h | |
+++ b/src/vim.h | |
@@ -1485,7 +1485,8 @@ typedef UINT32_TYPEDEF UINT32_T; | |
*/ | |
#define MIN_COLUMNS 12 /* minimal columns for screen */ | |
#define MIN_LINES 2 /* minimal lines for screen */ | |
-#define STATUS_HEIGHT 1 /* height of a status line under a window */ | |
+#define STATUS_HEIGHT 1 // default height of a status line under a | |
+ // window | |
#ifdef FEAT_MENU /* height of a status line under a window */ | |
# define WINBAR_HEIGHT(wp) (wp)->w_winbar_height | |
# define VISIBLE_HEIGHT(wp) ((wp)->w_height + (wp)->w_winbar_height) | |
diff --git a/src/window.c b/src/window.c | |
index e16570f4e..4614536a6 100644 | |
--- a/src/window.c | |
+++ b/src/window.c | |
@@ -49,6 +49,7 @@ static void win_goto_ver(int up, long count); | |
static void win_goto_hor(int left, long count); | |
static void frame_add_height(frame_T *frp, int n); | |
static void last_status_rec(frame_T *fr, int statusline); | |
+static void frame_change_statusline_height_rec(frame_T *frp); | |
static void make_snapshot_rec(frame_T *fr, frame_T **frp); | |
static void clear_snapshot(tabpage_T *tp, int idx); | |
@@ -784,7 +785,7 @@ win_split_ins( | |
EMSG(_(e_noroom)); | |
return FAIL; | |
} | |
- need_status = STATUS_HEIGHT; | |
+ need_status = statusline_height(oldwin); | |
} | |
#ifdef FEAT_GUI | |
@@ -890,7 +891,7 @@ win_split_ins( | |
*/ | |
/* Current window requires at least 1 space. */ | |
wmh1 = (p_wmh == 0 ? 1 : p_wmh) + WINBAR_HEIGHT(curwin); | |
- needed = wmh1 + STATUS_HEIGHT; | |
+ needed = p_wmh + statusline_height(oldwin); | |
if (flags & WSP_ROOM) | |
needed += p_wh - wmh1; | |
if (flags & (WSP_BOT | WSP_TOP)) | |
@@ -930,18 +931,23 @@ win_split_ins( | |
oldwin_height = oldwin->w_height; | |
if (need_status) | |
{ | |
- oldwin->w_status_height = STATUS_HEIGHT; | |
- oldwin_height -= STATUS_HEIGHT; | |
+ oldwin->w_status_height = statusline_height(oldwin); | |
+ oldwin_height -= oldwin->w_status_height; | |
} | |
if (new_size == 0) | |
- new_size = oldwin_height / 2; | |
- if (new_size > available - minheight - STATUS_HEIGHT) | |
- new_size = available - minheight - STATUS_HEIGHT; | |
+ { | |
+ if (lastwin == firstwin && p_ls == 0) | |
+ new_size = (oldwin_height - statusline_height(oldwin) + 1) / 2; | |
+ else | |
+ new_size = (oldwin_height - oldwin->w_status_height + 1) / 2; | |
+ } | |
+ if (new_size > available - minheight - statusline_height(oldwin)) | |
+ new_size = available - minheight - statusline_height(oldwin); | |
if (new_size < wmh1) | |
new_size = wmh1; | |
/* if it doesn't fit in the current window, need win_equal() */ | |
- if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh) | |
+ if (oldwin_height - new_size - statusline_height(oldwin) < p_wmh) | |
do_equal = TRUE; | |
/* We don't like to take lines for the new window from a | |
@@ -954,11 +960,11 @@ win_split_ins( | |
set_fraction(oldwin); | |
did_set_fraction = TRUE; | |
- win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT, | |
- oldwin); | |
+ win_setheight_win(oldwin->w_height + new_size | |
+ + statusline_height(oldwin), oldwin); | |
oldwin_height = oldwin->w_height; | |
if (need_status) | |
- oldwin_height -= STATUS_HEIGHT; | |
+ oldwin_height -= statusline_height(oldwin); | |
} | |
/* Only make all windows the same height if one of them (except oldwin) | |
@@ -972,7 +978,7 @@ win_split_ins( | |
if (frp->fr_win != oldwin && frp->fr_win != NULL | |
&& (frp->fr_win->w_height > new_size | |
|| frp->fr_win->w_height > oldwin_height - new_size | |
- - STATUS_HEIGHT)) | |
+ - statusline_height(oldwin))) | |
{ | |
do_equal = TRUE; | |
break; | |
@@ -1093,16 +1099,16 @@ win_split_ins( | |
if (need_status) | |
{ | |
- win_new_height(oldwin, oldwin->w_height - 1); | |
+ win_new_height(oldwin, oldwin->w_height - need_status); | |
oldwin->w_status_height = need_status; | |
} | |
if (flags & (WSP_TOP | WSP_BOT)) | |
{ | |
/* set height and row of new window to full height */ | |
wp->w_winrow = tabline_height(); | |
- win_new_height(wp, curfrp->fr_height - (p_ls > 0) | |
- - WINBAR_HEIGHT(wp)); | |
- wp->w_status_height = (p_ls > 0); | |
+ win_new_height(wp, curfrp->fr_height | |
+ - statusline_height(curfrp->fr_win) - WINBAR_HEIGHT(wp)); | |
+ wp->w_status_height = statusline_height(curfrp->fr_win); | |
} | |
else | |
{ | |
@@ -1170,24 +1176,25 @@ win_split_ins( | |
+ WINBAR_HEIGHT(wp) ; | |
if (!((flags & WSP_BOT) && p_ls == 0)) | |
- new_fr_height -= STATUS_HEIGHT; | |
+ new_fr_height -= statusline_height(curfrp->fr_win); | |
frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, FALSE); | |
} | |
else | |
- win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT)); | |
+ win_new_height(oldwin, oldwin_height - (new_size | |
+ + statusline_height(wp))); | |
if (before) /* new window above current one */ | |
{ | |
wp->w_winrow = oldwin->w_winrow; | |
- wp->w_status_height = STATUS_HEIGHT; | |
- oldwin->w_winrow += wp->w_height + STATUS_HEIGHT; | |
+ wp->w_status_height = statusline_height(wp); | |
+ oldwin->w_winrow += wp->w_height + statusline_height(wp); | |
} | |
else /* new window below current one */ | |
{ | |
wp->w_winrow = oldwin->w_winrow + VISIBLE_HEIGHT(oldwin) | |
- + STATUS_HEIGHT; | |
+ + statusline_height(oldwin); | |
wp->w_status_height = oldwin->w_status_height; | |
if (!(flags & WSP_BOT)) | |
- oldwin->w_status_height = STATUS_HEIGHT; | |
+ oldwin->w_status_height = statusline_height(oldwin); | |
} | |
if (flags & WSP_BOT) | |
frame_add_statusline(curfrp); | |
@@ -1295,6 +1302,7 @@ win_init(win_T *newp, win_T *oldp, int flags UNUSED) | |
newp->w_wrow = oldp->w_wrow; | |
newp->w_fraction = oldp->w_fraction; | |
newp->w_prev_fraction_row = oldp->w_prev_fraction_row; | |
+// newp->w_status_height = oldp->w_status_height; | |
#ifdef FEAT_JUMPLIST | |
copy_jumplist(oldp, newp); | |
#endif | |
@@ -1426,7 +1434,7 @@ make_windows( | |
{ | |
/* Each window needs at least 'winminheight' lines and a status line. */ | |
maxcount = (VISIBLE_HEIGHT(curwin) + curwin->w_status_height | |
- - (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT); | |
+ - (p_wh - p_wmh)) / (p_wmh + statusline_height(curwin)); | |
} | |
if (maxcount < 2) | |
@@ -1457,8 +1465,8 @@ make_windows( | |
else | |
{ | |
if (win_split(curwin->w_height - (curwin->w_height - todo | |
- * STATUS_HEIGHT) / (todo + 1) | |
- - STATUS_HEIGHT, WSP_ABOVE) == FAIL) | |
+ * statusline_height(curwin)) / (todo + 1) | |
+ - statusline_height(curwin), WSP_ABOVE) == FAIL) | |
break; | |
} | |
@@ -1766,6 +1774,7 @@ win_equal( | |
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current, | |
topframe, dir, 0, tabline_height(), | |
(int)Columns, topframe->fr_height); | |
+ frame_change_statusline_height(); | |
} | |
/* | |
@@ -1961,10 +1970,11 @@ win_equal_rec( | |
n = frame_minheight(topfr, NOWIN); | |
/* add one for the bottom window if it doesn't have a statusline */ | |
if (row + height == cmdline_row && p_ls == 0) | |
- extra_sep = 1; | |
+ extra_sep = statusline_height(next_curwin); | |
else | |
extra_sep = 0; | |
- totwincount = (n + extra_sep) / (p_wmh + 1); | |
+ totwincount = (n + extra_sep) / (p_wmh | |
+ + next_curwin->w_status_height); | |
has_next_curwin = frame_has_win(topfr, next_curwin); | |
/* | |
@@ -2003,7 +2013,8 @@ win_equal_rec( | |
else | |
/* These windows don't use up room. */ | |
totwincount -= (n + (fr->fr_next == NULL | |
- ? extra_sep : 0)) / (p_wmh + 1); | |
+ ? extra_sep : 0)) | |
+ / (p_wmh + next_curwin->w_status_height); | |
room -= new_size - n; | |
if (room < 0) | |
{ | |
@@ -2055,7 +2066,7 @@ win_equal_rec( | |
/* Compute the maximum number of windows vert. in "fr". */ | |
n = frame_minheight(fr, NOWIN); | |
wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) | |
- / (p_wmh + 1); | |
+ / (p_wmh + next_curwin->w_status_height); | |
m = frame_minheight(fr, next_curwin); | |
if (has_next_curwin) | |
hnc = frame_has_win(fr, next_curwin); | |
@@ -3058,9 +3069,10 @@ frame_add_statusline(frame_T *frp) | |
wp = frp->fr_win; | |
if (wp->w_status_height == 0) | |
{ | |
- if (wp->w_height > 0) /* don't make it negative */ | |
- --wp->w_height; | |
- wp->w_status_height = STATUS_HEIGHT; | |
+ wp->w_status_height = statusline_height(wp); | |
+ // don't make it negative | |
+ if (wp->w_height >= wp->w_status_height) | |
+ wp->w_height -= wp->w_status_height; | |
} | |
} | |
else if (frp->fr_layout == FR_ROW) | |
@@ -3555,6 +3567,10 @@ new_frame(win_T *wp) | |
win_init_size(void) | |
{ | |
firstwin->w_height = ROWS_AVAIL; | |
+ firstwin->w_status_height = 0; | |
+#ifdef FEAT_STL_MULTI | |
+ firstwin->w_onebuf_opt.wo_stlh = -1; | |
+#endif | |
topframe->fr_height = ROWS_AVAIL; | |
firstwin->w_width = Columns; | |
topframe->fr_width = Columns; | |
@@ -4566,6 +4582,9 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED) | |
} | |
init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE); | |
#endif | |
+#ifdef FEAT_STL_MULTI | |
+ new_wp->w_p_stlh = -1; | |
+#endif | |
/* Don't execute autocommands while the window is not properly | |
* initialized yet. gui_create_scrollbar() may trigger a FocusGained | |
@@ -4972,6 +4991,7 @@ win_comp_pos(void) | |
int col = 0; | |
frame_comp_pos(topframe, &row, &col); | |
+ frame_change_statusline_height(); | |
return row; | |
} | |
@@ -5029,6 +5049,9 @@ frame_comp_pos(frame_T *topfrp, int *row, int *col) | |
win_setheight(int height) | |
{ | |
win_setheight_win(height, curwin); | |
+#ifdef FEAT_STL_MULTI | |
+ frame_change_statusline_height(); | |
+#endif | |
} | |
/* | |
@@ -6008,6 +6031,7 @@ last_status( | |
/* Don't make a difference between horizontal or vertical split. */ | |
last_status_rec(topframe, (p_ls == 2 | |
|| (p_ls == 1 && (morewin || !ONE_WINDOW)))); | |
+ frame_change_statusline_height(); | |
} | |
static void | |
@@ -6022,7 +6046,7 @@ last_status_rec(frame_T *fr, int statusline) | |
if (wp->w_status_height != 0 && !statusline) | |
{ | |
/* remove status line */ | |
- win_new_height(wp, wp->w_height + 1); | |
+ win_new_height(wp, wp->w_height + wp->w_status_height); | |
wp->w_status_height = 0; | |
comp_col(); | |
} | |
@@ -6044,15 +6068,16 @@ last_status_rec(frame_T *fr, int statusline) | |
else | |
fp = fp->fr_parent; | |
} | |
- wp->w_status_height = 1; | |
+ wp->w_status_height = statusline_height(wp); | |
if (fp != fr) | |
{ | |
- frame_new_height(fp, fp->fr_height - 1, FALSE, FALSE); | |
+ frame_new_height(fp, fp->fr_height - wp->w_status_height, | |
+ FALSE, FALSE); | |
frame_fix_height(wp); | |
(void)win_comp_pos(); | |
} | |
else | |
- win_new_height(wp, wp->w_height - 1); | |
+ win_new_height(wp, wp->w_height - wp->w_status_height); | |
comp_col(); | |
redraw_all_later(SOME_VALID); | |
} | |
@@ -6072,6 +6097,97 @@ last_status_rec(frame_T *fr, int statusline) | |
} | |
} | |
+#ifdef FEAT_STL_MULTI | |
+ void | |
+fitting_statusline_height_value(void) | |
+{ | |
+ int height; | |
+ | |
+ /* use global value */ | |
+ if (curwin->w_p_stlh == -1) | |
+ { | |
+ win_T *wp; | |
+ tabpage_T *tp; | |
+ | |
+ FOR_ALL_TAB_WINDOWS(tp, wp) | |
+ { | |
+ if (wp->w_p_stlh == -1) | |
+ { | |
+ height = wp->w_height + wp->w_status_height; | |
+ if (height - 1 < p_stlh) | |
+ p_stlh = height - 1; | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ /* use window-local value */ | |
+ height = curwin->w_height + curwin->w_status_height; | |
+ if (height - 1 < curwin->w_p_stlh) | |
+ curwin->w_p_stlh = height - 1; | |
+ } | |
+ | |
+ return; | |
+} | |
+ | |
+/* | |
+ * Set a status line height to windows at the bottom of "frp". | |
+ * Note: Does not check if there is room! | |
+ */ | |
+ void | |
+frame_change_statusline_height(void) | |
+{ | |
+ frame_change_statusline_height_rec(topframe); | |
+ comp_col(); | |
+ redraw_all_later(SOME_VALID); | |
+} | |
+ | |
+ static void | |
+frame_change_statusline_height_rec(frame_T *frp) | |
+{ | |
+ win_T *wp; | |
+ | |
+ if (frp->fr_layout == FR_LEAF) | |
+ { | |
+ int new_w_height; | |
+ | |
+ wp = frp->fr_win; | |
+ if (wp->w_status_height > 0) | |
+ { | |
+ wp->w_status_height = statusline_height(wp); | |
+ new_w_height = frp->fr_height - wp->w_status_height; | |
+ win_new_height(wp, new_w_height); | |
+ } | |
+ } | |
+ else if (frp->fr_layout == FR_ROW) | |
+ { | |
+ /* Handle all the frames in the row. */ | |
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) | |
+ frame_change_statusline_height_rec(frp); | |
+ } | |
+ else /* frp->fr_layout == FR_COL */ | |
+ { | |
+ /* Handle all the frames in the column. */ | |
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) | |
+ frame_change_statusline_height_rec(frp); | |
+ } | |
+} | |
+#endif | |
+ | |
+/* | |
+ * Return the number of lines used by the status line. | |
+ */ | |
+ int | |
+statusline_height(wp) | |
+ win_T *wp; | |
+{ | |
+#ifdef FEAT_STL_MULTI | |
+ return (wp != NULL && wp->w_p_stlh >= 0) ? wp->w_p_stlh : p_stlh; | |
+#else | |
+ return STATUS_HEIGHT; | |
+#endif | |
+} | |
+ | |
/* | |
* Return the number of lines used by the tab page line. | |
*/ |
When you say it's over you mean it's finished and ready to be put into the core (if accepted)?
BTW been learning more Japanese, I recognize some Hiraganas and Katakanas now. Not most of them though. π
FYI I already know how to speak Japanese. π
@greduan
I posted to the vim_dev mailing list this patch.
https://groups.google.com/d/msg/vim_dev/ZWWgK9aXQ2Y/GC82mWbXJdcJ
However, I did not get a good reaction.
In addition, there was a decrease in motivation and technical problems.
Unfortunately, I quit update of this patch.
For more information, please refer to this Issue. (in Japanese)
vim-jp/issues#225
GreduanγγγζεΎ γ«εΏγγγγͺγγ¦γγγγͺγγ:pensive:
Ah I see. Well that's a shame.
γγ γγ, γγ€γγγγ:persevere:
http://www.romajidesu.com/hiragana/
http://www.romaji.org/
γγγγ€ γͺ γ¨γγ γ‘:wink:
Patch update for Vim 8.1.0500
update patch base on 7.3.931.
(No major and minor changes)
This Gist is Over.