Mercurial > vim
changeset 36524:464a84ee9b98 draft v9.1.0854
patch 9.1.0854: cannot get terminal cell size
Commit: https://github.com/vim/vim/commit/1083cae7091f006249c1349d0575412d2ff6a7dc
Author: mikoto2000 <mikoto2000@gmail.com>
Date: Mon Nov 11 21:24:14 2024 +0100
patch 9.1.0854: cannot get terminal cell size
Problem: cannot get terminal cell size
Solution: add getcellpixels() function to return xpixel * ypixel
cell size on terminal Unix (mikoto2000)
closes: #16004
Signed-off-by: mikoto2000 <mikoto2000@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 11 Nov 2024 21:30:03 +0100 |
parents | 6ab62967143b |
children | d8e94b51fb3d |
files | runtime/doc/builtin.txt runtime/doc/tags runtime/doc/usr_41.txt runtime/doc/version9.txt src/evalfunc.c src/os_unix.c src/os_unix.h src/proto/os_unix.pro src/testdir/test_utf8.vim src/version.c |
diffstat | 10 files changed, 112 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1,4 +1,4 @@ -*builtin.txt* For Vim version 9.1. Last change: 2024 Nov 10 +*builtin.txt* For Vim version 9.1. Last change: 2024 Nov 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -222,6 +222,7 @@ getbufline({buf}, {lnum} [, {end}]) getbufoneline({buf}, {lnum}) String line {lnum} of buffer {buf} getbufvar({buf}, {varname} [, {def}]) any variable {varname} in buffer {buf} +getcellpixels() List get character cell pixel size getcellwidths() List get character cell width overrides getchangelist([{buf}]) List list of change list items getchar([{expr}]) Number or String @@ -3786,6 +3787,15 @@ getbufvar({buf}, {varname} [, {def}]) Return type: any, depending on {varname} +getcellpixels() *getcellpixels()* + Returns a |List| of terminal cell pixel size. + List format is [xpixels, ypixels]. + Only works on Unix. For gVim and on other systems, + returns [-1, -1]. + + Return type: list<Number> + + getcellwidths() *getcellwidths()* Returns a |List| of cell widths of character ranges overridden by |setcellwidths()|. The format is equal to the argument of
--- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -7838,6 +7838,7 @@ getbufinfo() builtin.txt /*getbufinfo()* getbufline() builtin.txt /*getbufline()* getbufoneline() builtin.txt /*getbufoneline()* getbufvar() builtin.txt /*getbufvar()* +getcellpixels() builtin.txt /*getcellpixels()* getcellwidths() builtin.txt /*getcellwidths()* getchangelist() builtin.txt /*getchangelist()* getchar() builtin.txt /*getchar()*
--- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1,4 +1,4 @@ -*usr_41.txt* For Vim version 9.1. Last change: 2024 Oct 05 +*usr_41.txt* For Vim version 9.1. Last change: 2024 Nov 11 VIM USER MANUAL - by Bram Moolenaar @@ -778,6 +778,7 @@ String manipulation: *string-functio strdisplaywidth() size of string when displayed, deals with tabs setcellwidths() set character cell width overrides getcellwidths() get character cell width overrides + getcellpixels() get character cell pixel size reverse() reverse the order of characters in a string substitute() substitute a pattern match with a string submatch() get a specific match in ":s" and substitute() @@ -1394,6 +1395,7 @@ Various: *various-functions* did_filetype() check if a FileType autocommand was used diff() diff two Lists of strings eventhandler() check if invoked by an event handler + getcellpixels() get List of cell pixel size getpid() get process ID of Vim getscriptinfo() get list of sourced vim scripts getimstatus() check if IME status is active
--- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.1. Last change: 2024 Nov 06 +*version9.txt* For Vim version 9.1. Last change: 2024 Nov 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41621,6 +41621,7 @@ Functions: ~ |foreach()| apply function to List items |getcmdcomplpat()| Shell command line completion |getcmdprompt()| get prompt for input()/confirm() +|getcellpixels()| get List of terminal cell pixel size |getregion()| get a region of text from a buffer |getregionpos()| get a list of positions for a region |id()| get unique identifier for a Dict, List, Object,
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2077,6 +2077,14 @@ static funcentry_T global_functions[] = ret_string, f_getbufoneline}, {"getbufvar", 2, 3, FEARG_1, arg3_buffer_string_any, ret_any, f_getbufvar}, + {"getcellpixels", 0, 0, 0, NULL, + ret_list_any, +#if (defined(UNIX) || defined(VMS)) && (defined(FEAT_EVAL) || defined(PROTO)) + f_getcellpixels +#else + NULL +#endif + }, {"getcellwidths", 0, 0, 0, NULL, ret_list_any, f_getcellwidths}, {"getchangelist", 0, 1, FEARG_1, arg1_buffer,
--- a/src/os_unix.c +++ b/src/os_unix.c @@ -4348,6 +4348,68 @@ mch_get_shellsize(void) return OK; } +#if defined(FEAT_EVAL) || defined(PROTO) + void +f_getcellpixels(typval_T *argvars UNUSED, typval_T *rettv) +{ + struct cellsize cs; + mch_calc_cell_size(&cs); + + if (rettv_list_alloc(rettv) == FAIL) + return; + + list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_xpixel); + list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_ypixel); +} +#endif + +/* + * Try to get the current terminal cell size. + * If faile get cell size, fallback 5x10 pixel. + */ + void +mch_calc_cell_size(struct cellsize *cs_out) +{ +#if defined(FEAT_GUI) + if (!gui.in_use) + { +#endif + // get current tty size. + struct winsize ws; + int fd = 1; + int retval = -1; + retval = ioctl(fd, TIOCGWINSZ, &ws); +# ifdef FEAT_EVAL + ch_log(NULL, "ioctl(TIOCGWINSZ) %s", retval == 0 ? "success" : "failed"); +# endif + if (retval == -1) + { + cs_out->cs_xpixel = -1; + cs_out->cs_ypixel = -1; + return; + } + + // calculate parent tty's pixel per cell. + int x_cell_size = ws.ws_xpixel / ws.ws_col; + int y_cell_size = ws.ws_ypixel / ws.ws_row; + + // calculate current tty's pixel + cs_out->cs_xpixel = x_cell_size; + cs_out->cs_ypixel = y_cell_size; + +# ifdef FEAT_EVAL + ch_log(NULL, "Got cell pixel size with TIOCGWINSZ: %d x %d", x_cell_size, y_cell_size); +# endif +#if defined(FEAT_GUI) + } + else + { + cs_out->cs_xpixel = -1; + cs_out->cs_ypixel = -1; + } +#endif +} + #if defined(FEAT_TERMINAL) || defined(PROTO) /* * Report the windows size "rows" and "cols" to tty "fd". @@ -4367,8 +4429,13 @@ mch_report_winsize(int fd, int rows, int ws.ws_col = cols; ws.ws_row = rows; - ws.ws_xpixel = cols * 5; - ws.ws_ypixel = rows * 10; + + // calcurate and set tty pixel size + struct cellsize cs; + mch_calc_cell_size(&cs); + ws.ws_xpixel = cols * cs.cs_xpixel; + ws.ws_ypixel = rows * cs.cs_ypixel; + retval = ioctl(tty_fd, TIOCSWINSZ, &ws); ch_log(NULL, "ioctl(TIOCSWINSZ) %s", retval == 0 ? "success" : "failed"); # elif defined(TIOCSSIZE)
--- a/src/os_unix.h +++ b/src/os_unix.h @@ -488,3 +488,9 @@ int mch_rename(const char *src, const ch // We have three kinds of ACL support. #define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL || HAVE_AIX_ACL) + +struct cellsize { + unsigned int cs_xpixel; + unsigned int cs_ypixel; +}; +
--- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -91,4 +91,6 @@ void xsmp_close(void); void stop_timeout(void); volatile sig_atomic_t *start_timeout(long msec); void delete_timer(void); +void f_getcellpixels(typval_T *argvars UNUSED, typval_T *rettv); +void mch_calc_cell_size(struct cellsize *cs_out); /* vim: set ft=c : */
--- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -273,6 +273,14 @@ func Test_setcellwidths() bwipe! endfunc +" Pixel size of a cell is terminal-dependent, so in the test, only the list and size 2 are checked. +func Test_getcellpixels() + " Not yet Windows-compatible + CheckNotMSWindows + let cellpixels = getcellpixels() + call assert_equal(2, len(cellpixels)) +endfunc + func Test_getcellwidths() call setcellwidths([]) call assert_equal([], getcellwidths())