mirror of https://github.com/neovim/neovim.git
Compare commits
8 Commits
3f4ef27a3c
...
1340cd9730
Author | SHA1 | Date |
---|---|---|
Francesco Luzzi | 1340cd9730 | |
zeertzjq | 435dee74bb | |
zeertzjq | 694756252b | |
FrancescoLuzzi | 63e8575217 | |
zeertzjq | e81eb34aa1 | |
zeertzjq | a1568f5df0 | |
zeertzjq | f1f5fb911b | |
FrancescoLuzzi | 1edadd8501 |
|
@ -8208,6 +8208,10 @@ synconcealed({lnum}, {col}) *synconcealed()*
|
|||
synconcealed(lnum, 5) [1, 'X', 2]
|
||||
synconcealed(lnum, 6) [0, '', 0]
|
||||
|
||||
Note: Doesn't consider |matchadd()| highlighting items,
|
||||
since syntax and matching highlighting are two different
|
||||
mechanisms |syntax-vs-match|.
|
||||
|
||||
synstack({lnum}, {col}) *synstack()*
|
||||
Return a |List|, which is the stack of syntax items at the
|
||||
position {lnum} and {col} in the current window. {lnum} is
|
||||
|
|
|
@ -1375,6 +1375,19 @@ Finally, these constructs are unique to Perl:
|
|||
==============================================================================
|
||||
10. Highlighting matches *match-highlight*
|
||||
|
||||
*syntax-vs-match*
|
||||
Note that the match highlight mechanism is independent
|
||||
of |syntax-highlighting|, which is (usually) a buffer-local
|
||||
highlighting, while matching is window-local, both methods
|
||||
can be freely mixed. Match highlighting functions give you
|
||||
a bit more flexibility in when and how to apply, but are
|
||||
typically only used for temporary highlighting, without strict
|
||||
rules. Both methods can be used to conceal text.
|
||||
|
||||
Thus the matching functions like |matchadd()| won't consider
|
||||
syntax rules and functions like |synconcealed()| and the
|
||||
other way around.
|
||||
|
||||
*:mat* *:match*
|
||||
:mat[ch] {group} /{pattern}/
|
||||
Define a pattern to highlight in the current window. It will
|
||||
|
|
|
@ -3825,7 +3825,9 @@ Whether or not it is actually concealed depends on the value of the
|
|||
'conceallevel' option. The 'concealcursor' option is used to decide whether
|
||||
concealable items in the current line are displayed unconcealed to be able to
|
||||
edit the line.
|
||||
Another way to conceal text is with |matchadd()|.
|
||||
|
||||
Another way to conceal text is with |matchadd()|, but internally this works a
|
||||
bit differently |syntax-vs-match|.
|
||||
|
||||
concealends *:syn-concealends*
|
||||
|
||||
|
@ -3833,7 +3835,9 @@ When the "concealends" argument is given, the start and end matches of
|
|||
the region, but not the contents of the region, are marked as concealable.
|
||||
Whether or not they are actually concealed depends on the setting on the
|
||||
'conceallevel' option. The ends of a region can only be concealed separately
|
||||
in this way when they have their own highlighting via "matchgroup"
|
||||
in this way when they have their own highlighting via "matchgroup". The
|
||||
|synconcealed()| function can be used to retrieve information about conealed
|
||||
items.
|
||||
|
||||
cchar *:syn-cchar*
|
||||
*E844*
|
||||
|
|
|
@ -948,7 +948,7 @@ Syntax and highlighting: *syntax-functions* *highlighting-functions*
|
|||
synIDattr() get a specific attribute of a syntax ID
|
||||
synIDtrans() get translated syntax ID
|
||||
synstack() get list of syntax IDs at a specific position
|
||||
synconcealed() get info about concealing
|
||||
synconcealed() get info about (syntax) concealing
|
||||
diff_hlID() get highlight ID for diff mode at a position
|
||||
matchadd() define a pattern to highlight (a "match")
|
||||
matchaddpos() define a list of positions to highlight
|
||||
|
|
|
@ -9752,6 +9752,10 @@ function vim.fn.synIDtrans(synID) end
|
|||
--- synconcealed(lnum, 5) [1, 'X', 2]
|
||||
--- synconcealed(lnum, 6) [0, '', 0]
|
||||
---
|
||||
--- Note: Doesn't consider |matchadd()| highlighting items,
|
||||
--- since syntax and matching highlighting are two different
|
||||
--- mechanisms |syntax-vs-match|.
|
||||
---
|
||||
--- @param lnum integer
|
||||
--- @param col integer
|
||||
--- @return {[1]: integer, [2]: string, [3]: integer}
|
||||
|
|
|
@ -9,6 +9,12 @@ local schar = string.char
|
|||
local tohex = require('bit').tohex
|
||||
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):.*'
|
||||
local WINDOWS_URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):[a-zA-Z]:.*'
|
||||
-- https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou
|
||||
-- added also "." to the regex to handle \\wsl.localhost
|
||||
-- vim.fs.normalize returns paths formatted with "/" so we don't handle "\" (PR #28203)
|
||||
local WINDOWS_UNC_PATTERN = '^//([a-zA-Z.-]+)(/.*)'
|
||||
local IS_WINDOWS = vim.uv.os_uname().version:match('Windows')
|
||||
|
||||
local PATTERNS = {
|
||||
-- RFC 2396
|
||||
-- https://tools.ietf.org/html/rfc2396#section-2.2
|
||||
|
@ -36,7 +42,7 @@ end
|
|||
|
||||
---@param uri string
|
||||
---@return boolean
|
||||
local function is_windows_file_uri(uri)
|
||||
local function is_windows_volume_uri(uri)
|
||||
return uri:match('^file:/+[a-zA-Z]:') ~= nil
|
||||
end
|
||||
|
||||
|
@ -60,16 +66,16 @@ end
|
|||
---@param path string Path to file
|
||||
---@return string URI
|
||||
function M.uri_from_fname(path)
|
||||
local volume_path, fname = path:match('^([a-zA-Z]:)(.*)') ---@type string?
|
||||
local is_windows = volume_path ~= nil
|
||||
if is_windows then
|
||||
path = volume_path .. M.uri_encode(fname:gsub('\\', '/'))
|
||||
else
|
||||
path = M.uri_encode(path)
|
||||
end
|
||||
path = vim.fs.normalize(path)
|
||||
path = M.uri_encode(path)
|
||||
local uri_parts = { 'file://' }
|
||||
if is_windows then
|
||||
table.insert(uri_parts, '/')
|
||||
if IS_WINDOWS then
|
||||
local unc_path, _ = path:match(WINDOWS_UNC_PATTERN) ---@type string?,string?
|
||||
if unc_path then
|
||||
path = path:gsub('^//', '')
|
||||
else
|
||||
table.insert(uri_parts, '/')
|
||||
end
|
||||
end
|
||||
table.insert(uri_parts, path)
|
||||
return table.concat(uri_parts)
|
||||
|
@ -80,11 +86,8 @@ end
|
|||
---@return string URI
|
||||
function M.uri_from_bufnr(bufnr)
|
||||
local fname = vim.api.nvim_buf_get_name(bufnr)
|
||||
local volume_path = fname:match('^([a-zA-Z]:).*')
|
||||
local is_windows = volume_path ~= nil
|
||||
local scheme ---@type string?
|
||||
if is_windows then
|
||||
fname = fname:gsub('\\', '/')
|
||||
if IS_WINDOWS then
|
||||
scheme = fname:match(WINDOWS_URI_SCHEME_PATTERN)
|
||||
else
|
||||
scheme = fname:match(URI_SCHEME_PATTERN)
|
||||
|
@ -110,10 +113,14 @@ function M.uri_to_fname(uri)
|
|||
end
|
||||
uri = M.uri_decode(uri)
|
||||
--TODO improve this.
|
||||
if is_windows_file_uri(uri) then
|
||||
if is_windows_volume_uri(uri) then
|
||||
uri = uri:gsub('^file:/+', ''):gsub('/', '\\')
|
||||
else
|
||||
uri = uri:gsub('^file:/+', '/') ---@type string
|
||||
if IS_WINDOWS and uri:match('^file://[a-zA-Z.-]') ~= nil then -- handle UNC file uri in windows
|
||||
uri = uri:gsub('^file:/+', '//'):gsub('/', '\\')
|
||||
else
|
||||
uri = uri:gsub('^file:/+', '/')
|
||||
end
|
||||
end
|
||||
return uri
|
||||
end
|
||||
|
|
|
@ -47,8 +47,8 @@ typedef struct {
|
|||
#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid
|
||||
#define VALID_CHEIGHT 0x08 // w_cline_height and w_cline_folded valid
|
||||
#define VALID_CROW 0x10 // w_cline_row is valid
|
||||
#define VALID_BOTLINE 0x20 // w_botine and w_empty_rows are valid
|
||||
#define VALID_BOTLINE_AP 0x40 // w_botine is approximated
|
||||
#define VALID_BOTLINE 0x20 // w_botline and w_empty_rows are valid
|
||||
#define VALID_BOTLINE_AP 0x40 // w_botline is approximated
|
||||
#define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position)
|
||||
|
||||
// flags for b_flags
|
||||
|
|
|
@ -11621,6 +11621,10 @@ M.funcs = {
|
|||
synconcealed(lnum, 4) [1, 'X', 2]
|
||||
synconcealed(lnum, 5) [1, 'X', 2]
|
||||
synconcealed(lnum, 6) [0, '', 0]
|
||||
|
||||
Note: Doesn't consider |matchadd()| highlighting items,
|
||||
since syntax and matching highlighting are two different
|
||||
mechanisms |syntax-vs-match|.
|
||||
]=],
|
||||
name = 'synconcealed',
|
||||
params = { { 'lnum', 'integer' }, { 'col', 'integer' } },
|
||||
|
|
|
@ -2467,6 +2467,7 @@ void win_init_empty(win_T *wp)
|
|||
wp->w_topline = 1;
|
||||
wp->w_topfill = 0;
|
||||
wp->w_botline = 2;
|
||||
wp->w_valid = 0;
|
||||
wp->w_s = &wp->w_buffer->b_s;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,21 @@ describe('URI methods', function()
|
|||
eq('file:///C:/Foo%20/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)'))
|
||||
end)
|
||||
|
||||
it('UNC path includes only ascii characters', function()
|
||||
exec_lua([[filepath = '\\\\wsl.local-host\\Foo\\Bar\\Baz.txt']])
|
||||
|
||||
eq('file://wsl.local-host/Foo/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)'))
|
||||
end)
|
||||
|
||||
it('UNC path including white space', function()
|
||||
exec_lua([[filepath = '\\\\wsl.local-host\\Foo \\Bar\\Baz.txt']])
|
||||
|
||||
eq(
|
||||
'file://wsl.local-host/Foo%20/Bar/Baz.txt',
|
||||
exec_lua('return vim.uri_from_fname(filepath)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('file path including Unicode characters', function()
|
||||
exec_lua([[filepath = 'C:\\xy\\åäö\\ɧ\\汉语\\↥\\🤦\\🦄\\å\\بِيَّ.txt']])
|
||||
|
||||
|
@ -135,6 +150,26 @@ describe('URI methods', function()
|
|||
eq('C:\\Foo \\Bar\\Baz.txt', exec_lua(test_case))
|
||||
end)
|
||||
|
||||
it('UNC path includes only ascii characters', function()
|
||||
skip(not is_os('win'), 'Not applicable on non-Windows')
|
||||
local test_case = [[
|
||||
local uri = 'file://wsl.local-host/Foo/Bar/Baz.txt'
|
||||
return vim.uri_to_fname(uri)
|
||||
]]
|
||||
|
||||
eq('\\\\wsl.local-host\\Foo\\Bar\\Baz.txt', exec_lua(test_case))
|
||||
end)
|
||||
|
||||
it('UNC path including white space', function()
|
||||
skip(not is_os('win'), 'Not applicable on non-Windows')
|
||||
local test_case = [[
|
||||
local uri = 'file://wsl.local-host/Foo%20/Bar/Baz.txt'
|
||||
return vim.uri_to_fname(uri)
|
||||
]]
|
||||
|
||||
eq('\\\\wsl.local-host\\Foo \\Bar\\Baz.txt', exec_lua(test_case))
|
||||
end)
|
||||
|
||||
it('file path including Unicode characters', function()
|
||||
local test_case = [[
|
||||
local uri = 'file:///C:/xy/%C3%A5%C3%A4%C3%B6/%C9%A7/%E6%B1%89%E8%AF%AD/%E2%86%A5/%F0%9F%A4%A6/%F0%9F%A6%84/a%CC%8A/%D8%A8%D9%90%D9%8A%D9%8E%D9%91.txt'
|
||||
|
|
|
@ -4105,4 +4105,16 @@ func Test_SwapExists_set_other_buf_modified()
|
|||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_BufEnter_botline()
|
||||
set hidden
|
||||
call writefile(range(10), 'Xxx1', 'D')
|
||||
call writefile(range(20), 'Xxx2', 'D')
|
||||
edit Xxx1
|
||||
edit Xxx2
|
||||
au BufEnter Xxx1 call assert_true(line('w$') > 1)
|
||||
edit Xxx1
|
||||
au! BufEnter Xxx1
|
||||
set hidden&vim
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
|
Loading…
Reference in New Issue