Skip to content

feat(api): Allow to insert links through API #731

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

Merged
merged 2 commits into from
May 22, 2024
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
9 changes: 9 additions & 0 deletions lua/orgmode/api/init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---@diagnostic disable: invisible
local OrgFile = require('orgmode.api.file')
local OrgHeadline = require('orgmode.api.headline')
local Hyperlinks = require('orgmode.org.hyperlinks')
local Link = require('orgmode.org.hyperlinks.link')
local orgmode = require('orgmode')

---@class OrgApiRefileOpts
Expand Down Expand Up @@ -99,4 +101,11 @@ function OrgApi.refile(opts)
return true
end

--- Insert a link to a given location at the current cursor position
--- @param link_location string
--- @return boolean
function OrgApi.insert_link(link_location)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's abstract all this logic in Hyperlinks and then require that one here. I'm trying not to depend on orgmode.api in the core, but vice versa.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit, that I just looked at other functions, which had similar calling schemes, but I agree, that it would be cleaner to move them into Hyperlinks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the code as you suggested.

Hyperlinks.insert_link(link_location)
end

return OrgApi
55 changes: 55 additions & 0 deletions lua/orgmode/org/hyperlinks/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local org = require('orgmode')
local utils = require('orgmode.utils')
local fs = require('orgmode.utils.fs')
local Url = require('orgmode.org.hyperlinks.url')
local Link = require('orgmode.org.hyperlinks.link')
local config = require('orgmode.config')
local Hyperlinks = {
stored_links = {},
Expand Down Expand Up @@ -205,4 +206,58 @@ function Hyperlinks.autocomplete_links(arg_lead)
return vim.tbl_keys(Hyperlinks.stored_links)
end

---@return OrgLink|nil, table | nil
function Hyperlinks.get_link_under_cursor()
local line = vim.fn.getline('.')
local col = vim.fn.col('.') or 0
return Link.at_pos(line, col)
end

function Hyperlinks.insert_link(link_location)
local selected_link = Link:new(link_location)
local desc = selected_link.url:get_target_value()
if selected_link.url:is_id() then
local id_link = ('id:%s'):format(selected_link.url:get_id())
desc = link_location:gsub('^' .. vim.pesc(id_link) .. '%s+', '')
link_location = id_link
end

local link_description = vim.trim(vim.fn.OrgmodeInput('Description: ', desc or ''))

link_location = '[' .. vim.trim(link_location) .. ']'

if link_description ~= '' then
link_description = '[' .. link_description .. ']'
end

local insert_from
local insert_to
local target_col = #link_location + #link_description + 2

-- check if currently on link
local link, position = Hyperlinks.get_link_under_cursor()
if link and position then
insert_from = position.from - 1
insert_to = position.to + 1
target_col = target_col + position.from
else
local colnr = vim.fn.col('.')
insert_from = colnr
insert_to = colnr + 1
target_col = target_col + colnr
end

local linenr = vim.fn.line('.') or 0
local curr_line = vim.fn.getline(linenr)
local new_line = string.sub(curr_line, 0, insert_from)
.. '['
.. link_location
.. link_description
.. ']'
.. string.sub(curr_line, insert_to, #curr_line)

vim.fn.setline(linenr, new_line)
vim.fn.cursor(linenr, target_col)
end

return Hyperlinks
55 changes: 3 additions & 52 deletions lua/orgmode/org/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local Promise = require('orgmode.utils.promise')
local events = EventManager.event
local Link = require('orgmode.org.hyperlinks.link')
local Babel = require('orgmode.babel')
local OrgApi = require('orgmode.api')

---@class OrgMappings
---@field capture OrgCapture
Expand Down Expand Up @@ -736,50 +737,7 @@ function OrgMappings:insert_link()
return
end

local selected_link = Link:new(link_location)
local desc = selected_link.url:get_target_value()
if selected_link.url:is_id() then
local id_link = ('id:%s'):format(selected_link.url:get_id())
desc = link_location:gsub('^' .. vim.pesc(id_link) .. '%s+', '')
link_location = id_link
end

local link_description = vim.trim(vim.fn.OrgmodeInput('Description: ', desc or ''))

link_location = '[' .. vim.trim(link_location) .. ']'

if link_description ~= '' then
link_description = '[' .. link_description .. ']'
end

local insert_from
local insert_to
local target_col = #link_location + #link_description + 2

-- check if currently on link
local link, position = self:_get_link_under_cursor()
if link and position then
insert_from = position.from - 1
insert_to = position.to + 1
target_col = target_col + position.from
else
local colnr = vim.fn.col('.')
insert_from = colnr
insert_to = colnr + 1
target_col = target_col + colnr
end

local linenr = vim.fn.line('.') or 0
local curr_line = vim.fn.getline(linenr)
local new_line = string.sub(curr_line, 0, insert_from)
.. '['
.. link_location
.. link_description
.. ']'
.. string.sub(curr_line, insert_to, #curr_line)

vim.fn.setline(linenr, new_line)
vim.fn.cursor(linenr, target_col)
Hyperlinks.insert_link(link_location)
end

function OrgMappings:store_link()
Expand Down Expand Up @@ -823,7 +781,7 @@ function OrgMappings:_edit_special_callback()
end

function OrgMappings:open_at_point()
local link = self:_get_link_under_cursor()
local link = Hyperlinks.get_link_under_cursor()
if not link then
local date = self:_get_date_under_cursor()
if date then
Expand Down Expand Up @@ -1138,13 +1096,6 @@ function OrgMappings:_adjust_date(amount, span, fallback)
return vim.api.nvim_feedkeys(utils.esc(fallback), 'n', true)
end

---@return OrgLink|nil, table | nil
function OrgMappings:_get_link_under_cursor()
local line = vim.fn.getline('.')
local col = vim.fn.col('.') or 0
return Link.at_pos(line, col)
end

---@param headline OrgHeadline
function OrgMappings:_goto_headline(headline)
local current_file_path = utils.current_file_path()
Expand Down
Loading