Closed mihaicristiantanase closed 5 years ago
Yeah, this is a known issue and reported in https://github.com/kovisoft/paredit/issues/25
Unfortunately I don't know yet how to fix it, this seems to be a bug in vim. Currently the only workaround is to temporarily disable paredit mode via ,(
.
So, it's from paredit plugin.
I've also noticed that, in the following Lisp buffer:
;; this is a test comment
(defun a ())
(defun b ())
with the cursor on the first line (Normal mode), I do:
2dap // delete first 2 paragraphs
u // undo
P // paste the paragraphs back
The first 2 lines (the comment + the empty line) disappear.
Is this the same issue as the one mentioned here?
Disabling paredit mode fixes the issue.
The problem with the 2dap
example in your comment is fixed in commit https://github.com/kovisoft/slimv/commit/2bedede57afcbbfdcb60d551a4aaec72a3d3b203
I've checked, but there are lots of issues with the fix: First result (2dapP):
;; this is a test comment
(defun a ())
(defun b ());; this is a test comment
(defun a ())
(defun b ())
Repeating uu2dapP
a few times leads to lots of duplicated lines:
;; this is a test comment
(defun a ())
(defun b ());; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
(defun a ())
;; this is a test comment
;; this is a test comment
(defun a ())
(defun b ())
That is quite strange, if I make the same test, it's okay for me. So the difference must be due to a vim option that is different in our systems. What is your value of this option?
:set clipboard?
What is pasted into vim if you enter these commands, then you press P
?
:call setreg('"','"')
:call setreg('+','+')
:call setreg('*','*')
What is the output if you first yank (yy
) an empty line, then start your test case without pasting (2dap
) and type this command?
:reg
:set clipboard?
→ clipboard=unnamed
Running 2dap
, then the 3 commands, then P leads to:
*(defun b ())
:reg
before P
leads to:
Running P
afterwords adds an empty line in the top.
Thanks for the assistance. I've set clipboard=unnamed
but still was not able to reproduce the problem. Please add the below debug statements to paredit.vim and repeat your original 2dap
test (with the cursor being on the ;; this is a test comment
line and without the final P
):
Add this line to PareditOpFunc() before the if s:repeat > 0
line (before the first if in the function):
echomsg 'PareditOpFunc repeat='.s:repeat.' register='.v:register.':'.getreg(v:register)
Add this line to PareditSetDelete() anywhere in the function:
echomsg 'PareditSetDelete clear register='.v:register
Please send me the relevant parts of the output of the :mess
and :reg
commands after the test. I'm wondering what register is used on your system and why it differs from my system.
Oh, and just one more idea: could you please make a test with the following lines (there are two of them) replaced in function PareditOpFunc()?
let putreg = oldreg . getreg( '"' )
with the below version (i.e. replace '"'
with v:register
)
let putreg = oldreg . getreg( v:register )
Thanks.
Results with echomsg
(w/o P
):
Messages maintainer: Bram Moolenaar <Bram@vim.org>
"/tmp/a.lisp" 5L, 54C
PareditSetDelete clear register=*
PareditOpfunc repeat=2 register=*:(defun b ())
PareditOpfunc repeat=1 register=*:(defun b ())^@;; this is a test comment
Press ENTER or type command to continue
Results with v:register (after P
):
PareditSetDelete ;; this is a test comment
(defun a ())
(defun b ())
Thanks for doing the tests. How do you interpret the last result? Does it mean that 2dap
deleted the two paragraphs (only defun b remained), then after pressing P
the originally deleted two paragraphs were pasted but also some gibberish from a register (PareditSetDelete
) was also pasted? And in this case what was the output for :mess
and :reg
? Sorry, I'm a little confused, probably because I asked you to do multiple things. So please just repeat the last test (with v:register
) but also please provide the :mess
and :reg
output. Thanks again.
Sorry for the "too comprised" response I gave previously :)
So, here are the changes I make to paredit.vim:
diff --git a/plugin/paredit.vim b/plugin/paredit.vim
index 77af128..8160ede 100644
--- a/plugin/paredit.vim
+++ b/plugin/paredit.vim
@@ -279,6 +279,7 @@ function! PareditOpfunc( func, type, visualmode )
set virtualedit=all
let regname = v:register
let save_0 = getreg( '0' )
+ echomsg 'PareditOpFunc repeat='.s:repeat.' register='.v:register.':'.getreg(v:register)
if s:repeat > 0
let oldreg = getreg( v:register )
let s:repeat = s:repeat - 1
@@ -302,10 +303,10 @@ function! PareditOpfunc( func, type, visualmode )
if !g:paredit_mode || (a:visualmode && (a:type == 'block' || a:type == "\<C-V>"))
" Block mode is too difficult to handle at the moment
silent exe "normal! d"
- let putreg = oldreg . getreg( '"' )
+ let putreg = oldreg . getreg( v:register )
else
silent exe "normal! y"
- let putreg = oldreg . getreg( '"' )
+ let putreg = oldreg . getreg( v:register )
if a:func == 'd'
" Register "0 is corrupted by the above 'y' command
call setreg( '0', save_0 )
@@ -361,6 +362,7 @@ endfunction
" Set delete mode also saving repeat count
function! PareditSetDelete( count )
+ echomsg 'PareditSetDelete clear register='.v:register
let s:repeat = a:count
call setreg( v:register, '' )
set opfunc=PareditDelete
:mess
Messages maintainer: Bram Moolenaar <Bram@vim.org>
"a.lisp" 5L, 54C
PareditSetDelete clear register=*
PareditOpFunc repeat=2 register=*:;; this is a test comment testingstuff
PareditOpFunc repeat=1 register=*:;; this is a test comment testingstuff^@;; this is a test comment
Press ENTER or type command to continue
:reg
--- Registers ---
"" Messages maintainer: Bram Moolenaar <Bram@vim.org>^J"a.lisp" 5L, 54C^JPareditSetDelete clear register=*^JPareditOpFunc repeat=2 register=*:;; this is a test comment testingstuff^JPareditOpFunc repeat
"0 Messages maintainer: Bram Moolenaar <Bram@vim.org>^J"a.lisp" 5L, 54C^JPareditSetDelete clear register=*^JPareditOpFunc repeat=2 register=*:;; this is a test comment testingstuff^JPareditOpFunc repeat
"1 (defun a ())^J^J
"2 ;; this is a test comment^J^J
"3 (defun a ())^J^J
"4 ;; this is a test comment^J^J
"5 (defun a ())^J^J
"6 ;; this is a test comment^J^J
"7 Plug 'tpope/vim-fugitive'^J
"8 (defun a ())^J^J
"9 ;; this is a test comment^J^J
"* testingstuff
": Reg
Press ENTER or type command to continue
After doing P
, this is the buffer:
Messages maintainer: Bram Moolenaar <Bram@vim.org>
"a.lisp" 5L, 54C
PareditSetDelete clear register=*
PareditOpFunc repeat=2 register=*:;; this is a test comment testingstuff
PareditOpFunc repeat=1 register=*:;; this is a test comment testingstuff^@;; this is a test comment
Press ENTER or type command to continue(defun b ())
Obs: 'testingstuff' string is a text I had in clipboard before doing the 2dap
combo.
My impression is that the bug has become worse after 2bedede
TBH I'm completely clueless, because as I understand from your logs, your system is using the *
register for yanking and pasting, and at the beginning the *
register is cleared (in PareditSetDelete
), but then soon in PareditOpFunc
this *
register is printed in the log and it has some garbage value. How is this possible I can't explain. It was cleared and no yank/delete operation was performed up to the log message. I really need some more thorough debugging, so it would be nice if I could reproduce the problem on my system.
Is it possible that you send me your .vimrc file? You can find my email address in |slimv-credits|
part of the slimv doc. Thanks for the cooperation.
To reproduce the bug I have this setup:
.vim/
structure:
├── autoload
│ └── plug.vim
└── plugged
└── slimv
├── ..........
.vimrc
:
set clipboard=unnamed
call plug#begin('~/.vim/plugged')
Plug 'kovisoft/slimv'
call plug#end()
Computer
:
macOS Mojave 10.14.5
========================== I've nailed the problem to
set clipboard=unnamed
Removing this line fixes the bug.
Thank you, I really appreciate your kind assistance. I tried to create the same config on my system: I used your .vimrc, I downloaded plug.vim and created the same directory structure as yours, but unfortunately I was still unable to reproduce the problem.
Then I started to add more echomsg
lines and these suddenly broke the delete functionality. It seems that echomsg
is not fully compatible with opfunc
(or whatever). So I'd like to ask you to remove those echomsg
lines and check if anything changes. If still not okay, then please add this line at the beginning of paredit.vim:
let g:debug=''
And replace the previous echomsg
lines with these variants:
let g:debug=g:debug.'PareditOpFunc repeat='.s:repeat.' register='.v:register.':'.getreg(v:register)."\n"
and
let g:debug=g:debug.'PareditSetDelete clear register '.v:register."\n"
These statements don't print anything just store the debug string into variable g:debug
, this can be printed at the end of the test via;
:echo g:debug
Can you please send me what's the debug text? Thanks again.
So, here are my changes:
diff --git a/plugin/paredit.vim b/plugin/paredit.vim
index 77af128..a9dcb49 100644
--- a/plugin/paredit.vim
+++ b/plugin/paredit.vim
@@ -14,6 +14,8 @@ if &cp || exists( 'g:paredit_loaded' )
finish
endif
+let g:debug=''
+
let g:paredit_loaded = 1
" Needed to load filetype and indent plugins
@@ -279,6 +281,7 @@ function! PareditOpfunc( func, type, visualmode )
set virtualedit=all
let regname = v:register
let save_0 = getreg( '0' )
+ let g:debug=g:debug.'PareditOpFunc repeat='.s:repeat.' register='.v:register.':'.getreg(v:register)."\n"
if s:repeat > 0
let oldreg = getreg( v:register )
let s:repeat = s:repeat - 1
@@ -361,6 +364,7 @@ endfunction
" Set delete mode also saving repeat count
function! PareditSetDelete( count )
+ let g:debug=g:debug.'PareditSetDelete clear register '.v:register."\n"
let s:repeat = a:count
call setreg( v:register, '' )
set opfunc=PareditDelete
And this is the result of echo g:debug
:
PareditSetDelete clear register *
PareditOpFunc repeat=2 register=*:PareditSetDelete
PareditOpFunc repeat=1 register=*:PareditSetDelete ;; this is a test comment
Press ENTER or type command to continue
Unfortunately, it's still not working.
Thank you very much. That is very strange, the * register is cleared, then in the next function call it contains some text (that was yanked before). Maybe some other functions are called on your system that I'm not aware of. Could you please repeat the same test case but with vim verbose mode enabled:
:set verbosefile=test.log
:set verbose=20
2dap
):set verbose=0
test.log
, please send this file to meThanks again.
I've re-done the test, and here's the test.log file: test.log
Hope this helps.
Thank you very much. Unfortunately I still don't know what the problem is, so I created a debug version of paredit.vim. I added some extra debug messages to the test.log file and it automatically enables verbose mode during the yank-paste actions. Could you please unzip and replace paredit.vim with this file:
and simply repeat the 2dapP
test, then again please send me the resulting test.log.
Thank you and sorry for the troubles.
Sorry for late reply, I had a hard in finding some free time :)
So, I've updated the paredit
plugin and re-ran the test. Here's the log file:
unnamed-test.log
I've also re-done the test with default clibboard
setting. Here's the log file for the scenario in which everything is perfect:
default-test.log
You can do a diff between them. Maybe this will help you spot the issue.
Thanks!
Thank you very much! It was a good idea to make parallel tests with different clipboard settings. I compared the logfiles and it seems that when clipboard=unnamed
then some garbage is appearing in register *
between PareditSetDelete
and PareditOpfunc
on your system (on my systems it doesn't, neither in Windows, nor in Linux). Therefore I modified the code so that the *
register is initialized only later in PareditOpfunc
. This is the modified debug version:
Could you please repeat your previous test cases using this version of the script? Thanks again!
I've tested and the bug is fixed! I don't think it's necessary to send you the "test.log" file, but if you need it, please let me know. Please let me know when an "official" fix is added to master, so I can close this issue.
Thank you!
Great, thanks! Of course you don't need to send the logfile to me. I'll let you know when I'm ready with the fix. However I must tell you that the original problem with repeating the c
command is not yet solved, and unfortunately I don't know how to fix it, because it seems to be vim bug.
Thanks again for your kind assistance!
Fixed the count handling in the d
command in commit https://github.com/kovisoft/slimv/commit/42ec98e4f80a951455f481ad282153215b8934bd , sorry for the delay and again a big thank you for doing all the test cases for me.
As I mentioned, the original problem with the c
operator is still open, there is a paredit issue https://github.com/kovisoft/paredit/issues/25 for that.
Works perfectly. As you mentioned, there's another issue for the "ce" bug. So, I'm closing this one.
Thank you!
In a Lisp buffer with the following contents:
when I do (starting in Normal mode at the beginning of the line):
I get:
The expected behavior is to end up with: