Skip to content
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

Add support for 'zk.link' and some example linking commands #97

Merged
merged 5 commits into from
Feb 6, 2023
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ Try out different [commands](#built-in-commands) such as `:ZkNotes` or `:ZkNew`,
:ZkLinks [{options}]
```

```vim
" Inserts a link at the cursor location or around the selected text.
" params
" (optional) additional options, see https://github.com/mickael-menu/zk/blob/main/docs/editors-integration.md#zklist
" One additional option is `matchSelected` (boolean) which is only applicable to inserting a link around selected text. If `true`, the note picker will search for notes similar to the selected text. Otherwise, the note picker will load all notes to filter through.
" e.g. :'<'>ZkInsertLinkAtSelection {matchSelected = true}
:ZkInsertLink
:'<,'>ZkInsertLinkAtSelection [{options}]
```

```vim
" Opens a notes picker, filters for notes that match the text in the last visual selection
" params
Expand Down
12 changes: 12 additions & 0 deletions lua/zk/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ function M.new(path, options, cb)
execute_command("new", path, options, cb)
end

---@param target string path to note you want to link to
---@param location table LSP location at current caret
---@param path? string path to explicitly specify the notebook
---@param options? table Extra options; table in form {title: string}
---@param cb? function callback function
---@see https://github.com/mickael-menu/zk/blob/main/docs/editors-integration.md#zklink
function M.link(target, location, path, options, cb)
options = vim.tbl_extend("force", { path = target, location = location }, options or {})

execute_command("link", path, options, cb)
end

---@param path? string path to explicitly specify the notebook
---@param options table additional options
---@param cb function callback function
Expand Down
36 changes: 36 additions & 0 deletions lua/zk/commands/builtin.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local zk = require("zk")
local api = require("zk.api")
local util = require("zk.util")
local commands = require("zk.commands")

Expand Down Expand Up @@ -70,6 +71,41 @@ commands.add("ZkLinks", function(options)
zk.edit(options, { title = "Zk Links" })
end)

local function insert_link(selected, opts)
opts = vim.tbl_extend("force", {}, opts or {})

local location = util.get_lsp_location_from_selection()
local selected_text = util.get_text_in_range(util.get_selected_range())

if not selected then
location = util.get_lsp_location_from_caret()
else
if opts['matchSelected'] then
opts = vim.tbl_extend("force", { match = { selected_text } }, opts or {})
end
end

zk.pick_notes(opts, { multi_select = false }, function(note)
assert(note ~= nil, "Picker failed before link insertion: note is nil")

local link_opts = {}

if selected and selected_text ~= nil then
link_opts.title = selected_text
end

api.link(note.path, location, nil, link_opts, function(err, res)
if not res then
error(err)
end
end)
end)
end

commands.add('ZkInsertLink', function(opts) insert_link(false, opts) end, { title = 'Insert Zk link' })
commands.add('ZkInsertLinkAtSelection', function(opts) insert_link(true, opts) end,
{ title = 'Insert Zk link', needs_selection = true })

commands.add("ZkMatch", function(options)
local selected_text = util.get_text_in_range(util.get_selected_range())
assert(selected_text ~= nil, "No selected text")
Expand Down
29 changes: 26 additions & 3 deletions lua/zk/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,45 @@ function M.get_lsp_location_from_selection()
}
end

---Fix to correct cursor location
Copy link
Member

Choose a reason for hiding this comment

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

The nvim cursor is (1,0)-indexed, so lines start at 1. Might be what's causing the issue you noticed.

--
---When working on link insertion, it was discovered that there may be
---an off-by-one error for single point locations in glsp. This function
---corrects that error.
---@param location table An LSP location object representing a single cell
---@return table The LSP location corrected one row up and one column right
---@internal
local function fix_cursor_location(location)
-- Cursor LSP position is a little weird.
-- It inserts one line down. Seems like an off by one error somewhere
local pos = location['range']['start']

pos['line'] = pos['line'] - 1
pos['character'] = pos['character'] + 1

location['range']['start'] = pos
location['range']['end'] = pos

return location
end


---Makes an LSP location object from the caret position in the current buffer.
--
---@return table LSP location object
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#location
function M.get_lsp_location_from_caret()
local params = vim.lsp.util.make_given_range_params()

local row,col = unpack(vim.api.nvim_win_get_cursor(0))
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
local position = { line = row, character = col }
return {
return fix_cursor_location({
uri = params.textDocument.uri,
range = {
start = position,
["end"] = position
}
}
})
end

---Gets the text in the given range of the current buffer.
Expand Down