Compare commits

...

8 Commits

Author SHA1 Message Date
Francesco Luzzi 1340cd9730
Merge 63e8575217 into 435dee74bb 2024-04-27 06:04:35 +07:00
zeertzjq 435dee74bb
vim-patch:9.1.0374: wrong botline in BufEnter (#28530)
Problem:  When :edit an existing buffer, line('w$') may return a
          wrong result.
Solution: Reset w_valid in curwin_init() (Jaehwang Jung)

`do_ecmd()` reinitializes the current window (`curwin_init()`) whose
`w_valid` field may have `VALID_BOTLINE` set. Resetting `w_botline`
without marking it as invalid makes subsequent `validate_botline()`
calls a no-op, thus resulting in wrong `line('w$')` value.

closes: vim/vim#14642

eb80b8304e

Co-authored-by: Jaehwang Jung <tomtomjhj@gmail.com>
2024-04-27 06:32:25 +08:00
zeertzjq 694756252b
Merge pull request #28529 from zeertzjq/vim-fe1e2b5e2d65
vim-patch: clarify syntax vs matching mechanism
2024-04-27 06:31:55 +08:00
FrancescoLuzzi 63e8575217 fix(uri): using vim.normalize to simplify code 2024-04-27 00:06:33 +02:00
zeertzjq e81eb34aa1 vim-patch:9525f6213604
runtime(doc): fix typo synconcealend -> synconcealed (vim/vim#14644)

9525f62136

Co-authored-by: Philip H <47042125+pheiduck@users.noreply.github.com>
2024-04-27 05:52:47 +08:00
zeertzjq a1568f5df0 vim-patch:00ae5c5cba7b
runtime(doc): fix typo

00ae5c5cba

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-04-27 05:52:15 +08:00
zeertzjq f1f5fb911b vim-patch:fe1e2b5e2d65
runtime(doc): clarify syntax vs matching mechanism

fixes: vim/vim#14643

fe1e2b5e2d

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-04-27 05:51:52 +08:00
FrancescoLuzzi 1edadd8501 fix(uri): correctly convert win UNC path to URI 2024-04-21 17:36:11 +02:00
11 changed files with 105 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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*

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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' } },

View File

@ -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;
}

View File

@ -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'

View File

@ -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