aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c14
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/macros.h2
-rw-r--r--src/nvim/option.c6
-rw-r--r--src/nvim/option_defs.h5
-rw-r--r--src/nvim/options.lua6
-rw-r--r--src/nvim/os/fileio.c31
-rw-r--r--src/nvim/testdir/test_mapping.vim82
-rw-r--r--src/nvim/tui/tui.c12
-rw-r--r--src/nvim/version.c4
10 files changed, 124 insertions, 40 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 15b712e7de..f0d78a2508 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -17289,7 +17289,7 @@ static bool write_list(FileDescriptor *const fp, const list_T *const list,
}
}
}
- if ((error = file_fsync(fp)) != 0) {
+ if ((error = file_flush(fp)) != 0) {
goto write_list_error;
}
return true;
@@ -17439,21 +17439,21 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (fname == NULL) {
return;
}
- FileDescriptor *fp;
+ FileDescriptor fp;
int error;
rettv->vval.v_number = -1;
if (*fname == NUL) {
EMSG(_("E482: Can't open file with an empty name"));
- } else if ((fp = file_open_new(&error, fname,
- ((append ? kFileAppend : kFileTruncate)
- | kFileCreate), 0666)) == NULL) {
+ } else if ((error = file_open(&fp, fname,
+ ((append ? kFileAppend : kFileTruncate)
+ | kFileCreate), 0666)) != 0) {
emsgf(_("E482: Can't open file %s for writing: %s"),
fname, os_strerror(error));
} else {
- if (write_list(fp, argvars[0].vval.v_list, binary)) {
+ if (write_list(&fp, argvars[0].vval.v_list, binary)) {
rettv->vval.v_number = 0;
}
- if ((error = file_free(fp)) != 0) {
+ if ((error = file_close(&fp)) != 0) {
emsgf(_("E80: Error when closing file %s: %s"),
fname, os_strerror(error));
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 7143819e21..b83681ad01 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1903,7 +1903,7 @@ static int vgetorpeek(int advance)
}
if ((mp == NULL || max_mlen >= mp_match_len)
- && keylen != KEYLEN_PART_MAP) {
+ && keylen != KEYLEN_PART_MAP && keylen != KEYLEN_PART_KEY) {
// No matching mapping found or found a non-matching mapping that
// matches at least what the matching mapping matched
keylen = 0;
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index 5042663041..a8df6322cf 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -94,7 +94,7 @@
do { \
if (*p_langmap \
&& (condition) \
- && (!p_lnr || (p_lnr && typebuf_maplen() == 0)) \
+ && (p_lrm || (!p_lrm && KeyTyped)) \
&& !KeyStuffed \
&& (c) >= 0) \
{ \
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 0b4d9aae5d..b3b4dc1e0a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3630,6 +3630,12 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
} else if ((int *)varp == &p_force_off && p_force_off == true) {
p_force_off = false;
return (char *)e_unsupportedoption;
+ } else if ((int *)varp == &p_lrm) {
+ // 'langremap' -> !'langnoremap'
+ p_lnr = !p_lrm;
+ } else if ((int *)varp == &p_lnr) {
+ // 'langnoremap' -> !'langremap'
+ p_lrm = !p_lnr;
// 'undofile'
} else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
// Only take action when the option was set. When reset we do not
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 2475a0b6a1..4ee0f4f225 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -476,8 +476,9 @@ EXTERN char_u *p_isp; // 'isprint'
EXTERN int p_js; // 'joinspaces'
EXTERN char_u *p_kp; // 'keywordprg'
EXTERN char_u *p_km; // 'keymodel'
-EXTERN char_u *p_langmap; // 'langmap'*/
-EXTERN int p_lnr; // 'langnoremap'*/
+EXTERN char_u *p_langmap; // 'langmap'
+EXTERN int p_lnr; // 'langnoremap'
+EXTERN int p_lrm; // 'langremap'
EXTERN char_u *p_lm; // 'langmenu'
EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index ee2b8a563d..9dff3410d6 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1347,6 +1347,12 @@ return {
defaults={if_true={vi=false, vim=true}}
},
{
+ full_name='langremap', abbreviation='lrm',
+ type='bool', scope={'global'},
+ varname='p_lrm',
+ defaults={if_true={vi=true, vim=false}}
+ },
+ {
full_name='laststatus', abbreviation='ls',
type='number', scope={'global'},
vim=true,
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 775f2bd449..3c928363cc 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -143,21 +143,36 @@ int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
/// @param[in,out] fp File to work with.
///
/// @return 0 or error code.
-int file_fsync(FileDescriptor *const fp)
+int file_flush(FileDescriptor *const fp)
FUNC_ATTR_NONNULL_ALL
{
if (!fp->wr) {
return 0;
}
file_rb_write_full_cb(fp->rv, fp);
- if (fp->_error != 0) {
- const int error = fp->_error;
- fp->_error = 0;
- return error;
+ const int error = fp->_error;
+ fp->_error = 0;
+ return error;
+}
+
+/// Flush file modifications to disk and run fsync()
+///
+/// @param[in,out] fp File to work with.
+///
+/// @return 0 or error code.
+int file_fsync(FileDescriptor *const fp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!fp->wr) {
+ return 0;
}
- const int error = os_fsync(fp->fd);
- if (error != UV_EINVAL && error != UV_EROFS) {
- return error;
+ const int flush_error = file_flush(fp);
+ if (flush_error != 0) {
+ return flush_error;
+ }
+ const int fsync_error = os_fsync(fp->fd);
+ if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) {
+ return fsync_error;
}
return 0;
}
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
index d937565ce5..6b313ff54f 100644
--- a/src/nvim/testdir/test_mapping.vim
+++ b/src/nvim/testdir/test_mapping.vim
@@ -35,29 +35,81 @@ func Test_map_ctrl_c_visual()
endfunc
func Test_map_langmap()
- " langmap should not get remapped in insert mode
- inoremap { FAIL_ilangmap
- set langmap=+{ langnoremap
+ if !has('langmap')
+ return
+ endif
+
+ " check langmap applies in normal mode
+ set langmap=+- nolangremap
+ new
+ call setline(1, ['a', 'b', 'c'])
+ 2
+ call assert_equal('b', getline('.'))
+ call feedkeys("+", "xt")
+ call assert_equal('a', getline('.'))
+
+ " check no remapping
+ map x +
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('c', getline('.'))
+
+ " check with remapping
+ set langremap
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('a', getline('.'))
+
+ unmap x
+ bwipe!
+
+ " 'langnoremap' follows 'langremap' and vise versa
+ set langremap
+ set langnoremap
+ call assert_equal(0, &langremap)
+ set langremap
+ call assert_equal(0, &langnoremap)
+ set nolangremap
+ call assert_equal(1, &langnoremap)
+
+ " check default values
+ set langnoremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+ set langremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+
+ " langmap should not apply in insert mode, 'langremap' doesn't matter
+ set langmap=+{ nolangremap
call feedkeys("Go+\<Esc>", "xt")
call assert_equal('+', getline('$'))
-
- " Insert-mode expr mapping with langmap
- inoremap <expr> { "FAIL_iexplangmap"
+ set langmap=+{ langremap
call feedkeys("Go+\<Esc>", "xt")
call assert_equal('+', getline('$'))
- iunmap <expr> {
- " langmap should not get remapped in Command-line mode
- cnoremap { FAIL_clangmap
+ " langmap used for register name in insert mode.
+ call setreg('a', 'aaaa')
+ call setreg('b', 'bbbb')
+ call setreg('c', 'cccc')
+ set langmap=ab langremap
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ " mapping does not apply
+ imap c a
+ call feedkeys("Go\<C-R>c\<Esc>", "xt")
+ call assert_equal('cccc', getline('$'))
+ imap a c
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+
+ " langmap should not apply in Command-line mode
+ set langmap=+{ nolangremap
call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
call assert_equal('+', getline('$'))
- cunmap {
- " Command-line mode expr mapping with langmap
- cnoremap <expr> { "FAIL_cexplangmap"
- call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
- call assert_equal('+', getline('$'))
- cunmap {
set nomodified
endfunc
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 55936ad58d..ebdfb1e7a1 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -452,15 +452,19 @@ static void tui_busy_stop(UI *ui)
static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.enable_mouse);
- data->mouse_enabled = true;
+ if (!data->mouse_enabled) {
+ unibi_out(ui, data->unibi_ext.enable_mouse);
+ data->mouse_enabled = true;
+ }
}
static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.disable_mouse);
- data->mouse_enabled = false;
+ if (data->mouse_enabled) {
+ unibi_out(ui, data->unibi_ext.disable_mouse);
+ data->mouse_enabled = false;
+ }
}
static void tui_mode_change(UI *ui, int mode)
diff --git a/src/nvim/version.c b/src/nvim/version.c
index fdf5436a98..0ee0419849 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -135,7 +135,7 @@ static const int included_patches[] = {
2309,
// 2308 NA
2307,
- // 2306,
+ 2306,
2305,
// 2304 NA
2303,
@@ -205,7 +205,7 @@ static const int included_patches[] = {
// 2239,
// 2238 NA
2237,
- // 2236,
+ 2236,
2235,
// 2234 NA
2233,