From de194e8cc19f41738ef0db35dbfb7d4d4279c560 Mon Sep 17 00:00:00 2001 From: xudyang1 <61672396+xudyang1@users.noreply.github.com> Date: Tue, 21 May 2024 00:28:33 -0400 Subject: [PATCH] fix(help_tags): show help tags on windows (#3126) On Windows, `builtin.help_tags` picker does not show any help tags. To fix this, the following changes are needed: 1. `util.path_tail` checks unix separator `/` on Windows and leave the original implementation intact on unix systems. 2. Line endings should be taken carefully on Windows. `vim.split` with only newline `\n` character as separator may result in unexpected crash when parsing large files. When splits on lines are needed, call it with `\r?\n`, or even set up a wrapper function in utils is more prefered. Fixes #3126 --- lua/telescope/builtin/__internal.lua | 2 +- lua/telescope/utils.lua | 24 ++++++++--- lua/tests/automated/utils_spec.lua | 61 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/lua/telescope/builtin/__internal.lua b/lua/telescope/builtin/__internal.lua index 5db4a69d03..9149ecb4db 100644 --- a/lua/telescope/builtin/__internal.lua +++ b/lua/telescope/builtin/__internal.lua @@ -729,7 +729,7 @@ internal.help_tags = function(opts) local delimiter = string.char(9) for _, lang in ipairs(langs) do for _, file in ipairs(tag_files[lang] or {}) do - local lines = vim.split(Path:new(file):read(), "\n", true) + local lines = vim.split(Path:new(file):read(), "\r?\n", { trimempty = true }) for _, line in ipairs(lines) do -- TODO: also ignore tagComment starting with ';' if not line:match "^!_TAG_" then diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua index c2ee27f264..55d93698d3 100644 --- a/lua/telescope/utils.lua +++ b/lua/telescope/utils.lua @@ -213,16 +213,30 @@ utils.path_smart = (function() end end)() +-- vim.fn.fnamemodify(path, ":p:t") may replace util.path_tail(path), +-- but the former may be slower and has dependency on neovim utils.path_tail = (function() local os_sep = utils.get_separator() - return function(path) - for i = #path, 1, -1 do - if path:sub(i, i) == os_sep then - return path:sub(i + 1, -1) + if os_sep == "/" then + return function(path) + for i = #path, 1, -1 do + if path:sub(i, i) == os_sep then + return path:sub(i + 1, -1) + end end + return path + end + else + return function(path) + for i = #path, 1, -1 do + local c = path:sub(i, i) + if c == os_sep or c == "/" then + return path:sub(i + 1, -1) + end + end + return path end - return path end end)() diff --git a/lua/tests/automated/utils_spec.lua b/lua/tests/automated/utils_spec.lua index 51c3526648..871dee66c2 100644 --- a/lua/tests/automated/utils_spec.lua +++ b/lua/tests/automated/utils_spec.lua @@ -307,3 +307,64 @@ describe("transform_path", function() end, new_relpath "doc/mydoc.md", new_relpath "d/mydoc.md") end) end) + +describe("path_tail", function() + local Path = require "plenary.path" + local old_sep = Path.path.sep + + before_each(function() + Path.path.sep = old_sep + end) + + local function setup_windows_sep() + Path.path.sep = [[\]] + end + local function setup_unix_sep() + Path.path.sep = "/" + end + + local function assert_tails(paths) + for _, path in ipairs(paths) do + it("gets the tail of " .. path, function() + local tail = vim.fn.fnamemodify(path, ":p:t") + eq(tail, utils.path_tail(path)) + end) + end + end + + describe("handles windows paths", function() + local paths = { + [[C:\Users\username\AppData\Local\nvim-data\log]], + [[D:\Projects\project_folder\source_code.py]], + [[E:\Music\song.mp3]], + [[/home/usuario/documents/archivo.txt]], + [[/var/www/html/index.html]], + [[/mnt/backup/backup_file.tar.gz]], + } + + setup_windows_sep() + assert_tails(paths) + end) + + describe("handles linux paths", function() + local paths = { + [[/home/usuario/documents/archivo.txt]], + [[/var/www/html/index.html]], + [[/mnt/backup/backup_file.tar.gz]], + } + + setup_unix_sep() + assert_tails(paths) + end) + + describe("handles macos paths", function() + local paths = { + [[/Users/Usuario/Documents/archivo.txt]], + [[/Applications/App.app/Contents/MacOS/app_executable]], + [[/Volumes/ExternalDrive/Data/file.xlsx]], + } + + setup_unix_sep() + assert_tails(paths) + end) +end)