aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/shada.vim4
-rw-r--r--runtime/doc/starting.txt2
-rw-r--r--runtime/doc/vim_diff.txt1
-rw-r--r--src/nvim/search.c1
-rw-r--r--src/nvim/shada.c10
-rw-r--r--test/functional/plugin/shada_spec.lua12
-rw-r--r--test/functional/shada/errors_spec.lua5
-rw-r--r--test/functional/shada/history_spec.lua22
8 files changed, 54 insertions, 3 deletions
diff --git a/runtime/autoload/shada.vim b/runtime/autoload/shada.vim
index 234f35398b..9be85b6f2e 100644
--- a/runtime/autoload/shada.vim
+++ b/runtime/autoload/shada.vim
@@ -43,7 +43,8 @@ call map(copy(s:SHADA_ENTRY_NAMES),
" Only contains data for entries which are represented as mappings, except for
" the header.
let s:SHADA_MAP_ENTRIES = {
- \'search_pattern': ['sp', 'sh', 'ss', 'sm', 'sc', 'sl', 'se', 'so', 'su'],
+ \'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so',
+ \ 'su'],
\'register': ['n', 'rc', 'rw', 'rt'],
\'global_mark': ['n', 'f', 'l', 'c'],
\'local_mark': ['f', 'n', 'l', 'c'],
@@ -134,6 +135,7 @@ let s:SHADA_STANDARD_KEYS = {
\'ss': ['is :s pattern', 'boolean', g:msgpack#false],
\'sh': ['v:hlsearch value', 'boolean', g:msgpack#false],
\'sp': ['pattern', 'bin', s:SHADA_REQUIRED],
+ \'sb': ['search backward', 'boolean', g:msgpack#false],
\'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
\'rw': ['block width', 'uint', 0],
\'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 572823eca9..f729fbefcc 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1232,6 +1232,8 @@ exactly four MessagePack objects:
With |shada-h| or 'nohlsearch'
this key is always false.
sp Binary N/A Actual pattern. Required.
+ sb Boolean false True if search direction is
+ backward.
* any none Other keys are allowed for
compatibility reasons, see
|shada-compatibility|.
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 6cbc2aef59..a6cbf6f4c4 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -117,6 +117,7 @@ Additional differences:
|shada-error-handling|
- Vim keeps no timestamps at all, neither in viminfo file nor in the instance
itself.
+- ShaDa file keeps search direction (|v:searchforward|), viminfo does not.
==============================================================================
4. New Features *nvim-features-new*
diff --git a/src/nvim/search.c b/src/nvim/search.c
index a44b0e00c7..fbe07b6fed 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -4623,6 +4623,7 @@ void set_search_pattern(const SearchPattern pat)
{
free_spat(&spats[0]);
memcpy(&(spats[0]), &pat, sizeof(spats[0]));
+ set_vv_searchforward();
}
/// Set last substitute pattern
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index f8643fe655..939c435c01 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -98,6 +98,7 @@ KHASH_SET_INIT_STR(strset)
#define SEARCH_KEY_HIGHLIGHTED "sh"
#define SEARCH_KEY_OFFSET "so"
#define SEARCH_KEY_PAT "sp"
+#define SEARCH_KEY_BACKWARD "sb"
#define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw"
@@ -263,6 +264,7 @@ typedef struct {
bool is_last_used;
bool is_substitute_pattern;
bool highlighted;
+ bool search_backward;
char *pat;
dict_T *additional_data;
} search_pattern;
@@ -455,6 +457,7 @@ static const ShadaEntry sd_default_values[] = {
.is_last_used = true,
.is_substitute_pattern = false,
.highlighted = false,
+ .search_backward = false,
.pat = NULL,
.additional_data = NULL),
DEF_SDE(SubString, sub_string, .sub = NULL, .additional_elements = NULL),
@@ -1338,6 +1341,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.magic = cur_entry.data.search_pattern.magic,
.no_scs = !cur_entry.data.search_pattern.smartcase,
.off = {
+ .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
.line = cur_entry.data.search_pattern.has_line_offset,
.end = cur_entry.data.search_pattern.place_cursor_at_end,
.off = cur_entry.data.search_pattern.offset,
@@ -1754,6 +1758,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.is_substitute_pattern)
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
// finally, additional data:
+ (size_t) (
entry.data.search_pattern.additional_data
@@ -1780,6 +1785,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
+ PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
PACK_STATIC_STR(SEARCH_KEY_OFFSET);
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
@@ -2581,6 +2587,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
&& search_highlighted), \
.pat = (char *) pat.pat, \
.additional_data = pat.additional_data, \
+ .search_backward = (!is_sub && pat.off.dir == '?'), \
} \
} \
} \
@@ -3633,6 +3640,9 @@ shada_read_next_item_start:
BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
entry->data.search_pattern.highlighted)
else
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_BACKWARD,
+ entry->data.search_pattern.search_backward)
+ else
INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
entry->data.search_pattern.offset)
else
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
index 2202f60ce8..020bb11bbc 100644
--- a/test/functional/plugin/shada_spec.lua
+++ b/test/functional/plugin/shada_spec.lua
@@ -208,6 +208,7 @@ describe('In autoload/shada.vim', function()
' + rc contents ["abc", "def"]',
' + rt type CHARACTERWISE',
' + rw block width 10',
+ ' + sb search backward TRUE',
' + sc smartcase value FALSE',
' + se place cursor at end TRUE',
' + sh v:hlsearch value TRUE',
@@ -222,6 +223,7 @@ describe('In autoload/shada.vim', function()
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
'so': 10,
'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
@@ -307,6 +309,7 @@ describe('In autoload/shada.vim', function()
' + sp pattern "abc"',
' + sh v:hlsearch value FALSE',
' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
' + sm magic value TRUE',
' + sc smartcase value FALSE',
' + sl has line offset FALSE',
@@ -322,6 +325,7 @@ describe('In autoload/shada.vim', function()
' + sp pattern "abc"',
' + sh v:hlsearch value FALSE',
' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
' + sm magic value TRUE',
' + sc smartcase value FALSE',
' + sl has line offset FALSE',
@@ -343,6 +347,7 @@ describe('In autoload/shada.vim', function()
' + sp pattern "abc"',
' + sh v:hlsearch value FALSE',
' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
' + sm magic value TRUE',
' + sc smartcase value FALSE',
' + sl has line offset FALSE',
@@ -353,6 +358,7 @@ describe('In autoload/shada.vim', function()
'sp': 'abc',
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
@@ -366,6 +372,7 @@ describe('In autoload/shada.vim', function()
' # Required key missing: sp',
' + sh v:hlsearch value FALSE',
' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
' + sm magic value TRUE',
' + sc smartcase value FALSE',
' + sl has line offset FALSE',
@@ -380,6 +387,7 @@ describe('In autoload/shada.vim', function()
' + sp pattern ""',
' + sh v:hlsearch value TRUE',
' + ss is :s pattern TRUE',
+ ' + sb search backward TRUE',
' + sm magic value FALSE',
' + sc smartcase value TRUE',
' + sl has line offset TRUE',
@@ -390,6 +398,7 @@ describe('In autoload/shada.vim', function()
'sp': '',
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
@@ -407,6 +416,8 @@ describe('In autoload/shada.vim', function()
' # Expected boolean',
' + ss is :s pattern 0',
' # Expected boolean',
+ ' + sb search backward 0',
+ ' # Expected boolean',
' + sm magic value 0',
' # Expected boolean',
' + sc smartcase value 0',
@@ -422,6 +433,7 @@ describe('In autoload/shada.vim', function()
'sp': 0,
'sh': 0,
'ss': 0,
+ 'sb': 0,
'sm': 0,
'sc': 0,
'sl': 0,
diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua
index 16ae77af02..62b9e6c84d 100644
--- a/test/functional/shada/errors_spec.lua
+++ b/test/functional/shada/errors_spec.lua
@@ -124,6 +124,11 @@ describe('ShaDa error handling', function()
eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sc key value which is not a boolean', exc_exec(sdrcmd()))
end)
+ it('fails on search pattern item with NIL search_backward key value', function()
+ wshada('\002\000\009\130\162sX\192\162sb\192')
+ eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sb key value which is not a boolean', exc_exec(sdrcmd()))
+ end)
+
it('fails on search pattern item with NIL has_line_offset key value', function()
wshada('\002\000\009\130\162sX\192\162sl\192')
eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sl key value which is not a boolean', exc_exec(sdrcmd()))
diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua
index 1123f829d2..94513945d0 100644
--- a/test/functional/shada/history_spec.lua
+++ b/test/functional/shada/history_spec.lua
@@ -107,14 +107,32 @@ describe('ShaDa support code', function()
end)
it('dumps and loads last search pattern with offset', function()
- funcs.setline('.', {'foo', 'bar'})
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
nvim_feed('gg0/a/e+1\n')
eq({0, 2, 3, 0}, funcs.getpos('.'))
nvim_command('wshada')
reset()
- funcs.setline('.', {'foo', 'bar'})
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
nvim_feed('gg0n')
eq({0, 2, 3, 0}, funcs.getpos('.'))
+ eq(1, meths.get_vvar('searchforward'))
+ end)
+
+ it('dumps and loads last search pattern with offset and backward direction',
+ function()
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
+ nvim_feed('G$?a?e+1\n')
+ eq({0, 2, 3, 0}, funcs.getpos('.'))
+ nvim_command('wshada')
+ reset()
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
+ nvim_feed('G$n')
+ eq({0, 2, 3, 0}, funcs.getpos('.'))
+ eq(0, meths.get_vvar('searchforward'))
end)
it('saves v:hlsearch=1', function()