Skip to content
Merged
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
44 changes: 27 additions & 17 deletions lua/orgmode/capture/init.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local utils = require('orgmode.utils')
local fs = require('orgmode.utils.fs')
local config = require('orgmode.config')
local Templates = require('orgmode.capture.templates')
local Template = require('orgmode.capture.template')
Expand Down Expand Up @@ -363,12 +364,13 @@ function Capture:get_destination()
local valid_destinations = self:_get_autocompletion_files()

local destination = vim.fn.OrgmodeInput('Enter destination: ', '', function(arg_lead)
return self:autocomplete_refile(arg_lead)
return self:autocomplete_refile(arg_lead, valid_destinations)
end)

destination = vim.split(destination, '/', { plain = true })
local path = destination:match('^.*%.org/')
local headline_title = path and destination:sub(#path + 1) or ''

if not valid_destinations[destination[1]] then
if not valid_destinations[path] then
utils.echo_error(
('"%s" is not a is not a file specified in the "org_agenda_files" setting. Refiling cancelled.'):format(
destination[1]
Expand All @@ -377,11 +379,10 @@ function Capture:get_destination()
return {}
end

local destination_file = valid_destinations[destination[1]]
local destination_file = valid_destinations[path]
local result = {
file = destination_file,
}
local headline_title = table.concat({ unpack(destination, 2) }, '/')

if not headline_title or vim.trim(headline_title) == '' then
return result
Expand All @@ -406,24 +407,24 @@ function Capture:get_destination()
end

---@param arg_lead string
---@param files table<string, OrgFile>
---@return string[]
function Capture:autocomplete_refile(arg_lead)
local valid_files = self:_get_autocompletion_files(true)

function Capture:autocomplete_refile(arg_lead, files)
if not arg_lead or #arg_lead == 0 then
return vim.tbl_keys(valid_files)
return vim.tbl_keys(files)
end

local filename = vim.split(arg_lead, '/', { plain = true })[1]
local selected_file = valid_files[filename .. '/']
local filename = arg_lead:match('^.*%.org/')

local selected_file = filename and files[filename]

if not selected_file then
return vim.fn.matchfuzzy(vim.tbl_keys(valid_files), filename)
return vim.fn.matchfuzzy(vim.tbl_keys(files), filename or arg_lead)
end

local headlines = selected_file:get_opened_unfinished_headlines()
local result = vim.tbl_map(function(headline)
return string.format('%s/%s', vim.fn.fnamemodify(headline.file.filename, ':t'), headline:get_title())
return string.format('%s%s', filename, headline:get_title())
end, headlines)

return vim.tbl_filter(function(item)
Expand Down Expand Up @@ -597,16 +598,25 @@ function Capture:_create_menu_items(templates)
end

---@private
---@param add_slash_suffix? boolean
---@return table<string, OrgFile>
function Capture:_get_autocompletion_files(add_slash_suffix)
function Capture:_get_autocompletion_files()
local valid_destinations = {}
local filenames = {}
for _, file in ipairs(self.files:all()) do
if not file:is_archive_file() then
valid_destinations[vim.fn.fnamemodify(file.filename, ':t') .. (add_slash_suffix and '/' or '')] = file
table.insert(valid_destinations, file)
table.insert(filenames, file.filename)
end
end
return valid_destinations

filenames = fs.trim_common_root(filenames)
local result = {}

for i, filename in ipairs(filenames) do
result[filename .. '/'] = valid_destinations[i]
end

return result
end

---@private
Expand Down
20 changes: 20 additions & 0 deletions lua/orgmode/utils/fs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,24 @@ function M.get_current_file_dir()
return current_dir or ''
end

---@param paths string[]
---@return string[]
function M.trim_common_root(paths)
local filepaths = vim.deepcopy(paths)
table.sort(filepaths, function(a, b)
local _, count_a = a:gsub('/', '')
local _, count_b = b:gsub('/', '')
return count_a < count_b
end)

local result = {}
local root = vim.pesc(vim.fn.fnamemodify(filepaths[1], ':h')) .. '/'

for _, path in ipairs(paths) do
local relative_path = path:sub(#root + 1)
table.insert(result, relative_path)
end
return result
end

return M
Loading