]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1634: Clipboard code can be improved v9.1.1634
authorFoxe Chen <chen.foxe@gmail.com>
Thu, 14 Aug 2025 20:08:17 +0000 (22:08 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 14 Aug 2025 20:09:45 +0000 (22:09 +0200)
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.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/clipboard.c
src/proto/clipboard.pro
src/testdir/test_wayland.vim
src/version.c

index a22b6214522d101aebe0be52173d49b29437b3f1..55fa0ad9f04b3662f67648175d5375e5bb48e44c 100644 (file)
@@ -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)
 {
 }
index e21f1e27eaeeea7e4712e3e0e6c18198fcc04f17..9ccfea90a63d24a1c8e1329739de038a6e6a2004 100644 (file)
@@ -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 : */
index 8aa9abcd2b71923f98a74c1c6eec76d6bfc085f7..b60934c37039e60231b959b254d4501cce9613dd 100644 (file)
@@ -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')
 
index f87ed0016acc394e0f0c26ae557280e6ac847bad..f4f6a65607d08c58717eb9ef85d023d054870612 100644 (file)
@@ -719,6 +719,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1634,
 /**/
     1633,
 /**/