Skip to content

Commit

Permalink
fix: fix joining paths in Windows (#168)
Browse files Browse the repository at this point in the history
* fix: use plenary.path to manage paths in Windows

* fix: filter out paths validly in Windows

* fix: detect default `ignore_patterns` in Windows

fix: #169

* fix: join paths validly in Windows

* docs: fix value for `ignore_patterns` in Windows

* fix: avoid duplication of separators in paths

Fix: #171
This fixes only in native logic. The one with SQLite has still bugs.
……but that may not be fixed.
  • Loading branch information
delphinus authored Jan 28, 2024
1 parent 1189184 commit a3e818d
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 14 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ See [default configuration](https://github.com/nvim-telescope/telescope.nvim#tel

Delimiters to indicate the filter like `:CWD:`.

- `ignore_patterns` (default: `{ "*.git/*", "*/tmp/*", "term://*" }`)
- `ignore_patterns`
(default: for non-Windows → `{ "*.git/*", "*/tmp/*", "term://*" }`,
for Windows → `{ [[*.git\*]], [[*\tmp\*]], "term://*" }`)

Patterns in this table control which files are indexed (and subsequently
which you'll see in the finder results).
Expand Down
2 changes: 1 addition & 1 deletion lua/frecency/database/native.lua
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function Native:get_entries(workspace, datetime)
local now = self:now(datetime)
local items = {}
for path, record in pairs(self.table.records) do
if not workspace or path:find(workspace .. "/", 1, true) then
if self.fs:starts_with(path, workspace) then
table.insert(items, {
path = path,
count = record.count,
Expand Down
6 changes: 4 additions & 2 deletions lua/frecency/finder.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local os_util = require "frecency.os_util"
local Job = require "plenary.job"
local async = require "plenary.async" --[[@as PlenaryAsync]]
local log = require "plenary.log"
Expand Down Expand Up @@ -88,6 +89,7 @@ function Finder:start(datetime)
-- NOTE: return to the main loop to show the main window
async.util.scheduler()
for _, file in ipairs(self:get_results(self.path, datetime)) do
file.path = os_util.normalize_sep(file.path)
local entry = self.entry_maker(file)
self.tx.send(entry)
end
Expand All @@ -107,7 +109,7 @@ function Finder:scan_dir_cmd(cmd)
if not self.closed and not err and chunk then
for name in chunk:gmatch "[^\n]+" do
local cleaned = name:gsub("^%./", "")
local fullpath = self.fs.joinpath(self.path, cleaned)
local fullpath = os_util.join_path(self.path, cleaned)
local entry = self.entry_maker { id = 0, count = 0, path = fullpath, score = 0 }
self.scan_tx.send(entry)
end
Expand Down Expand Up @@ -163,7 +165,7 @@ function Finder:scan_dir_lua()
if self.closed then
break
end
local fullpath = self.fs.joinpath(self.path, name)
local fullpath = os_util.join_path(self.path, name)
local entry = self.entry_maker { id = 0, count = 0, path = fullpath, score = 0 }
self.scan_tx.send(entry)
count = count + 1
Expand Down
4 changes: 3 additions & 1 deletion lua/frecency/frecency.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local Picker = require "frecency.picker"
local Recency = require "frecency.recency"
local WebDevicons = require "frecency.web_devicons"
local sqlite_module = require "frecency.sqlite"
local os_util = require "frecency.os_util"
local log = require "plenary.log"

---@class Frecency
Expand Down Expand Up @@ -49,7 +50,8 @@ Frecency.new = function(opts)
default_workspace = nil,
disable_devicons = false,
filter_delimiter = ":",
ignore_patterns = { "*.git/*", "*/tmp/*", "term://*" },
ignore_patterns = os_util.is_windows and { [[*.git\*]], [[*\tmp\*]], "term://*" }
or { "*.git/*", "*/tmp/*", "term://*" },
max_timestamps = 10,
show_filter_column = true,
show_scores = false,
Expand Down
26 changes: 19 additions & 7 deletions lua/frecency/fs.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
local os_util = require "frecency.os_util"
local Path = require "plenary.path" --[[@as PlenaryPath]]
local scandir = require "plenary.scandir"
local log = require "plenary.log"
local uv = vim.uv or vim.loop

---@class FrecencyFS
---@field os_homedir string
---@field joinpath fun(...: string): string
---@field private config FrecencyFSConfig
---@field private ignore_regexes string[]
local FS = {}
Expand All @@ -27,10 +27,6 @@ FS.new = function(config)
local regex = escaped:gsub("%%%*", ".*"):gsub("%%%?", ".")
return "^" .. regex .. "$"
end, self.config.ignore_patterns)
---This is needed for Neovim v0.9.0.
self.joinpath = vim.fs.joinpath or function(...)
return (table.concat({ ... }, "/"):gsub("//+", "/"))
end
return self
end

Expand All @@ -50,13 +46,13 @@ function FS:scan_dir(path)
vim.fs.dir(path, {
depth = self.config.scan_depth,
skip = function(dirname)
if self:is_ignored(self.joinpath(path, dirname)) then
if self:is_ignored(os_util.join_path(path, dirname)) then
return false
end
end,
})
do
local fullpath = self.joinpath(path, name)
local fullpath = os_util.join_path(path, name)
if type == "file" and not self:is_ignored(fullpath) and gitignore({ path }, fullpath) then
coroutine.yield(name)
end
Expand All @@ -70,6 +66,22 @@ function FS:relative_from_home(path)
return Path:new(path):make_relative(self.os_homedir)
end

---@type table<string,string>
local with_sep = {}

---@param path string
---@param base string?
---@return boolean
function FS:starts_with(path, base)
if not base then
return true
end
if not with_sep[base] then
with_sep[base] = base .. (base:sub(#base) == Path.path.sep and "" or Path.path.sep)
end
return path:find(with_sep[base], 1, true) == 1
end

---@private
---@param path string
---@return boolean
Expand Down
30 changes: 30 additions & 0 deletions lua/frecency/os_util.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
local Path = require "plenary.path"
local uv = vim.uv or vim.loop

local M = {
is_windows = uv.os_uname().sysname == "Windows_NT",
}

---@type fun(filename: string): string
M.normalize_sep = M.is_windows
and function(filename)
if not filename:find("/", 1, true) or filename:match "^%a+://" then
return filename
end
local replaced = filename:gsub("/", Path.path.sep)
return replaced
end
or function(filename)
return filename
end

--- Join path segments into a single path string.
--- NOTE: Do not use vim.fs.joinpath because it does not work on Windows.
---@type fun(...: string): string
M.join_path = M.is_windows and function(...)
return M.normalize_sep(Path:new(...).filename)
end or function(...)
return Path:new(...).filename
end

return M
4 changes: 2 additions & 2 deletions lua/frecency/picker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ function Picker:default_path_display(opts, path)
local filename = Path:new(path):make_relative(opts.cwd)
if not self.workspace then
if vim.startswith(filename, self.fs.os_homedir) then
filename = "~/" .. self.fs:relative_from_home(filename)
filename = "~" .. Path.path.sep .. self.fs:relative_from_home(filename)
elseif filename ~= path then
filename = "./" .. filename
filename = "." .. Path.path.sep .. filename
end
end
return filename
Expand Down

0 comments on commit a3e818d

Please sign in to comment.