forked from aniani/vim
patch 9.1.1473: inconsistent range arg for :diffget/diffput
Problem: inconsistent range arg for :diffget/diffput Solution: fix the range specification, place the cursor for :diffput and :diffget consistently on the last line (Yee Cheng Chin) Previously, `:<range>diffget` only allowed using 1 or above in the range value, making it impossible to use the command for a diff block at the beginning of the file. Fix the range specification so the user can now use 0 to specify the space before the first line. This allows `:0,$+1diffget` to work to retrieve all the changes from the other file instead of missing the first diff block. Also do this for `:diffput`. Also, make `:diffput` work more similar to `:diffget`. Make it so that if the cursor is on the last line and a new line is inserted in the other file, doing `:diffput` will select that diff block below the line, just like `:diffget` would. Also clean up the logic a little bit for edge cases and for handling line matched diff blocks better. closes: #17579 Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
476b65ebac
commit
d75ab0cbf5
@ -1,4 +1,4 @@
|
|||||||
*diff.txt* For Vim version 9.1. Last change: 2025 Mar 28
|
*diff.txt* For Vim version 9.1. Last change: 2025 Jun 20
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -304,18 +304,20 @@ that the buffers will be equal within the specified range.
|
|||||||
|
|
||||||
|
|
||||||
When no [range] is given, the diff at the cursor position or just above it is
|
When no [range] is given, the diff at the cursor position or just above it is
|
||||||
affected. When [range] is used, Vim tries to only put or get the specified
|
affected. There can be deleted lines below the last line of the buffer. When
|
||||||
lines. When there are deleted lines, this may not always be possible.
|
the cursor is on the last line in the buffer and there is no diff above this
|
||||||
|
line, and no [range] is given, the diff below the cursor position will be used
|
||||||
|
instead.
|
||||||
|
|
||||||
There can be deleted lines below the last line of the buffer. When the cursor
|
When [range] is used, Vim tries to only put or get the specified lines. When
|
||||||
is on the last line in the buffer and there is no diff above this line, the
|
there are deleted lines, they will be used if they are between the lines
|
||||||
":diffget" and "do" commands will obtain lines from the other buffer.
|
specified by [range].
|
||||||
|
|
||||||
To be able to get those lines from another buffer in a [range] it's allowed to
|
To be able to put or get those lines to/from another buffer in a [range] it's
|
||||||
use the last line number plus one. This command gets all diffs from the other
|
allowed to use 0 and the last line number plus one. This command gets all
|
||||||
buffer: >
|
diffs from the other buffer: >
|
||||||
|
|
||||||
:1,$+1diffget
|
:0,$+1diffget
|
||||||
|
|
||||||
Note that deleted lines are displayed, but not counted as text lines. You
|
Note that deleted lines are displayed, but not counted as text lines. You
|
||||||
can't move the cursor into them. To fill the deleted lines with the lines
|
can't move the cursor into them. To fill the deleted lines with the lines
|
||||||
|
11
src/diff.c
11
src/diff.c
@ -3874,10 +3874,13 @@ ex_diffgetput(exarg_T *eap)
|
|||||||
{
|
{
|
||||||
// Make it possible that ":diffget" on the last line gets line below
|
// Make it possible that ":diffget" on the last line gets line below
|
||||||
// the cursor line when there is no difference above the cursor.
|
// the cursor line when there is no difference above the cursor.
|
||||||
if (eap->cmdidx == CMD_diffget
|
int linestatus = 0;
|
||||||
&& eap->line1 == curbuf->b_ml.ml_line_count
|
if (eap->line1 == curbuf->b_ml.ml_line_count
|
||||||
&& diff_check(curwin, eap->line1) == 0
|
&& (diff_check_with_linestatus(curwin, eap->line1, &linestatus) == 0
|
||||||
&& (eap->line1 == 1 || diff_check(curwin, eap->line1 - 1) == 0))
|
&& linestatus == 0)
|
||||||
|
&& (eap->line1 == 1 ||
|
||||||
|
(diff_check_with_linestatus(curwin, eap->line1 - 1, &linestatus) >= 0
|
||||||
|
&& linestatus == 0)))
|
||||||
++eap->line2;
|
++eap->line2;
|
||||||
else if (eap->line1 > 0)
|
else if (eap->line1 > 0)
|
||||||
--eap->line1;
|
--eap->line1;
|
||||||
|
@ -486,7 +486,7 @@ EXCMD(CMD_diffupdate, "diffupdate", ex_diffupdate,
|
|||||||
EX_BANG|EX_TRLBAR,
|
EX_BANG|EX_TRLBAR,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
EXCMD(CMD_diffget, "diffget", ex_diffgetput,
|
EXCMD(CMD_diffget, "diffget", ex_diffgetput,
|
||||||
EX_RANGE|EX_EXTRA|EX_TRLBAR|EX_MODIFY,
|
EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_MODIFY,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_diffoff, "diffoff", ex_diffoff,
|
EXCMD(CMD_diffoff, "diffoff", ex_diffoff,
|
||||||
EX_BANG|EX_TRLBAR,
|
EX_BANG|EX_TRLBAR,
|
||||||
@ -495,7 +495,7 @@ EXCMD(CMD_diffpatch, "diffpatch", ex_diffpatch,
|
|||||||
EX_EXTRA|EX_FILE1|EX_TRLBAR|EX_MODIFY,
|
EX_EXTRA|EX_FILE1|EX_TRLBAR|EX_MODIFY,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
EXCMD(CMD_diffput, "diffput", ex_diffgetput,
|
EXCMD(CMD_diffput, "diffput", ex_diffgetput,
|
||||||
EX_RANGE|EX_EXTRA|EX_TRLBAR,
|
EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_diffsplit, "diffsplit", ex_diffsplit,
|
EXCMD(CMD_diffsplit, "diffsplit", ex_diffsplit,
|
||||||
EX_EXTRA|EX_FILE1|EX_TRLBAR,
|
EX_EXTRA|EX_FILE1|EX_TRLBAR,
|
||||||
|
@ -4850,7 +4850,8 @@ invalid_range(exarg_T *eap)
|
|||||||
case ADDR_LINES:
|
case ADDR_LINES:
|
||||||
if (eap->line2 > curbuf->b_ml.ml_line_count
|
if (eap->line2 > curbuf->b_ml.ml_line_count
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
+ (eap->cmdidx == CMD_diffget)
|
+ (eap->cmdidx == CMD_diffget ||
|
||||||
|
eap->cmdidx == CMD_diffput)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
return _(e_invalid_range);
|
return _(e_invalid_range);
|
||||||
|
@ -288,6 +288,63 @@ func Test_diffget_diffput_range()
|
|||||||
%bw!
|
%bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test :diffget/:diffput handling of added/deleted lines
|
||||||
|
func Test_diffget_diffput_deleted_lines()
|
||||||
|
call setline(1, ['2','4','6'])
|
||||||
|
diffthis
|
||||||
|
new
|
||||||
|
call setline(1, range(1,7))
|
||||||
|
diffthis
|
||||||
|
wincmd w
|
||||||
|
|
||||||
|
3,3diffget " get nothing
|
||||||
|
call assert_equal(['2', '4', '6'], getline(1, '$'))
|
||||||
|
3,4diffget " get the last insertion past the end of file
|
||||||
|
call assert_equal(['2', '4', '6', '7'], getline(1, '$'))
|
||||||
|
0,1diffget " get the first insertion above first line
|
||||||
|
call assert_equal(['1', '2', '4', '6', '7'], getline(1, '$'))
|
||||||
|
|
||||||
|
" When using non-range diffget on the last line, it should get the
|
||||||
|
" change above or at the line as usual, but if the only change is below the
|
||||||
|
" last line, diffget should get that instead.
|
||||||
|
1,$delete
|
||||||
|
call setline(1, ['2','4','6'])
|
||||||
|
diffupdate
|
||||||
|
norm Gdo
|
||||||
|
call assert_equal(['2', '4', '5', '6'], getline(1, '$'))
|
||||||
|
norm Gdo
|
||||||
|
call assert_equal(['2', '4', '5', '6', '7'], getline(1, '$'))
|
||||||
|
|
||||||
|
" Test non-range diffput on last line with the same logic
|
||||||
|
1,$delete
|
||||||
|
call setline(1, ['2','4','6'])
|
||||||
|
diffupdate
|
||||||
|
norm Gdp
|
||||||
|
wincmd w
|
||||||
|
call assert_equal(['1', '2', '3', '4', '6', '7'], getline(1, '$'))
|
||||||
|
wincmd w
|
||||||
|
norm Gdp
|
||||||
|
wincmd w
|
||||||
|
call assert_equal(['1', '2', '3', '4', '6'], getline(1, '$'))
|
||||||
|
call setline(1, range(1,7))
|
||||||
|
diffupdate
|
||||||
|
wincmd w
|
||||||
|
|
||||||
|
" Test that 0,$+1 will get/put all changes from/to the other buffer
|
||||||
|
1,$delete
|
||||||
|
call setline(1, ['2','4','6'])
|
||||||
|
diffupdate
|
||||||
|
0,$+1diffget
|
||||||
|
call assert_equal(['1', '2', '3', '4', '5', '6', '7'], getline(1, '$'))
|
||||||
|
1,$delete
|
||||||
|
call setline(1, ['2','4','6'])
|
||||||
|
diffupdate
|
||||||
|
0,$+1diffput
|
||||||
|
wincmd w
|
||||||
|
call assert_equal(['2', '4', '6'], getline(1, '$'))
|
||||||
|
%bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
|
" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
|
||||||
func Test_diffget_diffput_empty_buffer()
|
func Test_diffget_diffput_empty_buffer()
|
||||||
%d _
|
%d _
|
||||||
|
@ -709,6 +709,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1473,
|
||||||
/**/
|
/**/
|
||||||
1472,
|
1472,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user