mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
shada: Also store last search direction
Note: it looks like viminfo files do not store search direction intentionally. After reading viminfo file search direction was considered to be “forward”. Note 2: all files created on earlier Neovim version will automatically receive “forward” direction. Fixes #3580
This commit is contained in:
parent
321db59ca1
commit
b98cea909f
@ -43,7 +43,8 @@ call map(copy(s:SHADA_ENTRY_NAMES),
|
|||||||
" Only contains data for entries which are represented as mappings, except for
|
" Only contains data for entries which are represented as mappings, except for
|
||||||
" the header.
|
" the header.
|
||||||
let s:SHADA_MAP_ENTRIES = {
|
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'],
|
\'register': ['n', 'rc', 'rw', 'rt'],
|
||||||
\'global_mark': ['n', 'f', 'l', 'c'],
|
\'global_mark': ['n', 'f', 'l', 'c'],
|
||||||
\'local_mark': ['f', 'n', '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],
|
\'ss': ['is :s pattern', 'boolean', g:msgpack#false],
|
||||||
\'sh': ['v:hlsearch value', 'boolean', g:msgpack#false],
|
\'sh': ['v:hlsearch value', 'boolean', g:msgpack#false],
|
||||||
\'sp': ['pattern', 'bin', s:SHADA_REQUIRED],
|
\'sp': ['pattern', 'bin', s:SHADA_REQUIRED],
|
||||||
|
\'sb': ['search backward', 'boolean', g:msgpack#false],
|
||||||
\'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
|
\'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
|
||||||
\'rw': ['block width', 'uint', 0],
|
\'rw': ['block width', 'uint', 0],
|
||||||
\'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
|
\'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
|
||||||
|
@ -1232,6 +1232,8 @@ exactly four MessagePack objects:
|
|||||||
With |shada-h| or 'nohlsearch'
|
With |shada-h| or 'nohlsearch'
|
||||||
this key is always false.
|
this key is always false.
|
||||||
sp Binary N/A Actual pattern. Required.
|
sp Binary N/A Actual pattern. Required.
|
||||||
|
sb Boolean false True if search direction is
|
||||||
|
backward.
|
||||||
* any none Other keys are allowed for
|
* any none Other keys are allowed for
|
||||||
compatibility reasons, see
|
compatibility reasons, see
|
||||||
|shada-compatibility|.
|
|shada-compatibility|.
|
||||||
|
@ -117,6 +117,7 @@ Additional differences:
|
|||||||
|shada-error-handling|
|
|shada-error-handling|
|
||||||
- Vim keeps no timestamps at all, neither in viminfo file nor in the instance
|
- Vim keeps no timestamps at all, neither in viminfo file nor in the instance
|
||||||
itself.
|
itself.
|
||||||
|
- ShaDa file keeps search direction (|v:searchforward|), viminfo does not.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
4. New Features *nvim-features-new*
|
4. New Features *nvim-features-new*
|
||||||
|
@ -4623,6 +4623,7 @@ void set_search_pattern(const SearchPattern pat)
|
|||||||
{
|
{
|
||||||
free_spat(&spats[0]);
|
free_spat(&spats[0]);
|
||||||
memcpy(&(spats[0]), &pat, sizeof(spats[0]));
|
memcpy(&(spats[0]), &pat, sizeof(spats[0]));
|
||||||
|
set_vv_searchforward();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set last substitute pattern
|
/// Set last substitute pattern
|
||||||
|
@ -98,6 +98,7 @@ KHASH_SET_INIT_STR(strset)
|
|||||||
#define SEARCH_KEY_HIGHLIGHTED "sh"
|
#define SEARCH_KEY_HIGHLIGHTED "sh"
|
||||||
#define SEARCH_KEY_OFFSET "so"
|
#define SEARCH_KEY_OFFSET "so"
|
||||||
#define SEARCH_KEY_PAT "sp"
|
#define SEARCH_KEY_PAT "sp"
|
||||||
|
#define SEARCH_KEY_BACKWARD "sb"
|
||||||
|
|
||||||
#define REG_KEY_TYPE "rt"
|
#define REG_KEY_TYPE "rt"
|
||||||
#define REG_KEY_WIDTH "rw"
|
#define REG_KEY_WIDTH "rw"
|
||||||
@ -263,6 +264,7 @@ typedef struct {
|
|||||||
bool is_last_used;
|
bool is_last_used;
|
||||||
bool is_substitute_pattern;
|
bool is_substitute_pattern;
|
||||||
bool highlighted;
|
bool highlighted;
|
||||||
|
bool search_backward;
|
||||||
char *pat;
|
char *pat;
|
||||||
dict_T *additional_data;
|
dict_T *additional_data;
|
||||||
} search_pattern;
|
} search_pattern;
|
||||||
@ -455,6 +457,7 @@ static const ShadaEntry sd_default_values[] = {
|
|||||||
.is_last_used = true,
|
.is_last_used = true,
|
||||||
.is_substitute_pattern = false,
|
.is_substitute_pattern = false,
|
||||||
.highlighted = false,
|
.highlighted = false,
|
||||||
|
.search_backward = false,
|
||||||
.pat = NULL,
|
.pat = NULL,
|
||||||
.additional_data = NULL),
|
.additional_data = NULL),
|
||||||
DEF_SDE(SubString, sub_string, .sub = NULL, .additional_elements = 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,
|
.magic = cur_entry.data.search_pattern.magic,
|
||||||
.no_scs = !cur_entry.data.search_pattern.smartcase,
|
.no_scs = !cur_entry.data.search_pattern.smartcase,
|
||||||
.off = {
|
.off = {
|
||||||
|
.dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
|
||||||
.line = cur_entry.data.search_pattern.has_line_offset,
|
.line = cur_entry.data.search_pattern.has_line_offset,
|
||||||
.end = cur_entry.data.search_pattern.place_cursor_at_end,
|
.end = cur_entry.data.search_pattern.place_cursor_at_end,
|
||||||
.off = cur_entry.data.search_pattern.offset,
|
.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.is_substitute_pattern)
|
||||||
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
|
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
|
||||||
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
|
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
|
||||||
|
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
|
||||||
// finally, additional data:
|
// finally, additional data:
|
||||||
+ (size_t) (
|
+ (size_t) (
|
||||||
entry.data.search_pattern.additional_data
|
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_PLACE_CURSOR_AT_END, place_cursor_at_end);
|
||||||
PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
|
PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
|
||||||
PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
|
PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
|
||||||
|
PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
|
||||||
if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
|
if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
|
||||||
PACK_STATIC_STR(SEARCH_KEY_OFFSET);
|
PACK_STATIC_STR(SEARCH_KEY_OFFSET);
|
||||||
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
|
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
|
||||||
@ -2581,6 +2587,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
&& search_highlighted), \
|
&& search_highlighted), \
|
||||||
.pat = (char *) pat.pat, \
|
.pat = (char *) pat.pat, \
|
||||||
.additional_data = pat.additional_data, \
|
.additional_data = pat.additional_data, \
|
||||||
|
.search_backward = (!is_sub && pat.off.dir == '?'), \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -3632,6 +3639,9 @@ shada_read_next_item_start:
|
|||||||
else
|
else
|
||||||
BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
|
BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
|
||||||
entry->data.search_pattern.highlighted)
|
entry->data.search_pattern.highlighted)
|
||||||
|
else
|
||||||
|
BOOLEAN_KEY("search pattern", SEARCH_KEY_BACKWARD,
|
||||||
|
entry->data.search_pattern.search_backward)
|
||||||
else
|
else
|
||||||
INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
|
INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
|
||||||
entry->data.search_pattern.offset)
|
entry->data.search_pattern.offset)
|
||||||
|
@ -209,6 +209,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' + rc contents ["abc", "def"]',
|
' + rc contents ["abc", "def"]',
|
||||||
' + rt type CHARACTERWISE',
|
' + rt type CHARACTERWISE',
|
||||||
' + rw block width 10',
|
' + rw block width 10',
|
||||||
|
' + sb search backward TRUE',
|
||||||
' + sc smartcase value FALSE',
|
' + sc smartcase value FALSE',
|
||||||
' + se place cursor at end TRUE',
|
' + se place cursor at end TRUE',
|
||||||
' + sh v:hlsearch value TRUE',
|
' + sh v:hlsearch value TRUE',
|
||||||
@ -223,6 +224,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
|
'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
'so': 10,
|
'so': 10,
|
||||||
'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
@ -308,6 +310,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' + sp pattern "abc"',
|
' + sp pattern "abc"',
|
||||||
' + sh v:hlsearch value FALSE',
|
' + sh v:hlsearch value FALSE',
|
||||||
' + ss is :s pattern FALSE',
|
' + ss is :s pattern FALSE',
|
||||||
|
' + sb search backward FALSE',
|
||||||
' + sm magic value TRUE',
|
' + sm magic value TRUE',
|
||||||
' + sc smartcase value FALSE',
|
' + sc smartcase value FALSE',
|
||||||
' + sl has line offset FALSE',
|
' + sl has line offset FALSE',
|
||||||
@ -323,6 +326,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' + sp pattern "abc"',
|
' + sp pattern "abc"',
|
||||||
' + sh v:hlsearch value FALSE',
|
' + sh v:hlsearch value FALSE',
|
||||||
' + ss is :s pattern FALSE',
|
' + ss is :s pattern FALSE',
|
||||||
|
' + sb search backward FALSE',
|
||||||
' + sm magic value TRUE',
|
' + sm magic value TRUE',
|
||||||
' + sc smartcase value FALSE',
|
' + sc smartcase value FALSE',
|
||||||
' + sl has line offset FALSE',
|
' + sl has line offset FALSE',
|
||||||
@ -344,6 +348,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' + sp pattern "abc"',
|
' + sp pattern "abc"',
|
||||||
' + sh v:hlsearch value FALSE',
|
' + sh v:hlsearch value FALSE',
|
||||||
' + ss is :s pattern FALSE',
|
' + ss is :s pattern FALSE',
|
||||||
|
' + sb search backward FALSE',
|
||||||
' + sm magic value TRUE',
|
' + sm magic value TRUE',
|
||||||
' + sc smartcase value FALSE',
|
' + sc smartcase value FALSE',
|
||||||
' + sl has line offset FALSE',
|
' + sl has line offset FALSE',
|
||||||
@ -354,6 +359,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
'sp': 'abc',
|
'sp': 'abc',
|
||||||
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'ss': {'_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},
|
'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
@ -367,6 +373,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' # Required key missing: sp',
|
' # Required key missing: sp',
|
||||||
' + sh v:hlsearch value FALSE',
|
' + sh v:hlsearch value FALSE',
|
||||||
' + ss is :s pattern FALSE',
|
' + ss is :s pattern FALSE',
|
||||||
|
' + sb search backward FALSE',
|
||||||
' + sm magic value TRUE',
|
' + sm magic value TRUE',
|
||||||
' + sc smartcase value FALSE',
|
' + sc smartcase value FALSE',
|
||||||
' + sl has line offset FALSE',
|
' + sl has line offset FALSE',
|
||||||
@ -381,6 +388,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
' + sp pattern ""',
|
' + sp pattern ""',
|
||||||
' + sh v:hlsearch value TRUE',
|
' + sh v:hlsearch value TRUE',
|
||||||
' + ss is :s pattern TRUE',
|
' + ss is :s pattern TRUE',
|
||||||
|
' + sb search backward TRUE',
|
||||||
' + sm magic value FALSE',
|
' + sm magic value FALSE',
|
||||||
' + sc smartcase value TRUE',
|
' + sc smartcase value TRUE',
|
||||||
' + sl has line offset TRUE',
|
' + sl has line offset TRUE',
|
||||||
@ -391,6 +399,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
'sp': '',
|
'sp': '',
|
||||||
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
'ss': {'_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},
|
'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
|
||||||
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
|
||||||
@ -408,6 +417,8 @@ describe('In autoload/shada.vim', function()
|
|||||||
' # Expected boolean',
|
' # Expected boolean',
|
||||||
' + ss is :s pattern 0',
|
' + ss is :s pattern 0',
|
||||||
' # Expected boolean',
|
' # Expected boolean',
|
||||||
|
' + sb search backward 0',
|
||||||
|
' # Expected boolean',
|
||||||
' + sm magic value 0',
|
' + sm magic value 0',
|
||||||
' # Expected boolean',
|
' # Expected boolean',
|
||||||
' + sc smartcase value 0',
|
' + sc smartcase value 0',
|
||||||
@ -423,6 +434,7 @@ describe('In autoload/shada.vim', function()
|
|||||||
'sp': 0,
|
'sp': 0,
|
||||||
'sh': 0,
|
'sh': 0,
|
||||||
'ss': 0,
|
'ss': 0,
|
||||||
|
'sb': 0,
|
||||||
'sm': 0,
|
'sm': 0,
|
||||||
'sc': 0,
|
'sc': 0,
|
||||||
'sl': 0,
|
'sl': 0,
|
||||||
|
@ -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()))
|
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)
|
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()
|
it('fails on search pattern item with NIL has_line_offset key value', function()
|
||||||
wshada('\002\000\009\130\162sX\192\162sl\192')
|
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()))
|
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()))
|
||||||
|
@ -107,14 +107,32 @@ describe('ShaDa support code', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('dumps and loads last search pattern with offset', function()
|
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')
|
nvim_feed('gg0/a/e+1\n')
|
||||||
eq({0, 2, 3, 0}, funcs.getpos('.'))
|
eq({0, 2, 3, 0}, funcs.getpos('.'))
|
||||||
nvim_command('wshada')
|
nvim_command('wshada')
|
||||||
reset()
|
reset()
|
||||||
funcs.setline('.', {'foo', 'bar'})
|
meths.set_option('wrapscan', false)
|
||||||
|
funcs.setline('.', {'foo', 'bar--'})
|
||||||
nvim_feed('gg0n')
|
nvim_feed('gg0n')
|
||||||
eq({0, 2, 3, 0}, funcs.getpos('.'))
|
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)
|
end)
|
||||||
|
|
||||||
it('saves v:hlsearch=1', function()
|
it('saves v:hlsearch=1', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user