WIP: force move cursor
This commit is contained in:
parent
b36ba91b7a
commit
33d5701a8d
5 changed files with 72 additions and 30 deletions
|
|
@ -27,11 +27,16 @@ local function get_column(adapter, defn)
|
||||||
return all_columns[name] or adapter.get_column(name)
|
return all_columns[name] or adapter.get_column(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param scheme string
|
---@param adapter_or_scheme string|oil.Adapter
|
||||||
---@return oil.ColumnSpec[]
|
---@return oil.ColumnSpec[]
|
||||||
M.get_supported_columns = function(scheme)
|
M.get_supported_columns = function(adapter_or_scheme)
|
||||||
|
local adapter
|
||||||
|
if type(adapter_or_scheme) == "string" then
|
||||||
|
adapter = config.get_adapter_by_scheme(adapter_or_scheme)
|
||||||
|
else
|
||||||
|
adapter = adapter_or_scheme
|
||||||
|
end
|
||||||
local ret = {}
|
local ret = {}
|
||||||
local adapter = config.get_adapter_by_scheme(scheme)
|
|
||||||
for _, def in ipairs(config.columns) do
|
for _, def in ipairs(config.columns) do
|
||||||
if get_column(adapter, def) then
|
if get_column(adapter, def) then
|
||||||
table.insert(ret, def)
|
table.insert(ret, def)
|
||||||
|
|
|
||||||
|
|
@ -138,9 +138,12 @@ M.get_trash_url = function()
|
||||||
return M.adapter_to_scheme.files .. fs.os_to_posix_path(M.trash)
|
return M.adapter_to_scheme.files .. fs.os_to_posix_path(M.trash)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param scheme string
|
---@param scheme nil|string
|
||||||
---@return nil|oil.Adapter
|
---@return nil|oil.Adapter
|
||||||
M.get_adapter_by_scheme = function(scheme)
|
M.get_adapter_by_scheme = function(scheme)
|
||||||
|
if not scheme then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
if not vim.endswith(scheme, "://") then
|
if not vim.endswith(scheme, "://") then
|
||||||
local pieces = vim.split(scheme, "://", { plain = true })
|
local pieces = vim.split(scheme, "://", { plain = true })
|
||||||
if #pieces <= 2 then
|
if #pieces <= 2 then
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ local M = {}
|
||||||
---@class oil.Entry
|
---@class oil.Entry
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field type oil.EntryType
|
---@field type oil.EntryType
|
||||||
---@field id nil|string Will be nil if it hasn't been persisted to disk yet
|
---@field id nil|integer Will be nil if it hasn't been persisted to disk yet
|
||||||
|
|
||||||
---@alias oil.EntryType "file"|"directory"|"socket"|"link"
|
---@alias oil.EntryType "file"|"directory"|"socket"|"link"
|
||||||
---@alias oil.TextChunk string|string[]
|
---@alias oil.TextChunk string|string[]
|
||||||
|
|
@ -29,15 +29,12 @@ local M = {}
|
||||||
---@return nil|oil.Entry
|
---@return nil|oil.Entry
|
||||||
M.get_entry_on_line = function(bufnr, lnum)
|
M.get_entry_on_line = function(bufnr, lnum)
|
||||||
local columns = require("oil.columns")
|
local columns = require("oil.columns")
|
||||||
local config = require("oil.config")
|
|
||||||
local parser = require("oil.mutator.parser")
|
local parser = require("oil.mutator.parser")
|
||||||
local util = require("oil.util")
|
local util = require("oil.util")
|
||||||
if vim.bo[bufnr].filetype ~= "oil" then
|
if vim.bo[bufnr].filetype ~= "oil" then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local bufname = vim.api.nvim_buf_get_name(0)
|
local adapter = util.get_adapter(bufnr)
|
||||||
local scheme = util.parse_url(bufname)
|
|
||||||
local adapter = config.get_adapter_by_scheme(scheme)
|
|
||||||
if not adapter then
|
if not adapter then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
@ -46,15 +43,15 @@ M.get_entry_on_line = function(bufnr, lnum)
|
||||||
if not line then
|
if not line then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local column_defs = columns.get_supported_columns(scheme)
|
local column_defs = columns.get_supported_columns(adapter)
|
||||||
local parsed_entry, entry = parser.parse_line(adapter, line, column_defs)
|
local result = parser.parse_line(adapter, line, column_defs)
|
||||||
if parsed_entry then
|
if result then
|
||||||
if entry then
|
if result.entry then
|
||||||
return util.export_entry(entry)
|
return util.export_entry(result.entry)
|
||||||
else
|
else
|
||||||
return {
|
return {
|
||||||
name = parsed_entry.name,
|
name = result.data.name,
|
||||||
type = parsed_entry._type,
|
type = result.data._type,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -38,27 +38,40 @@ local function parsedir(name)
|
||||||
return name, isdir
|
return name, isdir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@class oil.ParseResult
|
||||||
|
---@field data table Parsed entry data
|
||||||
|
---@field ranges table<string, integer[]> Locations of the various columns
|
||||||
|
---@field entry nil|oil.InternalEntry If the entry already exists
|
||||||
|
|
||||||
---Parse a single line in a buffer
|
---Parse a single line in a buffer
|
||||||
---@param adapter oil.Adapter
|
---@param adapter oil.Adapter
|
||||||
---@param line string
|
---@param line string
|
||||||
---@param column_defs oil.ColumnSpec[]
|
---@param column_defs oil.ColumnSpec[]
|
||||||
---@return nil|table Parsed entry data
|
---@return nil|oil.ParseResult
|
||||||
---@return nil|oil.InternalEntry If the entry already exists
|
---@return nil|string Error
|
||||||
---@return nil|string Error message
|
|
||||||
M.parse_line = function(adapter, line, column_defs)
|
M.parse_line = function(adapter, line, column_defs)
|
||||||
local ret = {}
|
local ret = {}
|
||||||
|
local ranges = {}
|
||||||
|
local start = 1
|
||||||
local value, rem = line:match("^/(%d+) (.+)$")
|
local value, rem = line:match("^/(%d+) (.+)$")
|
||||||
if not value then
|
if not value then
|
||||||
return nil, nil, "Malformed ID at start of line"
|
return nil, "Malformed ID at start of line"
|
||||||
end
|
end
|
||||||
|
ranges.id = { start, value:len() + 1 }
|
||||||
|
start = ranges.id[2] + 1
|
||||||
ret.id = tonumber(value)
|
ret.id = tonumber(value)
|
||||||
for _, def in ipairs(column_defs) do
|
for _, def in ipairs(column_defs) do
|
||||||
local name = util.split_config(def)
|
local name = util.split_config(def)
|
||||||
|
local range = { start }
|
||||||
|
local start_len = string.len(rem)
|
||||||
value, rem = columns.parse_col(adapter, rem, def)
|
value, rem = columns.parse_col(adapter, rem, def)
|
||||||
if not value then
|
if not value or not rem then
|
||||||
return nil, nil, string.format("Parsing %s failed", name)
|
return nil, string.format("Parsing %s failed", name)
|
||||||
end
|
end
|
||||||
ret[name] = value
|
ret[name] = value
|
||||||
|
range[2] = range[1] + start_len - string.len(rem) - 1
|
||||||
|
ranges[name] = range
|
||||||
|
start = range[2] + 1
|
||||||
end
|
end
|
||||||
local name = rem
|
local name = rem
|
||||||
if name then
|
if name then
|
||||||
|
|
@ -70,8 +83,9 @@ M.parse_line = function(adapter, line, column_defs)
|
||||||
ret._type = isdir and "directory" or "file"
|
ret._type = isdir and "directory" or "file"
|
||||||
end
|
end
|
||||||
local entry = cache.get_entry_by_id(ret.id)
|
local entry = cache.get_entry_by_id(ret.id)
|
||||||
|
ranges.name = { start, start + string.len(rem) - 1 }
|
||||||
if not entry then
|
if not entry then
|
||||||
return ret
|
return { data = ret, ranges = ranges }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Parse the symlink syntax
|
-- Parse the symlink syntax
|
||||||
|
|
@ -81,8 +95,9 @@ M.parse_line = function(adapter, line, column_defs)
|
||||||
local name_pieces = vim.split(ret.name, " -> ", { plain = true })
|
local name_pieces = vim.split(ret.name, " -> ", { plain = true })
|
||||||
if #name_pieces ~= 2 then
|
if #name_pieces ~= 2 then
|
||||||
ret.name = ""
|
ret.name = ""
|
||||||
return ret
|
return { data = ret, ranges = ranges }
|
||||||
end
|
end
|
||||||
|
ranges.name = { start, start + string.len(name_pieces[1]) - 1 }
|
||||||
ret.name = parsedir(vim.trim(name_pieces[1]))
|
ret.name = parsedir(vim.trim(name_pieces[1]))
|
||||||
ret.link_target = name_pieces[2]
|
ret.link_target = name_pieces[2]
|
||||||
ret._type = "link"
|
ret._type = "link"
|
||||||
|
|
@ -93,7 +108,7 @@ M.parse_line = function(adapter, line, column_defs)
|
||||||
ret._type = entry[FIELD.type]
|
ret._type = entry[FIELD.type]
|
||||||
end
|
end
|
||||||
|
|
||||||
return ret, entry
|
return { data = ret, entry = entry, ranges = ranges }
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
|
|
@ -113,8 +128,8 @@ M.parse = function(bufnr)
|
||||||
return diffs, errors
|
return diffs, errors
|
||||||
end
|
end
|
||||||
local scheme, path = util.parse_url(bufname)
|
local scheme, path = util.parse_url(bufname)
|
||||||
local column_defs = columns.get_supported_columns(scheme)
|
|
||||||
local parent_url = scheme .. path
|
local parent_url = scheme .. path
|
||||||
|
local column_defs = columns.get_supported_columns(adapter)
|
||||||
local children = cache.list_url(parent_url)
|
local children = cache.list_url(parent_url)
|
||||||
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
||||||
local original_entries = {}
|
local original_entries = {}
|
||||||
|
|
@ -137,8 +152,8 @@ M.parse = function(bufnr)
|
||||||
end
|
end
|
||||||
for i, line in ipairs(lines) do
|
for i, line in ipairs(lines) do
|
||||||
if line:match("^/%d+") then
|
if line:match("^/%d+") then
|
||||||
local parsed_entry, entry, err = M.parse_line(adapter, line, column_defs)
|
local result, err = M.parse_line(adapter, line, column_defs)
|
||||||
if not parsed_entry then
|
if not result or err then
|
||||||
table.insert(errors, {
|
table.insert(errors, {
|
||||||
message = err,
|
message = err,
|
||||||
lnum = i - 1,
|
lnum = i - 1,
|
||||||
|
|
@ -146,6 +161,8 @@ M.parse = function(bufnr)
|
||||||
})
|
})
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
local parsed_entry = result.data
|
||||||
|
local entry = result.entry
|
||||||
if not parsed_entry.name or parsed_entry.name:match("/") or not entry then
|
if not parsed_entry.name or parsed_entry.name:match("/") or not entry then
|
||||||
local message
|
local message
|
||||||
if not parsed_entry.name then
|
if not parsed_entry.name then
|
||||||
|
|
|
||||||
|
|
@ -244,11 +244,33 @@ M.initialize = function(bufnr)
|
||||||
group = "Oil",
|
group = "Oil",
|
||||||
buffer = bufnr,
|
buffer = bufnr,
|
||||||
callback = function()
|
callback = function()
|
||||||
|
local oil = require("oil")
|
||||||
|
local parser = require("oil.mutator.parser")
|
||||||
|
|
||||||
|
-- Force the cursor to be after the (concealed) ID at the beginning of the line
|
||||||
|
local adapter = util.get_adapter(bufnr)
|
||||||
|
if adapter then
|
||||||
|
local cur = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local line = vim.api.nvim_buf_get_lines(bufnr, cur[1] - 1, cur[1], true)[1]
|
||||||
|
local column_defs = columns.get_supported_columns(adapter)
|
||||||
|
local result = parser.parse_line(adapter, line, column_defs)
|
||||||
|
if result and result.data then
|
||||||
|
local min_col = result.ranges.id[2] + 1
|
||||||
|
if cur[2] < min_col then
|
||||||
|
vim.api.nvim_win_set_cursor(0, { cur[1], min_col })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debounce and update the preview window
|
||||||
if timer then
|
if timer then
|
||||||
timer:again()
|
timer:again()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
timer = vim.loop.new_timer()
|
timer = vim.loop.new_timer()
|
||||||
|
if not timer then
|
||||||
|
return
|
||||||
|
end
|
||||||
timer:start(10, 100, function()
|
timer:start(10, 100, function()
|
||||||
timer:stop()
|
timer:stop()
|
||||||
timer:close()
|
timer:close()
|
||||||
|
|
@ -257,7 +279,6 @@ M.initialize = function(bufnr)
|
||||||
if vim.api.nvim_get_current_buf() ~= bufnr then
|
if vim.api.nvim_get_current_buf() ~= bufnr then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local oil = require("oil")
|
|
||||||
local entry = oil.get_cursor_entry()
|
local entry = oil.get_cursor_entry()
|
||||||
if entry then
|
if entry then
|
||||||
local winid = util.get_preview_win()
|
local winid = util.get_preview_win()
|
||||||
|
|
@ -397,7 +418,6 @@ local function render_buffer(bufnr, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
---@param adapter oil.Adapter
|
|
||||||
---@param entry oil.InternalEntry
|
---@param entry oil.InternalEntry
|
||||||
---@param column_defs table[]
|
---@param column_defs table[]
|
||||||
---@param col_width integer[]
|
---@param col_width integer[]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue