From 31ef294d05e1feeb5eb9e8ff3895d09cc93d95e4 Mon Sep 17 00:00:00 2001 From: Federico Scodelaro Date: Tue, 9 Mar 2021 16:12:10 -0300 Subject: [PATCH] Patch windows (#222) --- README.md | 3 +-- doc/nvim-tree-lua.txt | 2 +- lua/nvim-tree/fs.lua | 20 +++++++++++--------- lua/nvim-tree/git.lua | 16 ++++++++++++++-- lua/nvim-tree/lib.lua | 5 +++-- lua/nvim-tree/populate.lua | 21 ++++++++++++++++----- lua/nvim-tree/renderer.lua | 5 ++++- lua/nvim-tree/utils.lua | 22 ++++++++++++++++++++++ plugin/tree.vim | 2 +- 9 files changed, 73 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index ea8a0025..bd2623d2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ ## Notice -This plugin doesn't support windows yet. \ -This plugin requires [neovim nightly](https://github.com/neovim/neovim/wiki/Installing-Neovim). +This plugin requires [neovim nightly (>=0.5.0)](https://github.com/neovim/neovim/wiki/Installing-Neovim). ## Install diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 2dfab932..82c47b5b 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -7,7 +7,7 @@ Author: Yazdani Kiyan ============================================================================== INTRODUCTION *nvim-tree-introduction* -This file explorer doesn't work on windows and requires neovim `nightly` +This file explorer requires neovim `nightly (>= 0.5.0)` ============================================================================== QUICK START *nvim-tree-quickstart* diff --git a/lua/nvim-tree/fs.lua b/lua/nvim-tree/fs.lua index 8d3da92a..22cad45d 100644 --- a/lua/nvim-tree/fs.lua +++ b/lua/nvim-tree/fs.lua @@ -2,6 +2,7 @@ local api = vim.api local luv = vim.loop local open_mode = luv.constants.O_CREAT + luv.constants.O_WRONLY + luv.constants.O_TRUNC +local utils = require'nvim-tree.utils' local M = {} local clipboard = { move = {}, @@ -44,7 +45,7 @@ function M.create(node) local add_into if node.entries ~= nil then - add_into = node.absolute_path..'/' + add_into = utils.path_add_trailing(node.absolute_path) else add_into = node.absolute_path:sub(0, -(#node.name + 1)) end @@ -53,7 +54,7 @@ function M.create(node) clear_prompt() if not ans or #ans == 0 then return end - if not ans:match('/') then + if not ans:match(utils.path_separator) then return create_file(add_into..ans) end @@ -61,11 +62,12 @@ function M.create(node) -- if element is ending with / and it's the last element, we need to manually refresh local relpath = '' local idx = 0 - local num_entries = get_num_entries(ans:gmatch('[^/]+/?')) - for path in ans:gmatch('[^/]+/?') do + + local num_entries = get_num_entries(utils.path_split(ans)) + for path in utils.path_split(ans) do idx = idx + 1 relpath = relpath..path - if relpath:match('.*/$') then + if relpath:match('.*'..utils.path_separator..'$') then local success = luv.fs_mkdir(add_into..relpath, 493) if not success then api.nvim_err_writeln('Could not create folder '..add_into..relpath) @@ -99,7 +101,7 @@ local function remove_dir(cwd) local name, t = luv.fs_scandir_next(handle) if not name then break end - local new_cwd = cwd..'/'..name + local new_cwd = utils.path_join({cwd, name}) if t == 'directory' then local success = remove_dir(new_cwd) if not success then return false end @@ -132,8 +134,8 @@ local function do_copy(source, destination) local name, _ = luv.fs_scandir_next(handle) if not name then break end - local new_name = source..'/'..name - local new_destination = destination..'/'..name + local new_name = utils.path_join({source, name}) + local new_destination = utils.path_join({destination, name}) local success, msg = do_copy(new_name, new_destination) if not success then return success, msg end end @@ -193,7 +195,7 @@ local function do_paste(node, action_type, action_fn) end for _, entry in ipairs(clip) do - local dest = destination..'/'..entry.name + local dest = utils.path_join({destination, entry.name }) do_single_paste(entry.absolute_path, dest, action_type, action_fn) end diff --git a/lua/nvim-tree/git.lua b/lua/nvim-tree/git.lua index 8fa57953..d16dbb43 100644 --- a/lua/nvim-tree/git.lua +++ b/lua/nvim-tree/git.lua @@ -4,6 +4,7 @@ local M = {} local roots = {} local not_git = 'not a git repo' +local is_win = vim.api.nvim_call_function("has", {"win32"}) == 1 local function update_root_status(root) local untracked = ' -u' @@ -19,6 +20,12 @@ local function update_root_status(root) if body:match('%->') ~= nil then body = body:gsub('^.* %-> ', '') end + + --- Git returns paths with a forward slash wherever you run it, thats why i have to replace it only on windows + if is_win then + body = body:gsub("/", "\\") + end + roots[root][body] = head end end @@ -53,6 +60,10 @@ local function create_root(cwd) return false end + if is_win then + git_root = git_root:gsub("/", "\\") + end + update_root_status(git_root:sub(0, -2)) return true end @@ -72,11 +83,12 @@ function M.update_status(entries, cwd) return end - local matching_cwd = utils.path_to_matching_str(git_root..'/') + local matching_cwd = utils.path_to_matching_str( utils.path_add_trailing(git_root) ) + for _, node in pairs(entries) do local relpath = node.absolute_path:gsub(matching_cwd, '') if node.entries ~= nil then - relpath = relpath..'/' + relpath = utils.path_add_trailing(relpath) node.git_status = nil end diff --git a/lua/nvim-tree/lib.lua b/lua/nvim-tree/lib.lua index 7030e449..5f8f3622 100644 --- a/lua/nvim-tree/lib.lua +++ b/lua/nvim-tree/lib.lua @@ -5,6 +5,7 @@ local renderer = require'nvim-tree.renderer' local config = require'nvim-tree.config' local git = require'nvim-tree.git' local pops = require'nvim-tree.populate' +local utils = require'nvim-tree.utils' local populate = pops.populate local refresh_entries = pops.refresh_entries @@ -23,7 +24,7 @@ M.Tree = { target_winid = nil, winnr = function() for _, i in ipairs(api.nvim_list_wins()) do - if api.nvim_buf_get_name(api.nvim_win_get_buf(i)):match('.*/'..M.Tree.buf_name..'$') then + if api.nvim_buf_get_name(api.nvim_win_get_buf(i)):match('.*'..utils.path_separator..M.Tree.buf_name..'$') then return i end end @@ -319,7 +320,7 @@ end function M.close_node(node) if node.name == '..' then return end - local sep = '/' + local sep = package.config:sub(1,1) local dname = node.absolute_path:match("(.*"..sep..")") local index = 2 diff --git a/lua/nvim-tree/populate.lua b/lua/nvim-tree/populate.lua index 23cf3b85..59f22462 100644 --- a/lua/nvim-tree/populate.lua +++ b/lua/nvim-tree/populate.lua @@ -10,18 +10,27 @@ local M = { show_dotfiles = vim.g.nvim_tree_hide_dotfiles ~= 1, } -local path_to_matching_str = require'nvim-tree.utils'.path_to_matching_str +local utils = require'nvim-tree.utils' +local path_to_matching_str = utils.path_to_matching_str local function dir_new(cwd, name) - local absolute_path = cwd..'/'..name + + local absolute_path = utils.path_join({cwd, name}) local stat = luv.fs_stat(absolute_path) local handle = luv.fs_scandir(absolute_path) local has_children = handle and luv.fs_scandir_next(handle) ~= nil + + --- This is because i have some folders that i dont have permissions to read its metadata, so i have to check that stat returns a valid info + local last_modified = 0 + if stat ~= nil then + last_modified = stat.mtime.sec + end + return { name = name, absolute_path = absolute_path, -- TODO: last modified could also involve atime and ctime - last_modified = stat.mtime.sec, + last_modified = last_modified, match_name = path_to_matching_str(name), match_path = path_to_matching_str(absolute_path), open = false, @@ -31,7 +40,7 @@ local function dir_new(cwd, name) end local function file_new(cwd, name) - local absolute_path = cwd..'/'..name + local absolute_path = utils.path_join({cwd, name}) local is_exec = luv.fs_access(absolute_path, 'X') return { name = name, @@ -49,7 +58,9 @@ end -- when it has no real reason to. Maybe there is a reason, but errno is definitely wrong. -- So we need to check for link_to ~= nil when adding new links to the main tree local function link_new(cwd, name) - local absolute_path = cwd..'/'..name + + --- I dont know if this is needed, because in my understanding, there isnt hard links in windows, but just to be sure i changed it. + local absolute_path = utils.path_join({ cwd, name }) local link_to = luv.fs_realpath(absolute_path) local open, entries if (link_to ~= nil) and luv.fs_stat(link_to).type == 'directory' then diff --git a/lua/nvim-tree/renderer.lua b/lua/nvim-tree/renderer.lua index 54d85037..e4a6c484 100644 --- a/lua/nvim-tree/renderer.lua +++ b/lua/nvim-tree/renderer.lua @@ -222,7 +222,10 @@ local root_folder_modifier = vim.g.nvim_tree_root_folder_modifier or ':~' local function update_draw_data(tree, depth, markers) if tree.cwd and tree.cwd ~= '/' then - local root_name = vim.fn.fnamemodify(tree.cwd, root_folder_modifier):gsub('/$', '').."/.." + local root_name = utils.path_join({ + utils.path_remove_trailing(vim.fn.fnamemodify(tree.cwd, root_folder_modifier)), + ".." + }) table.insert(lines, root_name) table.insert(hl, {'NvimTreeRootFolder', index, 0, string.len(root_name)}) index = 1 diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 73bc15f1..d8f1ef1e 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -11,4 +11,26 @@ function M.echo_warning(msg) api.nvim_command('echohl None') end +local path_separator = package.config:sub(1,1) +function M.path_join(paths) + return table.concat(paths, path_separator) +end + +function M.path_split(path) + return path:gmatch('[^'..path_separator..']+'..path_separator..'?') +end + +function M.path_add_trailing(path) + if path:sub(-1) == path_separator then + return path + end + + return path..path_separator +end + +function M.path_remove_trailing(path) + return path:gsub(path_separator..'$', '') +end + +M.path_separator = path_separator return M diff --git a/plugin/tree.vim b/plugin/tree.vim index 9b1b2fd8..533551a7 100644 --- a/plugin/tree.vim +++ b/plugin/tree.vim @@ -1,4 +1,4 @@ -if has('win32') || exists('g:loaded_tree') | finish | endif +if !has('nvim-0.5') || exists('g:loaded_tree') | finish | endif let s:save_cpo = &cpo set cpo&vim