Skip to content

msys2 bruteforce path support #663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions lua/plenary/job.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ local compat = require "plenary.compat"

local F = require "plenary.functional"

--qqq
local U = require "plenary.utils"
--!qqq

---@class Job
---@field command string Command to run
---@field args? string[] List of arguments to pass
Expand Down Expand Up @@ -64,8 +68,24 @@ end

local function expand(path)
if vim.in_fast_event() then
--qqq
if U.is_msys2 then
path = U.posix_to_windows(path)
-- Experiments with "{}" escaping.
--path = U.posix_to_windows(vim.fn.expand(vim.fn.escape(path, "{}[]$"), true))
end
return assert(uv.fs_realpath(path), string.format("Path must be valid: %s", path))
--!qqq
--return assert(uv.fs_realpath(path), string.format("Path must be valid: %s", path))
else
--qqq
if U.is_msys2 then
path = U.posix_to_windows(vim.fn.expand(vim.fn.escape(path, "[]$"), true))
--path = U.posix_to_windows(vim.fn.expand(vim.fn.escape(path, "{}[]$"), true))
--path = U.posix_to_windows(vim.fn.expand(path), true)
return path
end
--!qqq
-- TODO: Probably want to check that this is valid here... otherwise that's weird.
return vim.fn.expand(vim.fn.escape(path, "[]$"), true)
end
Expand Down Expand Up @@ -112,6 +132,18 @@ function Job:new(o)

obj.command = command
obj.args = args
--qqq
-- This is so annoying that path can be in posix style even here.
--vim.notify("Job:new(): " .. vim.inspect(obj), vim.log.levels.ERROR)
if U.is_msys2 and o.cwd then
-- "git_apply_stash" from Telescope does not work here possibly due to nil "o.cwd".
-- NVM. This was caused by curly braces expansion in stash@{0}.
--if not o.cwd then
-- o.cwd = vim.loop.cwd()
--end
o.cwd = U.posix_to_windows(o.cwd)
end
--!qqq
obj._raw_cwd = o.cwd
if o.env then
if type(o.env) ~= "table" then
Expand Down Expand Up @@ -269,6 +301,12 @@ function Job:_create_uv_options()
options.stdio = { self.stdin, self.stdout, self.stderr }

if self._raw_cwd then
--qqq
if U.is_msys2 then
--vim.notify("Job:_create_uv_options(): " .. vim.inspect(self), vim.log.levels.ERROR)
self._raw_cwd = U.posix_to_windows(self._raw_cwd)
end
--!qqq
options.cwd = expand(self._raw_cwd)
end
if self.env then
Expand Down Expand Up @@ -400,6 +438,15 @@ function Job:_execute()
self:_user_on_start()
end

--qqq
-- Path can be in posix style even here
-- UPD. Making the path transformation in Job:new() solves "nvim ."->":Telescope git_commits"
--if U.is_msys2 then
-- vim.notify("Job:_execute(): " .. vim.inspect(self) .. ", " .. vim.inspect(options), vim.log.levels.ERROR)
-- self._raw_cwd = U.posix_to_windows(self._raw_cwd)
--end
--!qqq

self.handle, self.pid = uv.spawn(options.command, options, shutdown_factory(self, options))

if not self.handle then
Expand Down
134 changes: 124 additions & 10 deletions lua/plenary/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ local uv = vim.loop

local F = require "plenary.functional"

--qqq
local U = require "plenary.utils"
--!qqq

local S_IF = {
-- S_IFDIR = 0o040000 # directory
DIR = 0x4000,
Expand All @@ -16,14 +20,29 @@ local S_IF = {
}

local path = {}
path.home = vim.loop.os_homedir()
--qqq
-- vim.loop.os_homedir() ignores HOME env var in msys2
if U.is_msys2 then
path.home = U.posix_to_windows(vim.fn.expand("~"))
else
path.home = vim.loop.os_homedir()
end
--!qqq
--path.home = vim.loop.os_homedir()

path.sep = (function()
if jit then
local os = string.lower(jit.os)
if os ~= "windows" then
if os ~= "windows" and not U.is_msys2 then
return "/"
else
--qqq
--vim.notify("os: " .. vim.inspect(os) .. ", U.is_msys: " .. vim.inspect(U.is_msys2), vim.log.levels.ERROR)
-- msys2 works fine with forward slashes as well as cmd.exe/powershell.exe
-- but not UNC paths if the paths will ever be supported.
-- Maybe returning "/" as path separator can break something in existing logic.
--return "/"
--!qqq
return "\\"
end
else
Expand All @@ -39,7 +58,17 @@ path.root = (function()
else
return function(base)
base = base or vim.loop.cwd()
return base:sub(1, 1) .. ":\\"
--qqq
if U.is_msys2 then
base = U.posix_to_windows(base)
--if not base:find("^[A-Za-z]:" .. path.sep) then
-- vim.notify("path.root IIFE: base has incorrect path style for msys2!", vim.log.levels.ERROR)
--end
end
return base:sub(1, 1) .. ":" .. path.sep
--return base:sub(1, 3)
--!qqq
--return base:sub(1, 1) .. ":\\"
end
end
end)()
Expand All @@ -55,8 +84,14 @@ local concat_paths = function(...)
end

local function is_root(pathname)
if path.sep == "\\" then
return string.match(pathname, "^[A-Z]:\\?$")
if path.sep == "\\" or U.is_msys2 then
--qqq
if U.is_msys2 then
pathname = U.posix_to_windows(pathname)
end
return string.match(pathname, "^[A-Za-z]:[\\/]?$")
--!qqq
--return string.match(pathname, "^[A-Z]:\\?$")
end
return pathname == "/"
end
Expand All @@ -77,7 +112,12 @@ local is_uri = function(filename)
end

local is_absolute = function(filename, sep)
if sep == "\\" then
if sep == "\\" or U.is_msys2 then
--qqq
if U.is_msys2 then
filename = U.posix_to_windows(filename)
end
--!qqq
return string.match(filename, "^[%a]:[\\/].*$") ~= nil
end
return string.sub(filename, 1, 1) == sep
Expand All @@ -98,12 +138,22 @@ local function _normalize_path(filename, cwd)

local has = string.find(filename, path.sep .. "..", 1, true) or string.find(filename, ".." .. path.sep, 1, true)

--qqq
--vim.notify("_normalize_path: has = " .. vim.inspect(has), vim.log.levels.WARN)
--!qqq

if has then
local is_abs = is_absolute(filename, path.sep)
--qqq
--vim.notify("_normalize_path: is_abs = " .. vim.inspect(is_abs), vim.log.levels.WARN)
--!qqq
local split_without_disk_name = function(filename_local)
local parts = _split_by_separator(filename_local)
-- Remove disk name part on Windows
if path.sep == "\\" and is_abs then
if is_abs and (path.sep == "\\" or U.is_msys2) then
--qqq
--vim.notify("_normalize_path: parts = " .. vim.inspect(parts), vim.log.levels.WARN)
--!qqq
table.remove(parts, 1)
end
return parts
Expand Down Expand Up @@ -137,9 +187,19 @@ local function _normalize_path(filename, cwd)
out_file = prefix .. table.concat(parts, path.sep)
end

--qqq
if U.is_msys2 then
out_file = U.posix_to_windows(out_file)
end
--!qqq

return out_file
end

--qqq
--vim.notify("_normalize_path: call returned " .. vim.inspect(_normalize_path("C:\\msys64\\home\\..\\123", "C:\\msys64\\123")), vim.log.levels.WARN)
--!qqq

local clean = function(pathname)
if is_uri(pathname) then
return pathname
Expand Down Expand Up @@ -182,12 +242,22 @@ Path.__index = function(t, k)

if k == "_cwd" then
local cwd = uv.fs_realpath "."
--qqq
if U.is_msys2 then
cwd = U.posix_to_windows(cwd)
end
--!qqq
t._cwd = cwd
return cwd
end

if k == "_absolute" then
local absolute = uv.fs_realpath(t.filename)
--qqq
if U.is_msys2 then
absolute = U.posix_to_windows(absolute)
end
--!qqq
t._absolute = absolute
return absolute
end
Expand Down Expand Up @@ -234,6 +304,13 @@ function Path:new(...)
-- If we already have a Path, it's fine.
-- Just return it
if Path.is_path(path_input) then
--qqq
-- Maybe we should fix fields with paths here as well
--if U.is_msys2 then
-- vim.notify("Path:new(...): returning already defined Path object " .. vim.inspect(path_input), vim.log.levels.ERROR)
-- path_input.filename = U.posix_to_windows(path_input.filename)
--end
--!qqq
return path_input
end

Expand All @@ -259,8 +336,18 @@ function Path:new(...)
end

path_string = table.concat(path_objs, sep)
--qqq
if U.is_msys2 then
path_string = U.posix_to_windows(path_string)
end
--!qqq
else
assert(type(path_input) == "string", vim.inspect(path_input))
--qqq
if U.is_msys2 then
path_input = U.posix_to_windows(path_input)
end
--!qqq
path_string = path_input
end

Expand Down Expand Up @@ -319,7 +406,15 @@ function Path:expand()
-- TODO support windows
local expanded
if string.find(self.filename, "~") then
expanded = string.gsub(self.filename, "^~", vim.loop.os_homedir())
--qqq
-- vim.loop.os_homedir() ignores HOME env variable in msys2
if U.is_msys2 then
expanded = string.gsub(self.filename, "^~", vim.fn.expand("~"))
else
expanded = string.gsub(self.filename, "^~", vim.loop.os_homedir())
end
--!qqq
--expanded = string.gsub(self.filename, "^~", vim.loop.os_homedir())
elseif string.find(self.filename, "^%.") then
expanded = vim.loop.fs_realpath(self.filename)
if expanded == nil then
Expand All @@ -336,9 +431,22 @@ function Path:expand()
else
expanded = self.filename
end
--qqq
if expanded and U.is_msys2 then
--vim.notify("Path:expand(): " .. "vim.inspect(expanded), vim.log.levels.ERROR")
expanded = U.posix_to_windows(expanded)
end
--!qqq
return expanded and expanded or error "Path not valid"
end

--qqq
-- Can be tough to achieve in msys2 for posix-style paths.
-- Like from C:\\msys64\\home\\User\\personal\\project\\src\\file.lua (rel. src\\file.lua)
-- to /home/User/personal/project/src/file.lua (rel. src/file.lua).
-- This will probably require back-and-forth path conversions.
-- But do we actually need to bother about that instead of leaving Windows-style rel. path?
--!qqq
function Path:make_relative(cwd)
if is_uri(self.filename) then
return self.filename
Expand All @@ -358,6 +466,12 @@ function Path:make_relative(cwd)
end
end

--qqq
if U.is_msys2 then
self.filename = U.posix_to_windows(self.filename)
end
--!qqq

return self.filename
end

Expand Down Expand Up @@ -435,7 +549,7 @@ local shorten = (function()
return shorten_len(filename, 1)
end

if jit and path.sep ~= "\\" then
if jit and path.sep ~= "\\" then --and not U.is_msys2 then
local ffi = require "ffi"
ffi.cdef [[
typedef unsigned char char_u;
Expand Down Expand Up @@ -489,7 +603,7 @@ function Path:mkdir(opts)
for _, dir in ipairs(dirs) do
if dir ~= "" then
local joined = concat_paths(processed, dir)
if processed == "" and self._sep == "\\" then
if processed == "" and (self._sep == "\\") then -- or U.is_msys2) then
joined = dir
end
local stat = uv.fs_stat(joined) or {}
Expand Down
Loading