Add function to search for next link on line
By choosing 'line' in the `zettel_link_following` option, the link to be opened will be searched for on the complete rest of the line, meaning from the cursor to the newline symbol onwards.
This commit is contained in:
parent
572ed6726b
commit
ba033e2b24
3 changed files with 66 additions and 57 deletions
12
README.md
12
README.md
|
@ -5,9 +5,9 @@ To develop / debug:
|
||||||
start neovim with `nvim --cmd "set rtp+=$(pwd)" .` to automatically load the files in project dir as if they were on path
|
start neovim with `nvim --cmd "set rtp+=$(pwd)" .` to automatically load the files in project dir as if they were on path
|
||||||
|
|
||||||
next up:
|
next up:
|
||||||
* link following option (under cursor, next on line)
|
* [x] link following option (under cursor, next on line)
|
||||||
* next link on line function (actions)
|
* [x] next link on line function (actions)
|
||||||
* helper function to decide which one to use from A.open
|
* [x] helper function to decide which one to use from A.open
|
||||||
|
|
||||||
## TODO: needed functionality
|
## TODO: needed functionality
|
||||||
|
|
||||||
|
@ -19,10 +19,11 @@ next up:
|
||||||
* [ ] list anchors
|
* [ ] list anchors
|
||||||
* [ ] list filenames
|
* [ ] list filenames
|
||||||
* [ ] link following (to existing anchor)
|
* [ ] link following (to existing anchor)
|
||||||
|
* [ ] fallback to filename if anchor invalid / not found
|
||||||
* [ ] link creation (to existing note)
|
* [ ] link creation (to existing note)
|
||||||
* [ ] list existing
|
* [ ] list existing
|
||||||
* [ ] create link (md / wiki)
|
* [ ] create link (md / wiki)
|
||||||
* [ ] link switching (to another existing note)
|
* [ ] link switching (point to another existing note)
|
||||||
* [ ] note search (title / full-text)
|
* [ ] note search (title / full-text)
|
||||||
* [ ] jump to zettel (open existing anchor)
|
* [ ] jump to zettel (open existing anchor)
|
||||||
* [ ] select by anchor
|
* [ ] select by anchor
|
||||||
|
@ -32,13 +33,14 @@ next up:
|
||||||
* [x] zettel extension
|
* [x] zettel extension
|
||||||
* [x] link style (wiki/markdown)
|
* [x] link style (wiki/markdown)
|
||||||
* [ ] custom link style?
|
* [ ] custom link style?
|
||||||
* [ ] link detection/following (under word, next on line)
|
* [x] link detection/following (under word, next on line)
|
||||||
* [ ] recursive dir lookup for zettel
|
* [ ] recursive dir lookup for zettel
|
||||||
* [ ] zettel anchor regex
|
* [ ] zettel anchor regex
|
||||||
|
|
||||||
## TODO: nice-to-haves
|
## TODO: nice-to-haves
|
||||||
|
|
||||||
* [ ] refactor parsers (md/wiki) to be tables of functions/regex in options, so e.g. valid link detection can call `options.parser.isValidLink(link)` or transformation `options.parser.styleLink(anchor, text)`
|
* [ ] refactor parsers (md/wiki) to be tables of functions/regex in options, so e.g. valid link detection can call `options.parser.isValidLink(link)` or transformation `options.parser.styleLink(anchor, text)`
|
||||||
|
* [ ] enable custom parser supply
|
||||||
* [ ] completion engine (e.g. for `completion-nvim`, look in completion_buffers/completion-tags for reference)
|
* [ ] completion engine (e.g. for `completion-nvim`, look in completion_buffers/completion-tags for reference)
|
||||||
* [ ] zettel caching for big directories
|
* [ ] zettel caching for big directories
|
||||||
* [ ] backlinks (via rg for filename anchor?)
|
* [ ] backlinks (via rg for filename anchor?)
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
local A = {}
|
local A = {}
|
||||||
|
|
||||||
|
local o = require 'zettelkasten.options'
|
||||||
|
|
||||||
|
local parsers = {markdown = "%[.-%]%((.-)%)", wiki = "%[%[(.+)|?.-%]%]"}
|
||||||
|
|
||||||
-- Extracts a file name from a link and opens the corresponding file
|
-- Extracts a file name from a link and opens the corresponding file
|
||||||
-- in the current buffer.
|
-- in the current buffer.
|
||||||
-- Takes an optional input parameter
|
-- Takes an optional input parameter
|
||||||
|
@ -12,15 +16,24 @@ end
|
||||||
|
|
||||||
-- Gets the input at the current buffer cursor and opens it
|
-- Gets the input at the current buffer cursor and opens it
|
||||||
-- in the current buffer.
|
-- in the current buffer.
|
||||||
function A.open_selected()
|
-- Takes an optional style of link following to use,
|
||||||
-- TODO decide between currentword/restofline option
|
-- superseding the one set in options.
|
||||||
A.open(A.get_link_under_cursor())
|
function A.open_selected(style)
|
||||||
|
local style = style or o.zettel().link_following
|
||||||
|
if style == 'line' then
|
||||||
|
A.open(A.get_next_link_on_line())
|
||||||
|
elseif style == 'cursor' then
|
||||||
|
A.open(A.get_link_under_cursor())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Return only the link reference portion of a markdown/wiki style link
|
-- Return only the link reference portion of a markdown/wiki style link.
|
||||||
|
-- For example, for a markdown link [my text](my-link.md)
|
||||||
|
-- it would only return my-link.md
|
||||||
function A.extract_link(input)
|
function A.extract_link(input)
|
||||||
if not input then return end
|
if not input then return end
|
||||||
return input:match("%[%[(.+)|?.*%]%]") or input:match("%[.*%]%((.+)%)")
|
for _, parser in pairs(parsers) do return input:match(parser) end
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the word currently under cursor, the vim equivalent of yiW.
|
-- Returns the word currently under cursor, the vim equivalent of yiW.
|
||||||
|
@ -33,48 +46,10 @@ function A.get_link_under_cursor(small)
|
||||||
return word
|
return word
|
||||||
end
|
end
|
||||||
|
|
||||||
-- -- Returns the content of the line from the cursor onwards.
|
-- Returns the content of the line from the cursor onwards.
|
||||||
-- function A.get_next_link_on_line()
|
function A.get_next_link_on_line()
|
||||||
-- local line = vim.api.nvim_get_current_line()
|
local line = vim.api.nvim_get_current_line()
|
||||||
-- local linenr = vim.api.nvim_win_get_cursor(0)[1]
|
return line:sub(vim.api.nvim_win_get_cursor(0)[2])
|
||||||
-- print(line, linenr)
|
end
|
||||||
-- return ""
|
|
||||||
-- end
|
|
||||||
|
|
||||||
return {open = A.open, open_selected = A.open_selected}
|
return {open = A.open, open_selected = A.open_selected}
|
||||||
|
|
||||||
-- local function get_selection()
|
|
||||||
-- s_start = vim.fn.line("'<") - 1
|
|
||||||
-- s_end = vim.fn.line("'>")
|
|
||||||
-- return vim.api.nvim_buf_get_lines(0, s_start, s_end, true)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- -- UGLY HACKS ABOUND
|
|
||||||
-- function ZK.create_zettel()
|
|
||||||
-- -- get line and its number
|
|
||||||
-- local selection
|
|
||||||
-- local line = vim.api.nvim_get_current_line()
|
|
||||||
-- local linenr = vim.api.nvim_win_get_cursor(0)[1]
|
|
||||||
|
|
||||||
-- -- get words under cursor / selected
|
|
||||||
-- local mode = vim.api.nvim_get_mode()['mode']
|
|
||||||
-- if mode == "n" then
|
|
||||||
-- print(vim.fn.line("'<'") - 1)
|
|
||||||
-- selection = vim.fn.expand("<cWORD>")
|
|
||||||
-- -- NOT WORKING YET
|
|
||||||
-- elseif mode == "v" then
|
|
||||||
-- selection = get_selection()
|
|
||||||
-- else
|
|
||||||
-- return
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- -- get valid link
|
|
||||||
-- local link = l.create(nil, selection)
|
|
||||||
|
|
||||||
-- -- create new line with selection replaced in middle
|
|
||||||
-- local st, en = line:find(selection, 0, true)
|
|
||||||
-- local repl_line = line:sub(1, st - 1) .. link .. line:sub(en + 1)
|
|
||||||
|
|
||||||
-- -- replace existing line in favor of new one
|
|
||||||
-- vim.api.nvim_buf_set_lines(0, linenr - 1, linenr, true, {repl_line})
|
|
||||||
-- end
|
|
||||||
|
|
|
@ -11,22 +11,54 @@ describe("open", function()
|
||||||
assert.spy(vim.api.nvim_command).was_called_with(
|
assert.spy(vim.api.nvim_command).was_called_with(
|
||||||
"edit 1910271456_link-to-my-file.md")
|
"edit 1910271456_link-to-my-file.md")
|
||||||
end)
|
end)
|
||||||
it("should not fail when no input is available", function()
|
it("should do nothing when no link passed in", function()
|
||||||
vim.fn = {expand = function() end}
|
vim.fn = {expand = function() end}
|
||||||
assert.is_not_error(action.open)
|
assert.is_not_error(action.open)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("open_selected", function()
|
describe("open_selected", function()
|
||||||
it("should open the next link found if no argument passed in", function()
|
before_each(function()
|
||||||
vim.api = {nvim_command = mock(function() end)}
|
vim.api = {
|
||||||
|
nvim_command = mock(function() end),
|
||||||
|
nvim_get_current_line = function(sure)
|
||||||
|
return
|
||||||
|
"Hello, this is a line and [mylink](1910271456_link-to-my-file.md) whereas another [link](2030101158 another-link-now.md)"
|
||||||
|
end,
|
||||||
|
nvim_win_get_cursor = function(winnum) return {0, 0} end
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
it("should use the style passed to it, above the one set in options",
|
||||||
|
function()
|
||||||
|
vim.g['zettel_link_following'] = 'cursor'
|
||||||
|
|
||||||
|
vim.api.nvim_get_current_line = mock(vim.api.nvim_get_current_line)
|
||||||
|
action.open_selected("line")
|
||||||
|
|
||||||
|
assert.spy(vim.api.nvim_get_current_line).was_called()
|
||||||
|
end)
|
||||||
|
it("should open link under cursor if option set", function()
|
||||||
|
vim.g['zettel_link_following'] = 'cursor'
|
||||||
vim.fn = {
|
vim.fn = {
|
||||||
expand = function(sure)
|
expand = function(sure)
|
||||||
return "[" .. sure .. "](1910271456_link-to-my-file.md)"
|
return "[" .. sure .. "](1910271456_link-to-my-file.md)"
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
action.open_selected()
|
action.open_selected()
|
||||||
assert.spy(vim.api.nvim_command).was_called_with(
|
assert.spy(vim.api.nvim_command).was_called_with(
|
||||||
"edit 1910271456_link-to-my-file.md")
|
"edit 1910271456_link-to-my-file.md")
|
||||||
end)
|
end)
|
||||||
|
it("should open next link on line if option set", function()
|
||||||
|
vim.g['zettel_link_following'] = 'line'
|
||||||
|
action.open_selected()
|
||||||
|
assert.spy(vim.api.nvim_command).was_called_with(
|
||||||
|
"edit 1910271456_link-to-my-file.md")
|
||||||
|
end)
|
||||||
|
it("should ignore links before cursor position", function()
|
||||||
|
vim.g['zettel_link_following'] = 'line'
|
||||||
|
vim.api.nvim_win_get_cursor = function(winnum) return {0, 65} end
|
||||||
|
action.open_selected()
|
||||||
|
assert.spy(vim.api.nvim_command).was_called_with(
|
||||||
|
"edit 2030101158 another-link-now.md")
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in a new issue