aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2021-11-17 07:07:15 +0800
committerzeertzjq <zeertzjq@outlook.com>2021-11-17 07:11:40 +0800
commit8c24e1462c567c30410d3a45e552ecffc95bbd1d (patch)
tree07f01e715a4fb7f5c69bfaa26e039cf67c2c167e /src
parenteba317d7a907a76e6e265c0fe0b97a87f17cf943 (diff)
downloadrneovim-8c24e1462c567c30410d3a45e552ecffc95bbd1d.tar.gz
rneovim-8c24e1462c567c30410d3a45e552ecffc95bbd1d.tar.bz2
rneovim-8c24e1462c567c30410d3a45e552ecffc95bbd1d.zip
vim-patch:8.2.2518: 'listchars' should be window-local
Problem: 'listchars' should be window-local. Solution: Make 'listchars' global-local. (Yegappan Lakshmanan, Marco Hinz, closes vim/vim#5206, closes vim/vim#7850) https://github.com/vim/vim/commit/eed9d46293f0842aad0d50ff3a526f9a48b12421 Nvim already has this feature, but it implements :set listchars the same as :setglobal listchars, which is incorrect. Vim's implementation of :set listchars is correct: using :set listchars clears local value.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/option.c11
-rw-r--r--src/nvim/testdir/test_listchars.vim115
-rw-r--r--src/nvim/testdir/test_listlbr.vim2
3 files changed, 122 insertions, 6 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 5dd7d708f9..d301b17265 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2650,14 +2650,19 @@ ambw_end:
}
s = skip_to_option_part(s);
}
- } else if (varp == &p_lcs) { // 'listchars'
+ } else if (varp == &p_lcs) { // global 'listchars'
errmsg = set_chars_option(curwin, varp, false);
- if (!errmsg) {
+ if (errmsg == NULL) {
+ // The current window is set to use the global 'listchars' value.
+ // So clear the window-local value.
+ if (!(opt_flags & OPT_GLOBAL)) {
+ clear_string_option(&curwin->w_p_lcs);
+ }
FOR_ALL_TAB_WINDOWS(tp, wp) {
set_chars_option(wp, &wp->w_p_lcs, true);
}
+ redraw_all_later(NOT_VALID);
}
- redraw_all_later(NOT_VALID);
} else if (varp == &curwin->w_p_lcs) { // local 'listchars'
errmsg = set_chars_option(curwin, varp, true);
} else if (varp == &p_fcs) { // 'fillchars'
diff --git a/src/nvim/testdir/test_listchars.vim b/src/nvim/testdir/test_listchars.vim
index 8a1393a45d..f57d4f9ab9 100644
--- a/src/nvim/testdir/test_listchars.vim
+++ b/src/nvim/testdir/test_listchars.vim
@@ -112,7 +112,7 @@ func Test_listchars()
" Test lead and trail
normal ggdG
- set listchars=eol:$
+ set listchars=eol:$ " Accommodate Nvim default
set listchars+=lead:>,trail:<,space:x
set list
@@ -142,7 +142,7 @@ func Test_listchars()
" Test multispace
normal ggdG
- set listchars=eol:$
+ set listchars=eol:$ " Accommodate Nvim default
set listchars+=multispace:yYzZ
set list
@@ -301,7 +301,7 @@ func Test_listchars_invalid()
enew!
set ff=unix
- set listchars=eol:$
+ set listchars=eol:$ " Accommodate Nvim default
set list
set ambiwidth=double
@@ -365,3 +365,112 @@ func Test_listchars_composing()
enew!
set listchars& ff&
endfunction
+
+" Check for the value of the 'listchars' option
+func s:CheckListCharsValue(expected)
+ call assert_equal(a:expected, &listchars)
+ call assert_equal(a:expected, getwinvar(0, '&listchars'))
+endfunc
+
+" Test for using a window local value for 'listchars'
+func Test_listchars_window_local()
+ %bw!
+ set list listchars&
+ let l:default_listchars = &listchars " Accommodate Nvim default
+ new
+ " set a local value for 'listchars'
+ setlocal listchars=tab:+-,eol:#
+ call s:CheckListCharsValue('tab:+-,eol:#')
+ " When local value is reset, global value should be used
+ setlocal listchars=
+ call s:CheckListCharsValue(l:default_listchars) " Accommodate Nvim default
+ " Use 'setlocal <' to copy global value
+ setlocal listchars=space:.,extends:>
+ setlocal listchars<
+ call s:CheckListCharsValue(l:default_listchars) " Accommodate Nvim default
+ " Use 'set <' to copy global value
+ setlocal listchars=space:.,extends:>
+ set listchars<
+ call s:CheckListCharsValue(l:default_listchars) " Accommodate Nvim default
+ " Changing global setting should not change the local setting
+ setlocal listchars=space:.,extends:>
+ setglobal listchars=tab:+-,eol:#
+ call s:CheckListCharsValue('space:.,extends:>')
+ " when split opening a new window, local value should be copied
+ split
+ call s:CheckListCharsValue('space:.,extends:>')
+ " clearing local value in one window should not change the other window
+ set listchars&
+ call s:CheckListCharsValue(l:default_listchars) " Accommodate Nvim default
+ close
+ call s:CheckListCharsValue('space:.,extends:>')
+
+ " use different values for 'listchars' items in two different windows
+ call setline(1, ["\t one two "])
+ setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
+ split
+ setlocal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
+ split
+ set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
+ call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ " changing the global setting should not change the local value
+ setglobal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ set listchars<
+ call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
+
+ " Using setglobal in a window with local setting should not affect the
+ " window. But should impact other windows using the global setting.
+ enew! | only
+ call setline(1, ["\t one two "])
+ set listchars=tab:[.],lead:#,space:_,trail:.,eol:&
+ split
+ setlocal listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
+ split
+ setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
+ setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
+
+ " Setting the global setting to the default value should not impact a window
+ " using a local setting
+ split
+ setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
+ setglobal listchars=eol:$ " Accommodate Nvim default
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
+
+ " Setting the local setting to the default value should not impact a window
+ " using a global setting
+ set listchars=tab:{.},lead:-,space:=,trail:#,eol:$
+ split
+ setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ setlocal listchars=eol:$ " Accommodate Nvim default
+ call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
+
+ " Using set in a window with a local setting should change it to use the
+ " global setting and also impact other windows using the global setting
+ split
+ setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
+ call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
+ set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
+ call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
+ close
+ call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
+
+ %bw!
+ set list& listchars&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim
index e0518de3c2..2fda12d8b4 100644
--- a/src/nvim/testdir/test_listlbr.vim
+++ b/src/nvim/testdir/test_listlbr.vim
@@ -43,6 +43,7 @@ endfunc
func Test_linebreak_with_list()
throw 'skipped: Nvim does not support enc=latin1'
+ set listchars=
call s:test_windows('setl ts=4 sbr=+ list listchars=')
call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
let lines = s:screen_lines([1, 4], winwidth(0))
@@ -54,6 +55,7 @@ func Test_linebreak_with_list()
\ ]
call s:compare_lines(expect, lines)
call s:close_windows()
+ set listchars&vim
endfunc
func Test_linebreak_with_nolist()