patch 9.1.1634: Clipboard code can be improved Commit: https://github.com/vim/vim/commit/126bc4690fb94c6628c704a3044bbc58d84dec42 Author: Foxe Chen <chen.f...@gmail.com> Date: Thu Aug 14 22:08:17 2025 +0200
patch 9.1.1634: Clipboard code can be improved Problem: Clipboard code can be improved Solution: Slightly refactor code (Foxe Chen). This commit does the following: - Use garray_T when receiving data instead of manually reallocing - formatting fixes - skip Wayland test that requires clientserver if x11 not compiled - Make some functions static closes: #17999 Signed-off-by: Foxe Chen <chen.f...@gmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/clipboard.c b/src/clipboard.c index a22b62145..55fa0ad9f 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -47,8 +47,12 @@ static const char *supported_mimes[] = { static void clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd); +static void clip_wl_request_selection(Clipboard_T *cbd); static void clip_wl_send_data(const char *mime_type, int fd, wayland_selection_T); +static int clip_wl_own_selection(Clipboard_T *cbd); +static void clip_wl_lose_selection(Clipboard_T *cbd); +static void clip_wl_set_selection(Clipboard_T *cbd); static void clip_wl_selection_cancelled(wayland_selection_T selection); #if defined(USE_SYSTEM) && defined(PROTO) @@ -2336,11 +2340,10 @@ adjust_clip_reg(int *rp) static void clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd) { - char_u *start, *buf, *tmp, *final, *enc; - int motion_type = MAUTO; - ssize_t r = 0; - size_t total = 0, max_total = 4096; // Initial buffer size, 4096 - // bytes seems reasonable. + char_u *start, *final, *enc; + garray_T buf; + int motion_type = MAUTO; + ssize_t r = 0; #ifndef HAVE_SELECT struct pollfd pfd @@ -2358,9 +2361,13 @@ clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd) if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == -1) return; - if ((buf = alloc_clear(max_total)) == NULL) + ga_init2(&buf, 1, 4096); + + // 4096 bytes seems reasonable for initial buffer size + if (ga_grow(&buf, 4096) == FAIL) return; - start = buf; + + start = buf.ga_data; // Only poll before reading when we first start, then we do non-blocking // reads and check for EAGAIN or EINTR to signal to poll again. @@ -2368,7 +2375,7 @@ clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd) while (errno = 0, TRUE) { - r = read(fd, start, max_total - 1 - total); + r = read(fd, start, buf.ga_maxlen - 1 - buf.ga_len); if (r == 0) break; @@ -2391,44 +2398,39 @@ poll_data: } start += r; - total += (size_t)r; + buf.ga_len += r; // Realloc if we are at the end of the buffer - if (total >= max_total - 1) + if (buf.ga_len >= buf.ga_maxlen - 1) { - tmp = vim_realloc(buf, max_total * 2); - if (tmp == NULL) + if (ga_grow(&buf, 8192) == FAIL) break; - max_total *= 2; // Double buffer size each time - buf = tmp; - start = buf + total; - // Zero out the newly allocated memory part - vim_memset(buf + total, 0, max_total - total); + start = buf.ga_data + buf.ga_len; } } - if (total == 0) + if (buf.ga_len == 0) { clip_free_selection(cbd); // Nothing received, clear register - vim_free(buf); + ga_clear(&buf); return; } - final = buf; + final = buf.ga_data; - if (STRCMP(mime_type, VIM_ATOM_NAME) == 0 && total >= 2) + if (STRCMP(mime_type, VIM_ATOM_NAME) == 0 && buf.ga_len >= 2) { motion_type = *final++;; - total--; + buf.ga_len--; } - else if (STRCMP(mime_type, VIMENC_ATOM_NAME) == 0 && total >= 3) + else if (STRCMP(mime_type, VIMENC_ATOM_NAME) == 0 && buf.ga_len >= 3) { - vimconv_T conv; - int convlen; + vimconv_T conv; + int convlen; // first byte is motion type motion_type = *final++; - total--; + buf.ga_len--; // Get encoding of selection enc = final; @@ -2437,30 +2439,32 @@ poll_data: final += STRLEN(final) + 1; // Subtract pointers to get length of encoding; - total -= final - enc; + buf.ga_len -= final - enc; conv.vc_type = CONV_NONE; convert_setup(&conv, enc, p_enc); if (conv.vc_type != CONV_NONE) { - convlen = total; + char_u *tmp; + + convlen = buf.ga_len; tmp = string_convert(&conv, final, &convlen); - total = convlen; + buf.ga_len = convlen; if (tmp != NULL) final = tmp; convert_setup(&conv, NULL, NULL); } } - clip_yank_selection(motion_type, final, (long)total, cbd); - vim_free(buf); + clip_yank_selection(motion_type, final, (long)buf.ga_len, cbd); + ga_clear(&buf); } /* * Get the current selection and fill the respective register for cbd with the * data. */ - void + static void clip_wl_request_selection(Clipboard_T *cbd) { wayland_selection_T selection; @@ -2646,7 +2650,7 @@ clip_wl_selection_cancelled(wayland_selection_T selection) * other Wayland clients so they can receive data from us. Returns OK on success * and FAIL on failure. */ - int + static int clip_wl_own_selection(Clipboard_T *cbd) { wayland_selection_T selection; @@ -2670,7 +2674,7 @@ clip_wl_own_selection(Clipboard_T *cbd) * Disown the selection that cbd corresponds to. Note that the the cancelled * event is not sent when the data source is destroyed. */ - void + static void clip_wl_lose_selection(Clipboard_T *cbd) { if (cbd == &clip_plus) @@ -2685,7 +2689,7 @@ clip_wl_lose_selection(Clipboard_T *cbd) * Send the current selection to the clipboard. Do nothing for Wayland because * we will fill in the selection only when requested by another client. */ - void + static void clip_wl_set_selection(Clipboard_T *cbd UNUSED) { } diff --git a/src/proto/clipboard.pro b/src/proto/clipboard.pro index e21f1e27e..9ccfea90a 100644 --- a/src/proto/clipboard.pro +++ b/src/proto/clipboard.pro @@ -35,10 +35,6 @@ int clip_convert_selection(char_u **str, long_u *len, Clipboard_T *cbd); int may_get_selection(int regname); void may_set_selection(void); void adjust_clip_reg(int *rp); -void clip_wl_request_selection(Clipboard_T *cbd); -int clip_wl_own_selection(Clipboard_T *cbd); -void clip_wl_lose_selection(Clipboard_T *cbd); -void clip_wl_set_selection(Clipboard_T *cbd); char *choose_clipmethod(void); void ex_clipreset(exarg_T *eap); /* vim: set ft=c : */ diff --git a/src/testdir/test_wayland.vim b/src/testdir/test_wayland.vim index 8aa9abcd2..b60934c37 100644 --- a/src/testdir/test_wayland.vim +++ b/src/testdir/test_wayland.vim @@ -52,16 +52,15 @@ endfunc " Need X connection for tests that use client server communication func s:CheckXConnection() - if has('x11') - try - call remote_send('xxx', '') - catch - if v:exception =~ 'E240:' - throw 'Skipped: no connection to the X server' - endif - " ignore other errors - endtry - endif + CheckFeature x11 + try + call remote_send('xxx', '') + catch + if v:exception =~ 'E240:' + thrclientserverow 'Skipped: no connection to the X server' + endif + " ignore other errors + endtry endfunc func s:EndRemoteVim(name, job) @@ -379,7 +378,7 @@ func Test_wayland_autoselect_works() call WaitForAssert({-> assert_equal("run", job_status(l:job))}) call WaitForAssert({-> assert_match(name, serverlist())}) - 1 + call remote_send(l:name, "ve") call WaitForAssert({-> assert_equal('LINE', system('wl-paste -p -n'))}) @@ -648,7 +647,6 @@ func Test_wayland_handle_large_data() call system('cmp --silent data_file data_file_cmp') call assert_equal(0, v:shell_error) - " copy the text call feedkeys('gg0v$G"+yy', 'x') call system('wl-paste -n -t TEXT > data_file') diff --git a/src/version.c b/src/version.c index f87ed0016..f4f6a6560 100644 --- a/src/version.c +++ b/src/version.c @@ -719,6 +719,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1634, /**/ 1633, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1umeLm-00F571-Vd%40256bit.org.