Move functions working on buffer text to own module
This commit is contained in:
parent
4e3d364d17
commit
2ff3a0b299
3 changed files with 94 additions and 125 deletions
|
@ -3,6 +3,7 @@ local A = {}
|
||||||
local o = require 'zettelkasten.options'
|
local o = require 'zettelkasten.options'
|
||||||
local l = require 'zettelkasten.link'
|
local l = require 'zettelkasten.link'
|
||||||
local f = require 'zettelkasten.files'
|
local f = require 'zettelkasten.files'
|
||||||
|
local t = require 'zettelkasten.text'
|
||||||
|
|
||||||
-- Opens the link passed in in the editor's current buffer.
|
-- Opens the link passed in in the editor's current buffer.
|
||||||
-- Requires a link object passed in.
|
-- Requires a link object passed in.
|
||||||
|
@ -25,145 +26,26 @@ function A.open_selected(style)
|
||||||
|
|
||||||
local ln
|
local ln
|
||||||
if st == 'line' then
|
if st == 'line' then
|
||||||
ln = A.get_next_link_on_line(links, curpos)
|
ln = t.get_next_link_on_line(links, curpos)
|
||||||
elseif st == 'cursor' then
|
elseif st == 'cursor' then
|
||||||
ln = A.get_link_under_cursor(links, curpos)
|
ln = t.get_link_under_cursor(links, curpos)
|
||||||
end
|
end
|
||||||
|
|
||||||
A.open(ln)
|
A.open(ln)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns visually selected text and cursor column where selection starts.
|
|
||||||
-- Works with selections over multiple lines, but will only return the
|
|
||||||
-- starting line, as well as the starting line's text.
|
|
||||||
local function get_current_selection()
|
|
||||||
local line, start_col, end_col = vim.fn.getpos("'<")[2],
|
|
||||||
vim.fn.getpos("'<")[3],
|
|
||||||
vim.fn.getpos("'>")[3]
|
|
||||||
local selection = vim.fn.getline(line, line)[1]:sub(start_col, end_col)
|
|
||||||
return selection, start_col
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns word currently under cursor and cursor column where
|
|
||||||
-- the word begins.
|
|
||||||
-- If big argument resolves to true, it will get the whitespace
|
|
||||||
-- delimited word, otherwise the vim specified wordboundary word.
|
|
||||||
local function get_current_word(big)
|
|
||||||
local pattern = [[\k]]
|
|
||||||
if not big then pattern = [[\S]] end
|
|
||||||
|
|
||||||
local cur_col = vim.api.nvim_win_get_cursor(0)[2]
|
|
||||||
local line = vim.api.nvim_get_current_line()
|
|
||||||
|
|
||||||
local word_before_cur = vim.fn.matchstrpos(line:sub(1, cur_col + 1),
|
|
||||||
pattern .. "*$")
|
|
||||||
local word_start_col = word_before_cur[2] + 1
|
|
||||||
word_before_cur = word_before_cur[1]
|
|
||||||
|
|
||||||
local word_after_cur = vim.fn.matchstr(line:sub(cur_col + 1),
|
|
||||||
"^" .. pattern .. "*"):sub(2)
|
|
||||||
|
|
||||||
return word_before_cur .. word_after_cur, word_start_col
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Sanitizes the string before replacement, taking care of escaping any
|
|
||||||
-- characters that lua uses to signify patterns.
|
|
||||||
local function replace(str, patt, repl, n)
|
|
||||||
patt = string.gsub(patt, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1")
|
|
||||||
repl = string.gsub(repl, "[%%]", "%%%%")
|
|
||||||
return string.gsub(str, patt, repl, n)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Replaces the input text on the current line with a zettel link.
|
|
||||||
-- Takes an optional initial column on which the text to be replaced starts,
|
|
||||||
-- which can prevent falsely substituting the wrong text fragment if an
|
|
||||||
-- identical one exists earlier on the line.
|
|
||||||
local function replace_text_with_link(text, start_col)
|
|
||||||
local link = l.new(text)
|
|
||||||
|
|
||||||
local line_full = vim.api.nvim_get_current_line()
|
|
||||||
local line_edited
|
|
||||||
if start_col then
|
|
||||||
line_edited = line_full:sub(1, start_col - 1) ..
|
|
||||||
replace(line_full:sub(start_col), text, link, 1)
|
|
||||||
else
|
|
||||||
line_edited = replace(line_full, text, link, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
return line_edited
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Replaces the current text context with a link to a new zettel.
|
-- Replaces the current text context with a link to a new zettel.
|
||||||
-- The current context is the visual selection (if called from visual mode)
|
-- The current context is the visual selection (if called from visual mode)
|
||||||
-- or the (big) word under the cursor if called from any other mode.
|
-- or the (big) word under the cursor if called from any other mode.
|
||||||
function A.link(visual)
|
function A.link(visual)
|
||||||
local selection, start_col
|
local selection, start_col
|
||||||
if visual or vim.api.nvim_get_mode()['mode'] == "v" then
|
if visual or vim.api.nvim_get_mode()['mode'] == "v" then
|
||||||
selection, start_col = get_current_selection()
|
selection, start_col = t.get_current_selection()
|
||||||
else
|
else
|
||||||
selection, start_col = get_current_word()
|
selection, start_col = t.get_current_word()
|
||||||
end
|
end
|
||||||
vim.api.nvim_set_current_line(replace_text_with_link(selection, start_col))
|
vim.api.nvim_set_current_line(t.replace_text(selection, l.new(selection),
|
||||||
end
|
start_col))
|
||||||
|
|
||||||
-- Returns the link currently under cursor, roughly the vim equivalent of yiW.
|
|
||||||
-- Works for links containing spaces in their text or reference link.
|
|
||||||
function A.get_link_under_cursor(links, curpos)
|
|
||||||
for _, link in pairs(links) do
|
|
||||||
if link.startpos <= curpos + 1 and link.endpos > curpos then
|
|
||||||
return link
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the next link of the current line from the cursor onwards.
|
|
||||||
function A.get_next_link_on_line(links, curpos)
|
|
||||||
local nearestpos = math.huge
|
|
||||||
local nearestlink
|
|
||||||
for _, ln in pairs(links) do
|
|
||||||
if ln.endpos > curpos and ln.endpos < nearestpos then
|
|
||||||
nearestpos = ln.endpos
|
|
||||||
nearestlink = ln
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nearestlink
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return {open = A.open, open_selected = A.open_selected, link = A.link}
|
return {open = A.open, open_selected = A.open_selected, link = A.link}
|
||||||
|
|
||||||
--- 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
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ local anchor_defaults = {
|
||||||
-- TODO zettel_root = vim.g["zettel_root"] or vim.b["zettel_root"] or "~/documents/notes",
|
-- TODO zettel_root = vim.g["zettel_root"] or vim.b["zettel_root"] or "~/documents/notes",
|
||||||
-- TODO zettel_anchor_pattern = regex? -> needs custom creation function in `create_anchor`
|
-- TODO zettel_anchor_pattern = regex? -> needs custom creation function in `create_anchor`
|
||||||
|
|
||||||
|
-- TODO refer to option name in error as well if something is not set correctly
|
||||||
local function must_contain(set, value, name)
|
local function must_contain(set, value, name)
|
||||||
if type(set) ~= "table" then return false end
|
if type(set) ~= "table" then return false end
|
||||||
if not set[value] then
|
if not set[value] then
|
||||||
|
|
86
lua/zettelkasten/text.lua
Normal file
86
lua/zettelkasten/text.lua
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
local T = {}
|
||||||
|
|
||||||
|
-- Returns visually selected text and cursor column where selection starts.
|
||||||
|
-- Works with selections over multiple lines, but will only return the
|
||||||
|
-- starting line, as well as the starting line's text.
|
||||||
|
function T.get_current_selection()
|
||||||
|
local line, start_col, end_col = vim.fn.getpos("'<")[2],
|
||||||
|
vim.fn.getpos("'<")[3],
|
||||||
|
vim.fn.getpos("'>")[3]
|
||||||
|
local selection = vim.fn.getline(line, line)[1]:sub(start_col, end_col)
|
||||||
|
return selection, start_col
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns word currently under cursor and cursor column where
|
||||||
|
-- the word begins.
|
||||||
|
-- If big argument resolves to true, it will get the whitespace
|
||||||
|
-- delimited word, otherwise the vim specified wordboundary word.
|
||||||
|
function T.get_current_word(big)
|
||||||
|
local pattern = [[\k]]
|
||||||
|
if not big then
|
||||||
|
pattern = [[\S]]
|
||||||
|
end
|
||||||
|
|
||||||
|
local cur_col = vim.api.nvim_win_get_cursor(0)[2]
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
|
||||||
|
local word_before_cur = vim.fn.matchstrpos(line:sub(1, cur_col + 1), pattern .. "*$")
|
||||||
|
local word_start_col = word_before_cur[2] + 1
|
||||||
|
word_before_cur = word_before_cur[1]
|
||||||
|
|
||||||
|
local word_after_cur = vim.fn.matchstr(line:sub(cur_col + 1), "^" .. pattern .."*"):sub(2)
|
||||||
|
|
||||||
|
return word_before_cur .. word_after_cur, word_start_col
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the link currently under cursor, roughly the vim equivalent of yiW.
|
||||||
|
-- Works for links containing spaces in their text or reference link.
|
||||||
|
function T.get_link_under_cursor(links, curpos)
|
||||||
|
for _, link in pairs(links) do
|
||||||
|
if link.startpos <= curpos + 1 and link.endpos > curpos then
|
||||||
|
return link
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the next link of the current line from the cursor onwards.
|
||||||
|
function T.get_next_link_on_line(links, curpos)
|
||||||
|
local nearestpos = math.huge
|
||||||
|
local nearestlink
|
||||||
|
for _, link in pairs(links) do
|
||||||
|
if link.endpos > curpos and link.endpos < nearestpos then
|
||||||
|
nearestpos = link.endpos
|
||||||
|
nearestlink = link
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nearestlink
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sanitizes the string before replacement, taking care of escaping any
|
||||||
|
-- characters that lua uses to signify patterns.
|
||||||
|
local function replace(str, patt, repl, n)
|
||||||
|
patt = string.gsub(patt, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1")
|
||||||
|
repl = string.gsub(repl, "[%%]", "%%%%")
|
||||||
|
return string.gsub(str, patt, repl, n)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Replaces the input text on the current line with new text.
|
||||||
|
-- Takes an optional initial column on which the text to be replaced starts,
|
||||||
|
-- which can prevent falsely substituting the wrong text fragment if an
|
||||||
|
-- identical one exists earlier on the line. (E.g. I want to replace the
|
||||||
|
-- second 'test' in 'test test 1 2 3').
|
||||||
|
function T.replace_text(text, new_text, start_col)
|
||||||
|
local line_full = vim.api.nvim_get_current_line()
|
||||||
|
local line_edited
|
||||||
|
if start_col then
|
||||||
|
line_edited = line_full:sub(1, start_col - 1) ..
|
||||||
|
replace(line_full:sub(start_col), text, new_text, 1)
|
||||||
|
else
|
||||||
|
line_edited = replace(line_full, text, new_text, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
return line_edited
|
||||||
|
end
|
||||||
|
|
||||||
|
return T
|
Loading…
Reference in a new issue