From a73dfc2f550155d676372c713011e6227245e9dc Mon Sep 17 00:00:00 2001 From: mikoto2000 Date: Mon, 18 Nov 2024 21:12:21 +0100 Subject: [PATCH] patch 9.1.0871: getcellpixels() can be further improved Problem: getcellpixels() can be further improved Solution: Fix floating point exception, implement getcellpixels() in the UI (mikoto2000) closes: #16059 Signed-off-by: mikoto2000 Signed-off-by: Christian Brabandt --- runtime/doc/builtin.txt | 11 +++++--- src/evalfunc.c | 48 +++++++++++++++++++++++++++++----- src/os_unix.c | 28 +------------------- src/os_unix.h | 6 ----- src/proto/os_unix.pro | 1 - src/structs.h | 8 ++++++ src/testdir/test_functions.vim | 28 +++++++++++++++----- src/version.c | 2 ++ 8 files changed, 82 insertions(+), 50 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index ab63681980..e763da065f 100644 --- 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 14 +*builtin.txt* For Vim version 9.1. Last change: 2024 Nov 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -3790,8 +3790,13 @@ getbufvar({buf}, {varname} [, {def}]) *getbufvar()* getcellpixels() *getcellpixels()* Returns a |List| of terminal cell pixel size. List format is [xpixels, ypixels]. - Only works on (terminal) Unix. For gVim, on other systems and - on failure returns []. + + Only works on Unix (terminal and gVim) and Windows (gVim only). + Returns [] on other systems or on failure. + Note that there could be variations across different terminals. + On macOS, system Terminal.app returns sizes in points (before + Retina scaling), whereas third-party terminals return raw pixel + sizes (post Retina scaling). Return type: list diff --git a/src/evalfunc.c b/src/evalfunc.c index 12f7a88b00..b2905da2a9 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -61,6 +61,7 @@ static void f_funcref(typval_T *argvars, typval_T *rettv); static void f_function(typval_T *argvars, typval_T *rettv); static void f_garbagecollect(typval_T *argvars, typval_T *rettv); static void f_get(typval_T *argvars, typval_T *rettv); +static void f_getcellpixels(typval_T *argvars, typval_T *rettv); static void f_getchangelist(typval_T *argvars, typval_T *rettv); static void f_getcharpos(typval_T *argvars, typval_T *rettv); static void f_getcharsearch(typval_T *argvars, typval_T *rettv); @@ -2078,13 +2079,7 @@ static funcentry_T global_functions[] = {"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 - }, + ret_list_any, f_getcellpixels}, {"getcellwidths", 0, 0, 0, NULL, ret_list_any, f_getcellwidths}, {"getchangelist", 0, 1, FEARG_1, arg1_buffer, @@ -5216,6 +5211,45 @@ f_get(typval_T *argvars, typval_T *rettv) copy_tv(tv, rettv); } +/* + * "getcellpixels()" function + */ + static void +f_getcellpixels(typval_T *argvars UNUSED, typval_T *rettv) +{ + if (rettv_list_alloc(rettv) == FAIL) + return; + +#if defined(FEAT_GUI) + if (gui.in_use) + { + // success pixel size and no gui. + list_append_number(rettv->vval.v_list, (varnumber_T)gui.char_width); + list_append_number(rettv->vval.v_list, (varnumber_T)gui.char_height); + } + else +#endif + { + struct cellsize cs; +#if defined(UNIX) + mch_calc_cell_size(&cs); +#else + // Non-Unix CUIs are not supported, so set this to -1x-1. + cs.cs_xpixel = -1; + cs.cs_ypixel = -1; +#endif + + // failed get pixel size. + if (cs.cs_xpixel == -1) + return; + + // success pixel size and no gui. + list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_xpixel); + list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_ypixel); + } + +} + /* * "getchangelist()" function */ diff --git a/src/os_unix.c b/src/os_unix.c index 80ca0ce26d..dc518fc676 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4348,32 +4348,6 @@ 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; - - // failed get pixel size. - if (cs.cs_xpixel == -1) - return; - -#if defined(FEAT_GUI) - // gui return []. - if (gui.in_use) - return; -#endif - - // success pixel size and no gui. - 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. * On failure, returns -1x-1 @@ -4391,7 +4365,7 @@ mch_calc_cell_size(struct cellsize *cs_out) ch_log(NULL, "ioctl(TIOCGWINSZ) %s", retval == 0 ? "success" : "failed"); #endif - if (retval == -1) + if (retval == -1 || ws.ws_col == 0 || ws.ws_row == 0) { cs_out->cs_xpixel = -1; cs_out->cs_ypixel = -1; diff --git a/src/os_unix.h b/src/os_unix.h index f017d56829..5ba64fd2f9 100644 --- a/src/os_unix.h +++ b/src/os_unix.h @@ -489,9 +489,3 @@ 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) -// Defined as signed, to return -1 on error -struct cellsize { - int cs_xpixel; - int cs_ypixel; -}; - diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index be4942d291..4b1257ba80 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -91,6 +91,5 @@ 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 : */ diff --git a/src/structs.h b/src/structs.h index 19768e6580..dcb8978fed 100644 --- a/src/structs.h +++ b/src/structs.h @@ -5099,3 +5099,11 @@ typedef struct #define KEYVALUE_ENTRY(k, v) \ {(k), {((char_u *)v), STRLEN_LITERAL(v)}} + +#if defined(UNIX) || defined(MSWIN) +// Defined as signed, to return -1 on error +struct cellsize { + int cs_xpixel; + int cs_ypixel; +}; +#endif diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index f555621041..8b2518f2bc 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -4160,10 +4160,9 @@ func Test_slice() endfunc -" Test for getcellpixels() +" Test for getcellpixels() for unix system " 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 +func Test_getcellpixels_for_unix() CheckNotMSWindows CheckRunVimInTerminal @@ -4180,13 +4179,30 @@ func Test_getcellpixels() call StopVimInTerminal(buf) endfunc +" Test for getcellpixels() for windows system +" Windows terminal vim is not support. check return `[]`. +func Test_getcellpixels_for_windows() + CheckMSWindows + CheckRunVimInTerminal + + let buf = RunVimInTerminal('', #{rows: 6}) + + " write getcellpixels() result to current buffer. + call term_sendkeys(buf, ":redi @\"\") + call term_sendkeys(buf, ":echo getcellpixels()\") + call term_sendkeys(buf, ":redi END\") + call term_sendkeys(buf, "P") + + call WaitForAssert({-> assert_match("\[\]", term_getline(buf, 3))}, 1000) + + call StopVimInTerminal(buf) +endfunc + " Test for getcellpixels() on gVim func Test_getcellpixels_gui() - " Not yet Windows-compatible - CheckNotMSWindows if has("gui_running") let cellpixels = getcellpixels() - call assert_equal(0, len(cellpixels)) + call assert_equal(2, len(cellpixels)) endif endfunc diff --git a/src/version.c b/src/version.c index ce6c38a327..dbd5fc68a8 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 871, /**/ 870, /**/