BUG: :set clipboard=unnamed makes small deletes clobber the number registers

166 views
Skip to first unread message

Ingo Karkat

unread,
Sep 3, 2012, 11:25:57 AM9/3/12
to vim...@googlegroups.com
Hello Vim developers,

This issue came up on Reddit
(http://www.reddit.com/r/vim/comments/yyq4a/is_there_anyway_to_configure_vim_to_use_the/).

With :set clipboard=unnamed, small deletes (such as "dw") affect the named
registers "1.."9. I can reproduce this with vanilla Vim 7.3.000 on Windows/x86,
and the latest Vim 7.3.646 on Ubuntu/x86.

It appears that the setting triggers the exception from the rule "This register
("-) contains text from commands that delete less than one line, except when the
command specifies a register with ["x].", although the register here comes from
the implementation, not the user.

Based on the Reddit posting, some people apparently prefer this behavior (though
I personally dislike that multiple "x" commands will rapidly fill the number
registers with single characters), so maybe there should be (yet another) option
for that. ('smalldeletethreshold', with 0 = off, 1 = all, and N = for deletes
equal or larger than N characters?!)

Anyway, this should be put into the todo list, so that people are discouraged
from (ab)using this accidental side effect.

-- regards, ingo
--
-- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
-- http://vim.sourceforge.net/account/profile.php?user_id=9713 --

Christian Brabandt

unread,
Sep 3, 2012, 2:43:14 PM9/3/12
to vim...@googlegroups.com
Hi Ingo!

On Mo, 03 Sep 2012, Ingo Karkat wrote:

> Hello Vim developers,
>
> This issue came up on Reddit
> (http://www.reddit.com/r/vim/comments/yyq4a/is_there_anyway_to_configure_vim_to_use_the/).
>
> With :set clipboard=unnamed, small deletes (such as "dw") affect the named
> registers "1.."9. I can reproduce this with vanilla Vim 7.3.000 on Windows/x86,
> and the latest Vim 7.3.646 on Ubuntu/x86.
>
> It appears that the setting triggers the exception from the rule "This register
> ("-) contains text from commands that delete less than one line, except when the
> command specifies a register with ["x].", although the register here comes from
> the implementation, not the user.
>
> Based on the Reddit posting, some people apparently prefer this behavior (though
> I personally dislike that multiple "x" commands will rapidly fill the number
> registers with single characters), so maybe there should be (yet another) option
> for that. ('smalldeletethreshold', with 0 = off, 1 = all, and N = for deletes
> equal or larger than N characters?!)

This patch just fixes this side effect. I don't think, it warrants yet
another option.

diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -1716,8 +1716,8 @@
* Put deleted text into register 1 and shift number registers if the
* delete contains a line break, or when a regname has been specified.
*/
- if (oap->regname != 0 || oap->motion_type == MLINE
- || oap->line_count > 1 || oap->use_reg_one)
+ if (oap->regname != 0 && (oap->motion_type == MLINE
+ || oap->line_count > 1 || oap->use_reg_one))
{
y_current = &y_regs[9];
free_yank_all(); /* free register nine */


regards,
Christian

Ingo Karkat

unread,
Sep 4, 2012, 5:39:08 AM9/4/12
to vim...@googlegroups.com
Hello Christian,

this does indeed fix the problem, but now (with empty 'clipboard'), when I "dd"
a single line, I get "cannot yank; delete anyway (y/n)?" and then a "E470:
Command aborted" when I press "n".

-- regards, ingo

Christian Brabandt

unread,
Sep 4, 2012, 2:38:42 PM9/4/12
to vim...@googlegroups.com
Hi Ingo!

On Di, 04 Sep 2012, Ingo Karkat wrote:

> this does indeed fix the problem, but now (with empty 'clipboard'), when I "dd"
> a single line, I get "cannot yank; delete anyway (y/n)?" and then a "E470:
> Command aborted" when I press "n".

Oh yes, sorry.
This one works:
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -1623,6 +1623,7 @@
#endif
linenr_T old_lcount = curbuf->b_ml.ml_line_count;
int did_yank = FALSE;
+ int orig_regname = oap->regname;

if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to do */
return OK;
@@ -1716,7 +1717,7 @@
* Put deleted text into register 1 and shift number registers if the
* delete contains a line break, or when a regname has been specified.
*/
- if (oap->regname != 0 || oap->motion_type == MLINE
+ if (orig_regname != 0 || oap->motion_type == MLINE
|| oap->line_count > 1 || oap->use_reg_one)
{
y_current = &y_regs[9];


Mit freundlichen Gr��en
Christian
--
Der G�tige l��t die Art, wie er einen geliebten Menschen behandelt,
auch den Ungeliebten zuteil werden.
-- Meng-Tzu

Bram Moolenaar

unread,
Sep 5, 2012, 8:19:04 AM9/5/12
to Christian Brabandt, vim...@googlegroups.com

Christian Brabandt wrote:

> On Di, 04 Sep 2012, Ingo Karkat wrote:
>
> > this does indeed fix the problem, but now (with empty 'clipboard'),
> > when I "dd" a single line, I get "cannot yank; delete anyway (y/n)?"
> > and then a "E470: Command aborted" when I press "n".
>
> Oh yes, sorry.
> This one works:

Thanks!

--
Proverb: A nightingale that forgets the lyrics is a hummingbird.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Aryeh Leib Taurog

unread,
Nov 18, 2013, 1:06:41 PM11/18/13
to vim...@googlegroups.com
On Mon, 3 Sep 2012, Christian Brabandt wrote:
> On Mo, 03 Sep 2012, Ingo Karkat wrote:
> > Hello Vim developers,
> >
> > This issue came up on Reddit
> > (http://www.reddit.com/r/vim/comments/yyq4a/is_there_anyway_to_configure_vim_to_use_the/).
> >
> > With :set clipboard=unnamed, small deletes (such as "dw") affect the named
> > registers "1.."9. I can reproduce this with vanilla Vim 7.3.000 on Windows/x86,
> > and the latest Vim 7.3.646 on Ubuntu/x86.
> >
> > It appears that the setting triggers the exception from the rule "This register
> > ("-) contains text from commands that delete less than one line, except when the
> > command specifies a register with ["x].", although the register here comes from
> > the implementation, not the user.
> >
> > Based on the Reddit posting, some people apparently prefer this behavior (though
> > I personally dislike that multiple "x" commands will rapidly fill the number
> > registers with single characters), so maybe there should be (yet another) option
> > for that. ('smalldeletethreshold', with 0 = off, 1 = all, and N = for deletes
> > equal or larger than N characters?!)
>
> This patch just fixes this side effect. I don't think, it warrants yet
> another option.

I haven't been active on this list. I apologize if reviving a year-
old post violates list etiquette, but it seems like the easiest way to
reference the issue.

I for one am one of those poor misguided souls who quite regularly
abused this accidental side effect. I was rather disturbed by its
disappearance with my recent upgrade from the vim 7.3 shipped with
debian wheezy. I do think this warrants an option, so I've made an
attempt to implement one. This is my first time poking around in
vim's innards. I'd love to get some feedback. Did I do this right?
Would a different name make more sense? Also, is there any chance of
getting this patch accepted? I am reasonably certain that there are
quite a few of those people who prefer the earlier behavior.

Thank you and best regards,
Aryeh Leib Taurog


diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1126,6 +1126,9 @@
made for the delete operator with these movement commands: |%|, |(|, |)|, |`|,
|/|, |?|, |n|, |N|, |{| and |}|. Register "1 is always used then (this is Vi
compatible). The "- register is used as well if the delete is within a line.
+If 'regone' is set, both registers "1 and "- will always be used for small
+deletes, regardless of the movement commands used (this option is not Vi
+compatible).
With each successive deletion or change, Vim shifts the previous contents
of register 1 into register 2, 2 into 3, and so forth, losing the previous
contents of register 9.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5581,6 +5581,16 @@
that is not supported the pattern will not match. This is only useful
for debugging the regexp engine.

+'regone' 'rgo' boolean (default off)
+ global
+ {not in Vi}
+ When set, a delete which would normally be stored only in the small
+ delete register will also be pushed onto the number register stack,
+ that is the number registers will be shifted down and the delete
+ contents will be stored in numbered register 1.
+ See |quote_number| and |quote_-|.
+ NOTE: This option is set to false when 'compatible' is set.
+
*'relativenumber'* *'rnu'* *'norelativenumber'* *'nornu'*
'relativenumber' 'rnu' boolean (default off)
local to window
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -1736,7 +1736,7 @@
* Use the register name from before adjust_clip_reg() may have
* changed it.
*/
- if (orig_regname != 0 || oap->motion_type == MLINE
+ if (orig_regname != 0 || p_rgo || oap->motion_type == MLINE
|| oap->line_count > 1 || oap->use_reg_one)
{
y_current = &y_regs[9];
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -2098,6 +2098,9 @@
{"regexpengine", "re", P_NUM|P_VI_DEF,
(char_u *)&p_re, PV_NONE,
{(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"regone", "rgo", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_rgo, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
{"relativenumber", "rnu", P_BOOL|P_VI_DEF|P_RWIN,
(char_u *)VAR_WIN, PV_RNU,
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
diff --git a/src/option.h b/src/option.h
--- a/src/option.h
+++ b/src/option.h
@@ -655,6 +655,7 @@
EXTERN long p_rdt; /* 'redrawtime' */
#endif
EXTERN int p_remap; /* 'remap' */
+EXTERN int p_rgo; /* 'regone' */
EXTERN long p_re; /* 'regexpengine' */
EXTERN long p_report; /* 'report' */
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)

Aryeh Leib Taurog

unread,
Nov 19, 2013, 8:22:16 AM11/19/13
to vim...@googlegroups.com
On Mon, Nov 18, 2013 at 08:06:41PM +0200, Aryeh Leib Taurog wrote:
> I do think this warrants an option, so I've made an attempt to
> implement one. This is my first time poking around in vim's
> innards. I'd love to get some feedback. Did I do this right?

Well I left the tags out of the documentation. Also it looks like the
vim.vim syntax file needs updating as well. Here's a second patch:

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5581,6 +5581,7 @@
that is not supported the pattern will not match. This is only useful
for debugging the regexp engine.

+ *'regone'* *'rgo'*
'regone' 'rgo' boolean (default off)
global
{not in Vi}
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -35,4 +35,4 @@
syn keyword vimOption contained allowrevins arab autoread backup balloonexpr bh bl bsk cc ch cino cmp com concealcursor cp cscopeprg csprg cul def diff display edcompatible endofline errorformat fcl fdm fex filetype fo foldlevelstart formatexpr ft gfw gtt guipty hh hkmap ic imc imsearch indentkeys isf isprint km lbr list lsp makeprg maxmem mh mmp more mouses mzq nuw opfunc patchexpr pfn popt printfont pumheight redrawtime rightleft rtp sbo scrolljump sel shell shelltype shortname shq sm so spellfile spr st sts swapsync syn tag tb termbidi tgst titleold top ttimeout ttym uc undolevels vb vfile visualbell wc wh wildcharm wim winminheight wmh wrapscan ww
-syn keyword vimOption contained altkeymap arabic autowrite backupcopy bdir bin bomb bt ccv charconvert cinoptions cms comments conceallevel cpo cscopequickfix csqf cursorbind define diffexpr dy ef eol esckeys fcs fdn ff fillchars foldclose foldmarker formatlistpat gcr ghr guicursor guitablabel hi hkmapp icon imcmdline inc indk isfname joinspaces kmp lcs listchars lw mat maxmempattern mis mmt mouse mouseshape mzquantum odev osfiletype patchmode ph preserveindent printheader pvh relativenumber rightleftcmd ru sbr scrolloff selection shellcmdflag shellxescape showbreak si smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tbi termencoding thesaurus titlestring
+syn keyword vimOption contained altkeymap arabic autowrite backupcopy bdir bin bomb bt ccv charconvert cinoptions cms comments conceallevel cpo cscopequickfix csqf cursorbind define diffexpr dy ef eol esckeys fcs fdn ff fillchars foldclose foldmarker formatlistpat gcr ghr guicursor guitablabel hi hkmapp icon imcmdline inc indk isfname joinspaces kmp lcs listchars lw mat maxmempattern mis mmt mouse mouseshape mzquantum odev osfiletype patchmode ph preserveindent printheader pvh regone rgo relativenumber rightleftcmd ru sbr scrolloff selection shellcmdflag shellxescape showbreak si smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tbi termencoding thesaurus titlestring

" vimOptions: These are the turn-off setting variants {{{2
Reply all
Reply to author
Forward
0 new messages