aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mpack/object.h2
-rw-r--r--src/nvim/api/buffer.c4
-rw-r--r--src/nvim/api/extmark.c2
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/fileio.c8
-rw-r--r--src/nvim/lib/khash.h2
-rw-r--r--src/nvim/lua/stdlib.c6
-rw-r--r--src/nvim/lua/vim.lua13
-rw-r--r--src/nvim/ops.c56
-rw-r--r--src/nvim/sign.c2
-rw-r--r--src/nvim/syntax.c2
-rw-r--r--src/nvim/testdir/test_blockedit.vim52
-rw-r--r--src/nvim/testdir/test_filetype.vim73
-rw-r--r--src/nvim/testdir/test_put.vim13
16 files changed, 204 insertions, 39 deletions
diff --git a/src/mpack/object.h b/src/mpack/object.h
index 5327e56e18..e69821f9de 100644
--- a/src/mpack/object.h
+++ b/src/mpack/object.h
@@ -22,7 +22,7 @@ enum {
};
/* Storing integer in pointers in undefined behavior according to the C
- * standard. Define a union type to accomodate arbitrary user data associated
+ * standard. Define a union type to accommodate arbitrary user data associated
* with nodes(and with requests in rpc.h). */
typedef union {
void *p;
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 4076a0d220..718743ed9c 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -535,7 +535,7 @@ end:
/// @param channel_id
/// @param buffer Buffer handle, or 0 for current buffer
/// @param start_row First line index
-/// @param start_column Last column
+/// @param start_column First column
/// @param end_row Last line index
/// @param end_column Last column
/// @param replacement Array of lines to use as replacement
@@ -1246,7 +1246,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
/// If the current window already shows "buffer", the window is not switched
/// If a window inside the current tabpage (including a float) already shows the
/// buffer One of these windows will be set as current window temporarily.
-/// Otherwise a temporary scratch window (calleed the "autocmd window" for
+/// Otherwise a temporary scratch window (called the "autocmd window" for
/// historical reasons) will be used.
///
/// This is useful e.g. to call vimL functions that only work with the current
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 6f1fb15dac..6e25e627b9 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -839,7 +839,7 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start,
/// - on_win: called when starting to redraw a specific window.
/// ["win", winid, bufnr, topline, botline_guess]
/// - on_line: called for each buffer line being redrawn. (The
-/// interation with fold lines is subject to change)
+/// interaction with fold lines is subject to change)
/// ["win", winid, bufnr, row]
/// - on_end: called at the end of a redraw cycle
/// ["end", tick]
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 6be51c504c..7e7114b291 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -37,6 +37,7 @@ return {
'CursorHoldI', -- idem, in Insert mode
'CursorMoved', -- cursor was moved
'CursorMovedI', -- cursor was moved in Insert mode
+ 'DiagnosticChanged', -- diagnostics in a buffer were modified
'DiffUpdated', -- diffs have been updated
'DirChanged', -- directory changed
'EncodingChanged', -- after changing the 'encoding' option
@@ -126,6 +127,7 @@ return {
-- syntax file
nvim_specific = {
BufModifiedSet=true,
+ DiagnosticChanged=true,
DirChanged=true,
Signal=true,
TabClosed=true,
diff --git a/src/nvim/change.c b/src/nvim/change.c
index c52d992fbe..ef771125f1 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -625,7 +625,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
}
}
- char_u *newp = xmalloc((size_t)(linelen + newlen - oldlen));
+ char_u *newp = xmalloc(linelen + newlen - oldlen);
// Copy bytes before the cursor.
if (col > 0) {
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 62919c98f7..284f8a9ab5 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -818,7 +818,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
// of interrupts or errors to exceptions, and ensure that no more
// commands are executed.
if (current_exception) {
- void *p = NULL;
+ char *p = NULL;
char_u *saved_sourcing_name;
int saved_sourcing_lnum;
struct msglist *messages = NULL;
@@ -835,7 +835,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
vim_snprintf((char *)IObuff, IOSIZE,
_("E605: Exception not caught: %s"),
current_exception->value);
- p = vim_strsave(IObuff);
+ p = (char *)vim_strsave(IObuff);
break;
case ET_ERROR:
messages = current_exception->messages;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 7573064fa9..c90115d796 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -100,8 +100,8 @@ struct bw_info {
char_u bw_rest[CONV_RESTLEN]; // not converted bytes
int bw_restlen; // nr of bytes in bw_rest[]
int bw_first; // first write call
- char_u *bw_conv_buf; // buffer for writing converted chars
- int bw_conv_buflen; // size of bw_conv_buf
+ char_u *bw_conv_buf; // buffer for writing converted chars
+ size_t bw_conv_buflen; // size of bw_conv_buf
int bw_conv_error; // set for conversion error
linenr_T bw_conv_error_lnum; // first line with error or zero
linenr_T bw_start_lnum; // line number at start of buffer
@@ -1360,6 +1360,10 @@ retry:
u8c += (unsigned)(*--p) << 16;
u8c += (unsigned)(*--p) << 24;
}
+ // Replace characters over INT_MAX with Unicode replacement character
+ if (u8c > INT_MAX) {
+ u8c = 0xfffd;
+ }
} else { // UTF-8
if (*--p < 0x80) {
u8c = *p;
diff --git a/src/nvim/lib/khash.h b/src/nvim/lib/khash.h
index 8cfeb03cc4..e81db43038 100644
--- a/src/nvim/lib/khash.h
+++ b/src/nvim/lib/khash.h
@@ -666,7 +666,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
} \
}
-// More conenient interfaces
+// More convenient interfaces
/*! @function
@abstract Instantiate a hash set containing integer keys
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index db79e9e7e9..b5553060a1 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -175,13 +175,13 @@ int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
size_t s1_len;
const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
intptr_t idx;
- if (lua_gettop(lstate) >= 2) {
+ if (lua_isnoneornil(lstate, 2)) {
+ idx = (intptr_t)s1_len;
+ } else {
idx = luaL_checkinteger(lstate, 2);
if (idx < 0 || idx > (intptr_t)s1_len) {
return luaL_error(lstate, "index out of range");
}
- } else {
- idx = (intptr_t)s1_len;
}
size_t codepoints = 0, codeunits = 0;
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index 30c7034209..c1a1e7f162 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -323,6 +323,7 @@ end
do
local validate = vim.validate
+ --@private
local function make_dict_accessor(scope, handle)
validate {
scope = {scope, 's'};
@@ -422,11 +423,10 @@ end
---
--- Without a runtime, writes to :Messages
---@see :help nvim_notify
----@param msg Content of the notification to show to the user
----@param log_level Optional log level
----@param opts Dictionary with optional options (timeout, etc)
-function vim.notify(msg, log_level, _opts)
-
+---@param msg string Content of the notification to show to the user
+---@param log_level number|nil enum from vim.log.levels
+---@param opts table|nil additional options (timeout, etc)
+function vim.notify(msg, log_level, opts) -- luacheck: no unused
if log_level == vim.log.levels.ERROR then
vim.api.nvim_err_writeln(msg)
elseif log_level == vim.log.levels.WARN then
@@ -454,7 +454,7 @@ local on_key_cbs = {}
--- On each key press, Nvim passes the key char to fn(). |i_CTRL-V|
--- If {fn} is nil, it removes the callback for the associated {ns_id}
---@param ns_id number? Namespace ID. If nil or 0, generates and returns a new
---- |nvim_create_namesapce()| id.
+--- |nvim_create_namespace()| id.
---
---@return number Namespace id associated with {fn}. Or count of all callbacks
---if on_key() is called without arguments.
@@ -580,6 +580,7 @@ function vim._expand_pat(pat, env)
end
local keys = {}
+ ---@private
local function insert_keys(obj)
for k,_ in pairs(obj) do
if type(k) == "string" and string.sub(k,1,string.len(match_part)) == match_part then
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index b4b9545daf..09979c4ef5 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2162,7 +2162,8 @@ void op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
- colnr_T ind_pre = 0;
+ colnr_T ind_pre_col = 0, ind_post_col;
+ int ind_pre_vcol = 0, ind_post_vcol = 0;
struct block_def bd;
int i;
pos_T t1;
@@ -2196,7 +2197,8 @@ void op_insert(oparg_T *oap, long count1)
// Get the info about the block before entering the text
block_prep(oap, &bd, oap->start.lnum, true);
// Get indent information
- ind_pre = (colnr_T)getwhitecols_curline();
+ ind_pre_col = (colnr_T)getwhitecols_curline();
+ ind_pre_vcol = get_indent();
firstline = ml_get(oap->start.lnum) + bd.textcol;
if (oap->op_type == OP_APPEND) {
@@ -2261,10 +2263,11 @@ void op_insert(oparg_T *oap, long count1)
// if indent kicked in, the firstline might have changed
// but only do that, if the indent actually increased
- const colnr_T ind_post = (colnr_T)getwhitecols_curline();
- if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre) {
- bd.textcol += ind_post - ind_pre;
- bd.start_vcol += ind_post - ind_pre;
+ ind_post_col = (colnr_T)getwhitecols_curline();
+ if (curbuf->b_op_start.col > ind_pre_col && ind_post_col > ind_pre_col) {
+ bd.textcol += ind_post_col - ind_pre_col;
+ ind_post_vcol = get_indent();
+ bd.start_vcol += ind_post_vcol - ind_pre_vcol;
did_indent = true;
}
@@ -2297,12 +2300,26 @@ void op_insert(oparg_T *oap, long count1)
}
}
- /*
- * Spaces and tabs in the indent may have changed to other spaces and
- * tabs. Get the starting column again and correct the length.
- * Don't do this when "$" used, end-of-line will have changed.
- */
+ // Spaces and tabs in the indent may have changed to other spaces and
+ // tabs. Get the starting column again and correct the length.
+ // Don't do this when "$" used, end-of-line will have changed.
+ //
+ // if indent was added and the inserted text was after the indent,
+ // correct the selection for the new indent.
+ if (did_indent && bd.textcol - ind_post_col > 0) {
+ oap->start.col += ind_post_col - ind_pre_col;
+ oap->start_vcol += ind_post_vcol - ind_pre_vcol;
+ oap->end.col += ind_post_col - ind_pre_col;
+ oap->end_vcol += ind_post_vcol - ind_pre_vcol;
+ }
block_prep(oap, &bd2, oap->start.lnum, true);
+ if (did_indent && bd.textcol - ind_post_col > 0) {
+ // undo for where "oap" is used below
+ oap->start.col -= ind_post_col - ind_pre_col;
+ oap->start_vcol -= ind_post_vcol - ind_pre_vcol;
+ oap->end.col -= ind_post_col - ind_pre_col;
+ oap->end_vcol -= ind_post_vcol - ind_pre_vcol;
+ }
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
if (oap->op_type == OP_APPEND) {
pre_textlen += bd2.textlen - bd.textlen;
@@ -3340,6 +3357,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
if (y_type == kMTCharWise && y_size == 1) {
linenr_T end_lnum = 0; // init for gcc
linenr_T start_lnum = lnum;
+ int first_byte_off = 0;
if (VIsual_active) {
end_lnum = curbuf->b_visual.vi_end.lnum;
@@ -3386,6 +3404,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
STRMOVE(ptr, oldp + col);
ml_replace(lnum, newp, false);
+
+ // compute the byte offset for the last character
+ first_byte_off = utf_head_off(newp, ptr - 1);
+
// Place cursor on last putted char.
if (lnum == curwin->w_cursor.lnum) {
// make sure curwin->w_virtcol is updated
@@ -3405,10 +3427,15 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
lnum--;
}
+ // put '] at the first byte of the last character
curbuf->b_op_end = curwin->w_cursor;
+ curbuf->b_op_end.col -= first_byte_off;
+
// For "CTRL-O p" in Insert mode, put cursor after last char
if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND))) {
curwin->w_cursor.col++;
+ } else {
+ curwin->w_cursor.col -= first_byte_off;
}
} else {
// Insert at least one line. When y_type is kMTCharWise, break the first
@@ -3520,12 +3547,13 @@ error:
curbuf->b_op_start.lnum, nr_lines, true);
}
- // put '] mark at last inserted character
+ // Put the '] mark on the first byte of the last inserted character.
+ // Correct the length for change in indent.
curbuf->b_op_end.lnum = lnum;
- // correct length for change in indent
col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
if (col > 1) {
- curbuf->b_op_end.col = col - 1;
+ curbuf->b_op_end.col = col - 1 - utf_head_off(y_array[y_size - 1],
+ y_array[y_size - 1] + col - 1);
} else {
curbuf->b_op_end.col = 0;
}
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index d8eea7f942..fca73dc9f2 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -80,7 +80,7 @@ static signgroup_T *sign_group_ref(const char_u *groupname)
hi = hash_lookup(&sg_table, (char *)groupname, STRLEN(groupname), hash);
if (HASHITEM_EMPTY(hi)) {
// new group
- group = xmalloc((unsigned)(sizeof(signgroup_T) + STRLEN(groupname)));
+ group = xmalloc(sizeof(signgroup_T) + STRLEN(groupname));
STRCPY(group->sg_name, groupname);
group->sg_refcount = 1;
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index dd3f1b4dc9..49f8bbab37 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -5401,7 +5401,7 @@ static int get_id_list(char_u **const arg, const int keylen, int16_t **const lis
do {
for (end = p; *end && !ascii_iswhite(*end) && *end != ','; end++) {
}
- char_u *const name = xmalloc((int)(end - p + 3)); // leave room for "^$"
+ char_u *const name = xmalloc(end - p + 3); // leave room for "^$"
STRLCPY(name + 1, p, end - p + 1);
if (STRCMP(name + 1, "ALLBUT") == 0
|| STRCMP(name + 1, "ALL") == 0
diff --git a/src/nvim/testdir/test_blockedit.vim b/src/nvim/testdir/test_blockedit.vim
index 180524cd73..38978ef689 100644
--- a/src/nvim/testdir/test_blockedit.vim
+++ b/src/nvim/testdir/test_blockedit.vim
@@ -15,6 +15,58 @@ func Test_blockinsert_indent()
bwipe!
endfunc
+func Test_blockinsert_autoindent()
+ new
+ let lines =<< trim END
+ var d = {
+ a: () => 0,
+ b: () => 0,
+ c: () => 0,
+ }
+ END
+ call setline(1, lines)
+ filetype plugin indent on
+ setlocal sw=2 et ft=vim
+ setlocal indentkeys+=:
+ exe "norm! 2Gf)\<c-v>2jA: asdf\<esc>"
+ let expected =<< trim END
+ var d = {
+ a: (): asdf => 0,
+ b: (): asdf => 0,
+ c: (): asdf => 0,
+ }
+ END
+ call assert_equal(expected, getline(1, 5))
+
+ " insert on the next column should do exactly the same
+ :%dele
+ call setline(1, lines)
+ exe "norm! 2Gf)l\<c-v>2jI: asdf\<esc>"
+ call assert_equal(expected, getline(1, 5))
+
+ :%dele
+ call setline(1, lines)
+ setlocal sw=8 noet
+ exe "norm! 2Gf)\<c-v>2jA: asdf\<esc>"
+ let expected =<< trim END
+ var d = {
+ a: (): asdf => 0,
+ b: (): asdf => 0,
+ c: (): asdf => 0,
+ }
+ END
+ call assert_equal(expected, getline(1, 5))
+
+ " insert on the next column should do exactly the same
+ :%dele
+ call setline(1, lines)
+ exe "norm! 2Gf)l\<c-v>2jI: asdf\<esc>"
+ call assert_equal(expected, getline(1, 5))
+
+ filetype off
+ bwipe!
+endfunc
+
func Test_blockinsert_delete()
new
let _bs = &bs
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 9651b8dce0..48b434b9fd 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -59,7 +59,7 @@ let s:filename_checks = {
\ 'aml': ['file.aml'],
\ 'ampl': ['file.run'],
\ 'ant': ['build.xml'],
- \ 'apache': ['.htaccess', '/etc/httpd/file.conf', '/etc/apache2/sites-2/file.com', '/etc/apache2/some.config', '/etc/apache2/conf.file/conf', '/etc/apache2/mods-some/file', '/etc/apache2/sites-some/file', '/etc/httpd/conf.d/file.config', '/etc/apache2/conf.file/file', '/etc/apache2/file.conf', '/etc/apache2/file.conf-file', '/etc/apache2/mods-file/file', '/etc/apache2/sites-file/file', '/etc/apache2/sites-file/file.com', '/etc/httpd/conf.d/file.conf', '/etc/httpd/conf.d/file.conf-file', 'access.conf', 'access.conf-file', 'any/etc/apache2/conf.file/file', 'any/etc/apache2/file.conf', 'any/etc/apache2/file.conf-file', 'any/etc/apache2/mods-file/file', 'any/etc/apache2/sites-file/file', 'any/etc/apache2/sites-file/file.com', 'any/etc/httpd/conf.d/file.conf', 'any/etc/httpd/conf.d/file.conf-file', 'any/etc/httpd/file.conf', 'apache.conf', 'apache.conf-file', 'apache2.conf', 'apache2.conf-file', 'httpd.conf', 'httpd.conf-file', 'srm.conf', 'srm.conf-file'],
+ \ 'apache': ['.htaccess', '/etc/httpd/file.conf', '/etc/apache2/sites-2/file.com', '/etc/apache2/some.config', '/etc/apache2/conf.file/conf', '/etc/apache2/mods-some/file', '/etc/apache2/sites-some/file', '/etc/httpd/conf.d/file.config', '/etc/apache2/conf.file/file', '/etc/apache2/file.conf', '/etc/apache2/file.conf-file', '/etc/apache2/mods-file/file', '/etc/apache2/sites-file/file', '/etc/apache2/sites-file/file.com', '/etc/httpd/conf.d/file.conf', '/etc/httpd/conf.d/file.conf-file', 'access.conf', 'access.conf-file', 'any/etc/apache2/conf.file/file', 'any/etc/apache2/file.conf', 'any/etc/apache2/file.conf-file', 'any/etc/apache2/mods-file/file', 'any/etc/apache2/sites-file/file', 'any/etc/apache2/sites-file/file.com', 'any/etc/httpd/conf.d/file.conf', 'any/etc/httpd/conf.d/file.conf-file', 'any/etc/httpd/file.conf', 'apache.conf', 'apache.conf-file', 'apache2.conf', 'apache2.conf-file', 'httpd.conf', 'httpd.conf-file', 'srm.conf', 'srm.conf-file', '/etc/httpd/mods-some/file', '/etc/httpd/sites-some/file', '/etc/httpd/conf.file/conf'],
\ 'apachestyle': ['/etc/proftpd/file.config,/etc/proftpd/conf.file/file', '/etc/proftpd/conf.file/file', '/etc/proftpd/file.conf', '/etc/proftpd/file.conf-file', 'any/etc/proftpd/conf.file/file', 'any/etc/proftpd/file.conf', 'any/etc/proftpd/file.conf-file', 'proftpd.conf', 'proftpd.conf-file'],
\ 'applescript': ['file.scpt'],
\ 'aptconf': ['apt.conf', '/.aptitude/config', 'any/.aptitude/config'],
@@ -142,7 +142,7 @@ let s:filename_checks = {
\ 'desc': ['file.desc'],
\ 'desktop': ['file.desktop', '.directory', 'file.directory'],
\ 'dictconf': ['dict.conf', '.dictrc'],
- \ 'dictdconf': ['dictd.conf'],
+ \ 'dictdconf': ['dictd.conf', 'dictdfile.conf', 'dictd-file.conf'],
\ 'diff': ['file.diff', 'file.rej'],
\ 'dircolors': ['.dir_colors', '.dircolors', '/etc/DIR_COLORS', 'any/etc/DIR_COLORS'],
\ 'dnsmasq': ['/etc/dnsmasq.conf', '/etc/dnsmasq.d/file', 'any/etc/dnsmasq.conf', 'any/etc/dnsmasq.d/file'],
@@ -182,11 +182,12 @@ let s:filename_checks = {
\ 'fgl': ['file.4gl', 'file.4gh', 'file.m4gl'],
\ 'fish': ['file.fish'],
\ 'focexec': ['file.fex', 'file.focexec'],
- \ 'forth': ['file.fs', 'file.ft', 'file.fth'],
+ \ 'forth': ['file.ft', 'file.fth'],
\ 'fortran': ['file.f', 'file.for', 'file.fortran', 'file.fpp', 'file.ftn', 'file.f77', 'file.f90', 'file.f95', 'file.f03', 'file.f08'],
\ 'fpcmake': ['file.fpc'],
\ 'framescript': ['file.fsl'],
\ 'freebasic': ['file.fb', 'file.bi'],
+ \ 'fsharp': ['file.fs', 'file.fsi', 'file.fsx'],
\ 'fstab': ['fstab', 'mtab'],
\ 'fvwm': ['/.fvwm/file', 'any/.fvwm/file'],
\ 'gdb': ['.gdbinit', 'gdbinit'],
@@ -553,7 +554,7 @@ let s:filename_checks = {
\ 'xhtml': ['file.xhtml', 'file.xht'],
\ 'xinetd': ['/etc/xinetd.conf', '/etc/xinetd.d/file', 'any/etc/xinetd.conf', 'any/etc/xinetd.d/file'],
\ 'xmath': ['file.msc', 'file.msf'],
- \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu'],
+ \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd'],
\ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'],
\ 'xf86conf': ['xorg.conf', 'xorg.conf-4'],
\ 'xpm': ['file.xpm'],
@@ -663,6 +664,7 @@ let s:script_checks = {
\ 'fennel': [['#!/path/fennel']],
\ 'routeros': [['#!/path/rsc']],
\ 'fish': [['#!/path/fish']],
+ \ 'forth': [['#!/path/gforth']],
\ }
" Various forms of "env" optional arguments.
@@ -866,6 +868,16 @@ func Test_m_file()
call assert_equal('objc', &filetype)
bwipe!
+ call writefile(['#include <header.h>'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('objc', &filetype)
+ bwipe!
+
+ call writefile(['#define FORTY_TWO'], 'Xfile.m')
+ split Xfile.m
+ call assert_equal('objc', &filetype)
+ bwipe!
+
" Octave
call writefile(['# Octave line comment'], 'Xfile.m')
@@ -935,4 +947,57 @@ func Test_xpm_file()
filetype off
endfunc
+func Test_fs_file()
+ filetype on
+
+ call writefile(['looks like F#'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('fsharp', &filetype)
+ bwipe!
+
+ let g:filetype_fs = 'forth'
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+ unlet g:filetype_fs
+
+ " Test dist#ft#FTfs()
+
+ " Forth (Gforth)
+
+ call writefile(['( Forth inline comment )'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ call writefile(['.( Forth displayed inline comment )'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ call writefile(['\ Forth line comment'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ " empty line comment - no space required
+ call writefile(['\'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ call writefile(['\G Forth documentation comment '], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ call writefile([': squared ( n -- n^2 )', 'dup * ;'], 'Xfile.fs')
+ split Xfile.fs
+ call assert_equal('forth', &filetype)
+ bwipe!
+
+ call delete('Xfile.fs')
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim
index 15745d5619..8d8cc77025 100644
--- a/src/nvim/testdir/test_put.vim
+++ b/src/nvim/testdir/test_put.vim
@@ -111,3 +111,16 @@ func Test_put_p_indent_visual()
call assert_equal('select that text', getline(2))
bwipe!
endfunc
+
+func Test_multibyte_op_end_mark()
+ new
+ call setline(1, 'ั‚ะตัั‚')
+ normal viwdp
+ call assert_equal([0, 1, 7, 0], getpos("'>"))
+ call assert_equal([0, 1, 7, 0], getpos("']"))
+
+ normal Vyp
+ call assert_equal([0, 1, 2147483647, 0], getpos("'>"))
+ call assert_equal([0, 2, 7, 0], getpos("']"))
+ bwipe!
+ endfunc