0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

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>
This commit is contained in:
mikoto2000
2024-11-11 21:24:14 +01:00
committed by Christian Brabandt
parent 6fbf63de86
commit 1083cae709
10 changed files with 112 additions and 5 deletions

View File

@@ -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}]) *getbufvar()*
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

View File

@@ -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()*

View File

@@ -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-functions*
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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 cols)
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)

View File

@@ -488,3 +488,9 @@ int mch_rename(const char *src, const char *dest);
// 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;
};

View File

@@ -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 : */

View File

@@ -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())

View File

@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
854,
/**/
853,
/**/