]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1999: clipboard provider does not respect 'clipboard' option v9.1.1999
authorFoxe Chen <chen.foxe@gmail.com>
Thu, 18 Dec 2025 20:47:34 +0000 (21:47 +0100)
committerChristian Brabandt <cb@256bit.org>
Thu, 18 Dec 2025 20:47:34 +0000 (21:47 +0100)
Problem:  clipboard provider does not respect 'clipboard' option
          (Satoru Kitaguchi, after v9.1.1972)
Solution: make clipboard provider register respect "unnamed/unnamedplus"
          from the 'clipboard' option value

fixes:  #18930
closes: #18952

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
17 files changed:
runtime/doc/change.txt
runtime/doc/eval.txt
runtime/doc/options.txt
runtime/doc/tags
src/clipboard.c
src/evalvars.c
src/globals.h
src/normal.c
src/ops.c
src/option.h
src/optiondefs.h
src/optionstr.c
src/proto/clipboard.pro
src/register.c
src/testdir/test_eval_stuff.vim
src/testdir/util/gen_opt_test.vim
src/version.c

index 7320460615deac3c0c430f2bf031efbafbbefdff..172bf494a60fbf4ba05f6eff27c4a6fce0c22595 100644 (file)
@@ -1,4 +1,4 @@
-*change.txt*   For Vim version 9.1.  Last change: 2025 Nov 09
+*change.txt*   For Vim version 9.1.  Last change: 2025 Dec 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1094,7 +1094,8 @@ inside of strings can change!  Also see 'softtabstop' option. >
                                                        *:y* *:yank* *E850*
 :[range]y[ank] [x]     Yank [range] lines [into register x].  Yanking to the
                        "* or "+ registers is possible only when the
-                       |+clipboard| feature is included.
+                       |+clipboard| or |+clipboard_provider| features are
+                       included.
 
 :[range]y[ank] [x] {count}
                        Yank {count} lines, starting with last line number
index 54a0cb67b1c9623e30adf1b39653da9f61595325..439e4529192c41b8cfae46103eadb2f8502261a1 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 17
+*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -5286,9 +5286,14 @@ Usage: >vim
 The clipboard provider feature allows the "+" |quoteplus| and "*" |quotestar|
 registers to be overridden by custom Vimscript functions.  There can be
 multiple providers, and Vim chooses which one to use based on 'clipmethod'.
-Despite the name, it does not use the 'clipboard' option and should be treated
-separate from the clipboard functionality.  It essentially overrides the
-existing behaviour of the clipboard registers.
+
+Despite the name, it should be treated separate from the clipboard
+functionality.  It essentially overrides the existing behaviour of the
+clipboard registers.
+
+                                               *clipboard-providers-clipboard*
+The clipboard provider feature will respect the "unnamed" and "unnamedplus"
+values in the 'clipboard' option.  Any other value will be ignored.
 
                                                *clipboard-providers-no-clipboard*
 If the |+clipboard| feature is not enabled, then the "+" and "*" registers
index 010b9a389fcf7ad7b6bd73f0eb46b2f4867b06ce..a8dbab912b0fa750786bf69d8840880fd1feb05c 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 13
+*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 18
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1815,13 +1815,19 @@ A jump table for the options with a short description can be found at |Q_op|.
                                                  for X-windows, "" otherwise)
                        global
                        {only in GUI versions or when the |+xterm_clipboard|
-                       or |+wayland_clipboard| features are included}
+                       or |+wayland_clipboard| features or
+                       |+clipboard_provider| features are included}
        This option is a list of comma-separated names.
        Note: if one of the items is "exclude:", then you can't add an item
        after that.  Therefore do not append an item with += but use ^= to
        prepend, e.g.: >
                set clipboard^=unnamed
 <      When using the GUI see |'go-A'|.
+       When using the |clipboard-providers| feature, only the "unamed" and
+       "unnamedplus" features will be recognized  If compiled without the
+       |+clipboard| feature but compiled with the |+clipboard_provider|
+       feature, then they will be the only values allowed and the other
+       values will be invalid.
        These names are recognized:
 
                                                *clipboard-unnamed*
@@ -1845,9 +1851,8 @@ A jump table for the options with a short description can be found at |Q_op|.
                        '*'.  If Wayland is being used and the compositor does
                        not support the primary selection then the regular
                        selection is used in its place.  Only available with
-                       the |+X11| or
-                       |+wayland_clipboard| feature.  Availability can be
-                       checked with: >
+                       the |+X11| or |+wayland_clipboard| feature.
+                       Availability can be checked with: >
                        if has('unnamedplus')
 <
                                                *clipboard-autoselect*
index 2f83c8a28dde150f720dfa286c68ee74db426c2f..684f392d56a5a1642ec3c2e194b2b87dc7f6f556 100644 (file)
@@ -6698,6 +6698,7 @@ clipboard-exclude options.txt     /*clipboard-exclude*
 clipboard-html options.txt     /*clipboard-html*
 clipboard-providers    eval.txt        /*clipboard-providers*
 clipboard-providers-available  eval.txt        /*clipboard-providers-available*
+clipboard-providers-clipboard  eval.txt        /*clipboard-providers-clipboard*
 clipboard-providers-clipmethod eval.txt        /*clipboard-providers-clipmethod*
 clipboard-providers-copy       eval.txt        /*clipboard-providers-copy*
 clipboard-providers-define     eval.txt        /*clipboard-providers-define*
index 6d321e5c0bb6d64a423a29b346dbb9099b19e2a8..1d46b56f0b0b52798e1d8e0017e0d4a09cc8893d 100644 (file)
@@ -1428,104 +1428,6 @@ clip_gen_owner_exists(Clipboard_T *cbd UNUSED)
 }
 #endif
 
-/*
- * Extract the items in the 'clipboard' option and set global values.
- * Return an error message or NULL for success.
- */
-    char *
-did_set_clipboard(optset_T *args UNUSED)
-{
-    int                new_unnamed = 0;
-    int                new_autoselect_star = FALSE;
-    int                new_autoselect_plus = FALSE;
-    int                new_autoselectml = FALSE;
-    int                new_html = FALSE;
-    regprog_T  *new_exclude_prog = NULL;
-    char       *errmsg = NULL;
-    char_u     *p;
-
-    for (p = p_cb; *p != NUL; )
-    {
-       // Note: Keep this in sync with p_cb_values.
-       if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
-       {
-           new_unnamed |= CLIP_UNNAMED;
-           p += 7;
-       }
-       else if (STRNCMP(p, "unnamedplus", 11) == 0
-                                           && (p[11] == ',' || p[11] == NUL))
-       {
-           new_unnamed |= CLIP_UNNAMED_PLUS;
-           p += 11;
-       }
-       else if (STRNCMP(p, "autoselect", 10) == 0
-                                           && (p[10] == ',' || p[10] == NUL))
-       {
-           new_autoselect_star = TRUE;
-           p += 10;
-       }
-       else if (STRNCMP(p, "autoselectplus", 14) == 0
-                                           && (p[14] == ',' || p[14] == NUL))
-       {
-           new_autoselect_plus = TRUE;
-           p += 14;
-       }
-       else if (STRNCMP(p, "autoselectml", 12) == 0
-                                           && (p[12] == ',' || p[12] == NUL))
-       {
-           new_autoselectml = TRUE;
-           p += 12;
-       }
-       else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
-       {
-           new_html = TRUE;
-           p += 4;
-       }
-       else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
-       {
-           p += 8;
-           new_exclude_prog = vim_regcomp(p, RE_MAGIC);
-           if (new_exclude_prog == NULL)
-               errmsg = e_invalid_argument;
-           break;
-       }
-       else
-       {
-           errmsg = e_invalid_argument;
-           break;
-       }
-       if (*p == ',')
-           ++p;
-    }
-    if (errmsg == NULL)
-    {
-       if (global_busy)
-           // clip_unnamed will be reset to clip_unnamed_saved
-           // at end_global_changes
-           clip_unnamed_saved = new_unnamed;
-       else
-           clip_unnamed = new_unnamed;
-       clip_autoselect_star = new_autoselect_star;
-       clip_autoselect_plus = new_autoselect_plus;
-       clip_autoselectml = new_autoselectml;
-       clip_html = new_html;
-       vim_regfree(clip_exclude_prog);
-       clip_exclude_prog = new_exclude_prog;
-#ifdef FEAT_GUI_GTK
-       if (gui.in_use)
-       {
-           gui_gtk_set_selection_targets((GdkAtom)GDK_SELECTION_PRIMARY);
-           gui_gtk_set_selection_targets((GdkAtom)clip_plus.gtk_sel_atom);
-           gui_gtk_set_dnd_targets();
-       }
-#endif
-    }
-    else
-       vim_regfree(new_exclude_prog);
-
-    return errmsg;
-}
-
 /*
  * Stuff for the X clipboard.  Shared between VMS and Unix.
  */
@@ -2394,32 +2296,6 @@ may_set_selection(void)
     }
 }
 
-/*
- * Adjust the register name pointed to with "rp" for the clipboard being
- * used always and the clipboard being available.
- */
-    void
-adjust_clip_reg(int *rp)
-{
-    // If no reg. specified, and "unnamed" or "unnamedplus" is in 'clipboard',
-    // use '*' or '+' reg, respectively. "unnamedplus" prevails.
-    if (*rp == 0 && (clip_unnamed != 0 || clip_unnamed_saved != 0))
-    {
-       if (clip_unnamed != 0)
-           *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available)
-                                                                 ? '+' : '*';
-       else
-           *rp = ((clip_unnamed_saved & CLIP_UNNAMED_PLUS)
-                                          && clip_plus.available) ? '+' : '*';
-    }
-    if ((!clip_star.available && *rp == '*') ||
-          (!clip_plus.available && *rp == '+'))
-    {
-       msg_warn_missing_clipboard();
-       *rp = 0;
-    }
-}
-
 #if defined(FEAT_WAYLAND_CLIPBOARD)
 
     static clip_wl_selection_T *
@@ -3483,7 +3359,7 @@ get_clipmethod(char_u *str)
        }
        else
        {
-#ifdef FEAT_EVAL
+#ifdef FEAT_CLIPBOARD_PROVIDER
            // Check if name matches a clipboard provider
            int r = clip_provider_is_available(buf);
 
@@ -3501,7 +3377,7 @@ get_clipmethod(char_u *str)
            else if (r == -1)
 #endif
            {
-#ifdef FEAT_EVAL
+#ifdef FEAT_CLIPBOARD_PROVIDER
 fail:
 #endif
                ret = CLIPMETHOD_FAIL;
@@ -3648,6 +3524,148 @@ ex_clipreset(exarg_T *eap UNUSED)
                clipmethod_to_str(clipmethod));
 }
 
+/*
+ * Adjust the register name pointed to with "rp" for the clipboard being
+ * used always and the clipboard being available.
+ */
+    void
+adjust_clip_reg(int *rp)
+{
+#ifdef FEAT_CLIPBOARD_PROVIDER
+    if (clipmethod == CLIPMETHOD_PROVIDER)
+    {
+       if (clip_unnamed != 0)
+           *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS)) ? '+' : '*';
+       return;
+    }
+#endif
+#ifdef FEAT_CLIPBOARD
+    // If no reg. specified, and "unnamed" or "unnamedplus" is in 'clipboard',
+    // use '*' or '+' reg, respectively. "unnamedplus" prevails.
+    if (*rp == 0 && (clip_unnamed != 0 || clip_unnamed_saved != 0))
+    {
+       if (clip_unnamed != 0)
+           *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available)
+                                                                 ? '+' : '*';
+       else
+           *rp = ((clip_unnamed_saved & CLIP_UNNAMED_PLUS)
+                                          && clip_plus.available) ? '+' : '*';
+    }
+    if ((!clip_star.available && *rp == '*') ||
+          (!clip_plus.available && *rp == '+'))
+    {
+       msg_warn_missing_clipboard();
+       *rp = 0;
+    }
+#endif
+}
+
+/*
+ * Extract the items in the 'clipboard' option and set global values.
+ * Return an error message or NULL for success.
+ */
+    char *
+did_set_clipboard(optset_T *args UNUSED)
+{
+    int                new_unnamed = 0;
+#ifdef FEAT_CLIPBOARD
+    int                new_autoselect_star = FALSE;
+    int                new_autoselect_plus = FALSE;
+    int                new_autoselectml = FALSE;
+    int                new_html = FALSE;
+#endif
+    regprog_T  *new_exclude_prog = NULL;
+    char       *errmsg = NULL;
+    char_u     *p;
+
+    for (p = p_cb; *p != NUL; )
+    {
+       // Note: Keep this in sync with p_cb_values.
+       if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
+       {
+           new_unnamed |= CLIP_UNNAMED;
+           p += 7;
+       }
+       else if (STRNCMP(p, "unnamedplus", 11) == 0
+                                           && (p[11] == ',' || p[11] == NUL))
+       {
+           new_unnamed |= CLIP_UNNAMED_PLUS;
+           p += 11;
+       }
+#ifdef FEAT_CLIPBOARD
+       else if (STRNCMP(p, "autoselect", 10) == 0
+                                           && (p[10] == ',' || p[10] == NUL))
+       {
+           new_autoselect_star = TRUE;
+           p += 10;
+       }
+       else if (STRNCMP(p, "autoselectplus", 14) == 0
+                                           && (p[14] == ',' || p[14] == NUL))
+       {
+           new_autoselect_plus = TRUE;
+           p += 14;
+       }
+       else if (STRNCMP(p, "autoselectml", 12) == 0
+                                           && (p[12] == ',' || p[12] == NUL))
+       {
+           new_autoselectml = TRUE;
+           p += 12;
+       }
+       else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
+       {
+           new_html = TRUE;
+           p += 4;
+       }
+       else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
+       {
+           p += 8;
+           new_exclude_prog = vim_regcomp(p, RE_MAGIC);
+           if (new_exclude_prog == NULL)
+               errmsg = e_invalid_argument;
+           break;
+       }
+#endif
+       else
+       {
+           errmsg = e_invalid_argument;
+           break;
+       }
+       if (*p == ',')
+           ++p;
+    }
+    if (errmsg == NULL)
+    {
+#ifdef FEAT_CLIPBOARD
+       if (global_busy)
+           // clip_unnamed will be reset to clip_unnamed_saved
+           // at end_global_changes
+           clip_unnamed_saved = new_unnamed;
+       else
+#endif
+           clip_unnamed = new_unnamed;
+#ifdef FEAT_CLIPBOARD
+       clip_autoselect_star = new_autoselect_star;
+       clip_autoselect_plus = new_autoselect_plus;
+       clip_autoselectml = new_autoselectml;
+       clip_html = new_html;
+       vim_regfree(clip_exclude_prog);
+       clip_exclude_prog = new_exclude_prog;
+#endif
+#ifdef FEAT_GUI_GTK
+       if (gui.in_use)
+       {
+           gui_gtk_set_selection_targets((GdkAtom)GDK_SELECTION_PRIMARY);
+           gui_gtk_set_selection_targets((GdkAtom)clip_plus.gtk_sel_atom);
+           gui_gtk_set_dnd_targets();
+       }
+#endif
+    }
+    else
+       vim_regfree(new_exclude_prog);
+
+    return errmsg;
+}
+
 #endif // HAVE_CLIPMETHOD
 
 #ifdef FEAT_CLIPBOARD_PROVIDER
index 2e01085342e08c28d67c133ee51adb74a69f9da0..406417771a750178a09d18a34e44664f0cd79457 100644 (file)
@@ -2986,7 +2986,7 @@ reset_reg_var(void)
 
     // Adjust the register according to 'clipboard', so that when
     // "unnamed" is present it becomes '*' or '+' instead of '"'.
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
     adjust_clip_reg(&regname);
 #endif
     set_reg_var(regname);
index ed4affa8c002225cd5581ab0731fb06d1a34f839..9b101d8f20bf3f99ee276a0da4423af1beb795c8 100644 (file)
@@ -980,17 +980,21 @@ EXTERN Clipboard_T clip_plus;     // CLIPBOARD selection in X11/Wayland
 #  define clip_plus clip_star  // there is only one clipboard
 #  define ONE_CLIPBOARD
 # endif
+#endif
 
+#ifdef HAVE_CLIPMETHOD
 # define CLIP_UNNAMED      1
 # define CLIP_UNNAMED_PLUS 2
 EXTERN int     clip_unnamed INIT(= 0); // above two values or'ed
 
+# ifdef FEAT_CLIPBOARD
 EXTERN int     clip_autoselect_star INIT(= FALSE);
 EXTERN int     clip_autoselect_plus INIT(= FALSE);
 EXTERN int     clip_autoselectml INIT(= FALSE);
 EXTERN int     clip_html INIT(= FALSE);
 EXTERN regprog_T *clip_exclude_prog INIT(= NULL);
 EXTERN int     clip_unnamed_saved INIT(= 0);
+# endif
 #endif
 
 #ifdef FEAT_CLIPBOARD_PROVIDER
index 59843293e59a67a86323e1f96a634dd5a330587b..2f2a560179bd09574a58338f06d4d640a6dc9b07 100644 (file)
@@ -7425,7 +7425,7 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
        was_visual = TRUE;
        regname = cap->oap->regname;
        keep_registers = cap->cmdchar == 'P';
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
        adjust_clip_reg(&regname);
 #endif
        if (regname == 0 || regname == '"'
index 7e1bb1bfb494697ebd73d36d27ca8526efd45131..a7f0f041d0208a60d769479281b139db1cb7b40c 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -800,7 +800,7 @@ op_delete(oparg_T *oap)
        // use register given with CTRL_R, defaults to zero
        oap->regname = VIsual_select_reg;
 
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
     adjust_clip_reg(&oap->regname);
 #endif
 
@@ -857,12 +857,18 @@ op_delete(oparg_T *oap)
      */
     if (oap->regname != '_')
     {
+#ifdef FEAT_CLIPBOARD_PROVIDER
+       inc_clip_provider();
+#endif
        if (oap->regname != 0)
        {
            // check for read-only register
            if (!valid_yank_reg(oap->regname, TRUE))
            {
                beep_flush();
+#ifdef FEAT_CLIPBOARD_PROVIDER
+               dec_clip_provider();
+#endif
                return OK;
            }
            get_yank_register(oap->regname, TRUE); // yank into specif'd reg.
@@ -888,7 +894,7 @@ op_delete(oparg_T *oap)
        // Yank into small delete register when no named register specified
        // and the delete is within one line.
        if ((
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
            ((clip_unnamed & CLIP_UNNAMED) && oap->regname == '*') ||
            ((clip_unnamed & CLIP_UNNAMED_PLUS) && oap->regname == '+') ||
 #endif
@@ -918,6 +924,9 @@ op_delete(oparg_T *oap)
            if (n != 'y')
            {
                emsg(_(e_command_aborted));
+#ifdef FEAT_CLIPBOARD_PROVIDER
+               dec_clip_provider();
+#endif
                return FAIL;
            }
        }
@@ -925,6 +934,9 @@ op_delete(oparg_T *oap)
 #if defined(FEAT_EVAL)
        if (did_yank && has_textyankpost())
            yank_do_autocmd(oap, get_y_current());
+#endif
+#ifdef FEAT_CLIPBOARD_PROVIDER
+       dec_clip_provider();
 #endif
     }
 
index 87096fa60b6a68e2119f99ffde1a5d79719ecde3..55dbf8a566a58bf93b190b25b7598e4e8f7c767a 100644 (file)
@@ -505,10 +505,8 @@ EXTERN int p_cdh;          // 'cdhome'
 EXTERN char_u  *p_cino;        // 'cinoptions'
 EXTERN char_u  *p_cedit;       // 'cedit'
 EXTERN long    p_cwh;          // 'cmdwinheight'
-#ifdef FEAT_CLIPBOARD
-EXTERN char_u  *p_cb;          // 'clipboard'
-#endif
 #ifdef HAVE_CLIPMETHOD
+EXTERN char_u  *p_cb;          // 'clipboard'
 EXTERN char_u  *p_cpm;         // 'clipmethod'
 #endif
 EXTERN long    p_ch;           // 'cmdheight'
index 81d9ff76e7ff0fae78a79ce05c63f76577354b6e..d888615f539d1ce914091416791036c02ffa651b 100644 (file)
@@ -618,7 +618,7 @@ static struct vimoption options[] =
                                (char_u *)0L}
                            SCTX_INIT},
     {"clipboard",   "cb",   P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
                            (char_u *)&p_cb, PV_NONE, did_set_clipboard, expand_set_clipboard,
 # if defined(FEAT_XCLIPBOARD) || defined(FEAT_WAYLAND_CLIPBOARD)
                            {(char_u *)"autoselect,exclude:cons\\|linux",
index 42e09b3c949954f261bb884505447743f5588861..84f9734428dd4009fdfe99f00dd9e3640aab7fda 100644 (file)
@@ -41,9 +41,13 @@ static char *(p_dip_inline_values[]) = {"none", "simple", "char", "word", NULL};
 #endif
 static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", "blank", NULL};
 static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
 // Note: Keep this in sync with did_set_clipboard()
-static char *(p_cb_values[]) = {"unnamed", "unnamedplus", "autoselect", "autoselectplus", "autoselectml", "html", "exclude:", NULL};
+static char *(p_cb_values[]) = {"unnamed", "unnamedplus",
+# ifdef FEAT_CLIPBOARD
+    "autoselect", "autoselectplus", "autoselectml", "html", "exclude:",
+# endif
+    NULL};
 #endif
 #ifdef FEAT_CRYPT
 static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2",
@@ -1389,7 +1393,7 @@ expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches)
            matches);
 }
 
-#if defined(FEAT_CLIPBOARD)
+#if defined(HAVE_CLIPMETHOD)
     int
 expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches)
 {
index 6ada18c9e7e7abd6cfa2482b4b36a66545157170..5bcaf2ce99ceddafe91730ac0cfc964de33b58e8 100644 (file)
@@ -18,7 +18,6 @@ void clip_scroll_selection(int rows);
 void clip_copy_modeless_selection(int both);
 void clip_gen_set_selection(Clipboard_T *cbd);
 int clip_gen_owner_exists(Clipboard_T *cbd);
-char *did_set_clipboard(optset_T *args);
 void open_app_context(void);
 void x11_setup_atoms(Display *dpy);
 void x11_setup_selection(Widget w);
@@ -34,12 +33,13 @@ void clip_yank_selection(int type, char_u *str, long len, Clipboard_T *cbd);
 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);
 int clip_init_wayland(void);
 void clip_uninit_wayland(void);
 int clip_reset_wayland(void);
 char *choose_clipmethod(void);
 void ex_clipreset(exarg_T *eap);
+void adjust_clip_reg(int *rp);
+char *did_set_clipboard(optset_T *args);
 void call_clip_provider_request(int reg);
 void call_clip_provider_set(int reg);
 void inc_clip_provider(void);
index 12fe8ebb149b9bd0448f3c1c30726e51cc8773ee..90abbcc54b33856a44dc8207e5e0b24ebc31c952 100644 (file)
@@ -33,7 +33,7 @@ static int    stuff_yank(int, char_u *);
 static void    put_reedit_in_typebuf(int silent);
 static int     put_in_typebuf(char_u *s, int esc, int colon, int silent);
 static int     yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space);
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
 static void    copy_yank_reg(yankreg_T *reg);
 #endif
 static void    dis_msg(char_u *p, int skip_esc);
@@ -1421,10 +1421,20 @@ op_yank(oparg_T *oap, int deleting, int mess)
 
 #ifdef FEAT_CLIPBOARD_PROVIDER
     inc_clip_provider();
-    if (curr == &y_regs[REAL_PLUS_REGISTER])
+    if (curr == &y_regs[REAL_PLUS_REGISTER] || (!deleting && oap->regname == 0
+               && (clip_unnamed & CLIP_UNNAMED_PLUS)))
+    {
+       if (curr != &(y_regs[REAL_PLUS_REGISTER]))
+           copy_yank_reg(&(y_regs[REAL_PLUS_REGISTER]));
        call_clip_provider_set('+');
-    else if (curr == &y_regs[STAR_REGISTER])
+    }
+    if (curr == &y_regs[STAR_REGISTER] || (!deleting && oap->regname == 0
+               && (clip_unnamed & CLIP_UNNAMED)))
+    {
+       if (curr != &(y_regs[STAR_REGISTER]))
+           copy_yank_reg(&(y_regs[STAR_REGISTER]));
        call_clip_provider_set('*');
+    }
 #endif
 
 #ifdef FEAT_CLIPBOARD
@@ -1518,7 +1528,7 @@ yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space)
     return OK;
 }
 
-#ifdef FEAT_CLIPBOARD
+#ifdef HAVE_CLIPMETHOD
 /*
  * Make a copy of the y_current register to register "reg".
  */
@@ -1589,16 +1599,16 @@ do_put(
     pos_T      orig_end = curbuf->b_op_end;
     unsigned int cur_ve_flags = get_ve_flags();
 
+#ifdef HAVE_CLIPMETHOD
+    adjust_clip_reg(&regname);
+#endif
 #ifdef FEAT_CLIPBOARD_PROVIDER
     call_clip_provider_request(regname);
 #endif
 #ifdef FEAT_CLIPBOARD
     if (clipmethod != CLIPMETHOD_PROVIDER)
-    {
        // Adjust register name for "unnamed" in 'clipboard'.
-       adjust_clip_reg(&regname);
        (void)may_get_selection(regname);
-    }
 #endif
 
 
@@ -2458,18 +2468,18 @@ ex_display(exarg_T *eap)
                )
            continue;       // did not ask for this register
 
+#ifdef HAVE_CLIPMETHOD
+       adjust_clip_reg(&name);
+#endif
 #ifdef FEAT_CLIPBOARD_PROVIDER
        call_clip_provider_request(name);
 #endif
 #ifdef FEAT_CLIPBOARD
        if (clipmethod != CLIPMETHOD_PROVIDER)
-       {
            // Adjust register name for "unnamed" in 'clipboard'.
            // When it's a clipboard register, fill it with the current contents
            // of the clipboard.
-           adjust_clip_reg(&name);
            (void)may_get_selection(name);
-       }
 #endif
 
        if (i == -1)
index c1a27abba5b3ce81f472a38c5de2574a83963732..3da9ee303e2f7d7c18c9fd25538d3d7789ef09f4 100644 (file)
@@ -1100,7 +1100,31 @@ func Test_clipboard_provider_accessed_once()
   call assert_equal(0, g:vim_paste_count['*'])
 
   bw!
+
+  new
+  " Test same for changing and deleting text when 'clipboard' is
+  " unnamed/unnamedplus.
+  let g:vim_paste_count = {'*': 0, '+': 0}
+  let g:vim_copy_count = {'*': 0, '+': 0}
+
+  set clipboard=unnamed
+  call setline(1, "testing")
+  normal cw
+
+  call assert_equal(0, g:vim_paste_count['*'])
+  call assert_equal(1, g:vim_copy_count['*'])
+
+  set clipboard=unnamedplus
+  call setline(1, "testing")
+  normal dw
+
+  call assert_equal(0, g:vim_paste_count['+'])
+  call assert_equal(1, g:vim_copy_count['+'])
+
+  bw!
+
   set clipmethod&
+  set clipboard&
 endfunc
 
 " Test if the copying does not call the paste callback, and pasting does not all
@@ -1194,4 +1218,73 @@ func Test_clipboard_provider_redir_execute()
   set clipmethod&
 endfunc
 
+" Test if clipboard provider feature respects the "unnamed" and "unnamedplus"
+" values in the 'clipboard' option
+func Test_clipboard_provider_clipboard_option()
+  CheckFeature clipboard_provider
+
+  let v:clipproviders["test"] = {
+        \ "paste": {
+        \       '+': function("s:Paste"),
+        \       '*': function("s:Paste")
+        \   },
+        \ "copy": {
+        \       '+': function("s:Copy"),
+        \       '*': function("s:Copy")
+        \   }
+        \ }
+  set clipmethod=test
+  let g:vim_paste = "tuple"
+
+  new
+
+  call setline(1, "hello world!")
+
+  set clipboard=unnamed
+
+  yank
+  call assert_equal("*",g:vim_copy.reg)
+  call assert_equal(["hello world!"], g:vim_copy.lines)
+  call assert_equal("V", g:vim_copy.type)
+
+  put
+  call assert_equal(["a", "tuple", "*"], getline(2, 4))
+
+  set clipboard=unnamedplus
+
+  call cursor(1, 0)
+  yank
+  call assert_equal("+",g:vim_copy.reg)
+  call assert_equal(["hello world!"], g:vim_copy.lines)
+  call assert_equal("V", g:vim_copy.type)
+
+  put
+  call assert_equal(["a", "tuple", "+"], getline(2, 4))
+
+  set clipboard=unnamed,unnamedplus
+
+  call setline(1, "testing")
+  call cursor(1, 0)
+  yank
+  call assert_equal(["testing"], g:vim_copy.lines)
+  call assert_equal(["testing"], g:vim_copy.lines)
+
+  " Change and delete operations are tested in
+  " Test_clipboard_provider_accessed_once()
+  bw!
+
+  " Check if only "unnamed" and "unnamedplus" values are allowed when no
+  " +clipboard feature (including cmdline expansion).
+  if !has('clipboard')
+    call assert_fails("set clipboard=autoselect", "E474:")
+
+    call assert_equal(["unnamed,unnamedplus", "unnamed", "unnamedplus"],
+          \ getcompletion('set clipboard=', 'cmdline'))
+  endif
+
+  set clipmethod&
+  set clipboard&
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
index 7c7a0ce4720f5321ff6d3e1ce3129f9e751d5595..51ff726d34b353e0df9c98b57ac6d3f173862311 100644 (file)
@@ -370,6 +370,15 @@ let test_values = {
       \ 'otherstring': [['', 'xxx'], []],
       \}
 
+if !has('clipboard')
+  " If +clipboard isn't enabled but +clipboard_provider is, then 'clipboard' is
+  " limited to "unnamed" and "unnamedplus"
+  let test_values['clipboard'] = [
+       \ ['', 'unnamed', 'unnamedplus'],
+       \ ['xxx', 'autoselect', 'exclude:\\%(']
+       \ ]
+endif
+
 " Two lists with values: values that pre- and post-processing in test.
 " Clear out t_WS: we don't want to resize the actual terminal.
 let test_prepost = {
index 39b6496e3ba37aa724ddd17413a6572d0f074dcb..c7d4d473226a83abee18e989cedc395b7a26ee7c 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1999,
 /**/
     1998,
 /**/