Code Monkey home page Code Monkey logo

Comments (12)

j-hui avatar j-hui commented on August 24, 2024 8

not stale, would still love to have this feature!

from zk-nvim.

nathanbraun avatar nathanbraun commented on August 24, 2024 1

I have [[ mapped to open up the file picker, where I can pick a note. When I do a link is inserted with the note title as text. See code below for this.

Note: what I (and @j-hui) would like is this same functionality, but where I can highlight some text, press [[ and have it open up the picker and insert a link where the text of the link is what was visually selected.

Code for mapping [[ in insert mode to link picker. In my config, which is in lua:

local opts = { noremap = true, silent = true}
local keymap = vim.api.nvim_buf_set_keymap

local zk = require("zk")
local commands = require("zk.commands")

local function yankName(options, picker_options)
  zk.pick_notes(options, picker_options, function(notes)
    local pos = vim.api.nvim_win_get_cursor(0)[2]
    local line = vim.api.nvim_get_current_line()

    if picker_options.multi_select == false then
      notes = { notes }
    end
    for _, note in ipairs(notes) do
      local nline = line:sub(0, pos) .. "[" .. note.title  .. "]" .. "(" .. note.path:sub(1,-6) .. ")" .. line:sub(pos + 1)
      vim.api.nvim_set_current_line(nline)
    end
  end)
end
commands.add("ZkYankName", function(options) yankName(options, { title = "Zk Yank" }) end)

keymap(0, "i", "[[", "<Cmd>ZkYankName<CR>", opts)

from zk-nvim.

nathanbraun avatar nathanbraun commented on August 24, 2024 1

I went back and played with this some more. I was able to come up with some code that does what I wanted, e.g. let's you highlight some text and press [[ to turn it into a link. I'm sure there's some unnecessary duplication etc so feel free to suggest tweaks.

local opts = { noremap = true, silent = true}
local keymap = vim.api.nvim_buf_set_keymap

local zk = require("zk")
local commands = require("zk.commands")

function tbl_length(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end   

function get_visual_selection()
    -- this will exit visual mode
    -- use 'gv' to reselect the text
    local _, csrow, cscol, cerow, cecol
    local mode = vim.fn.mode()
    if mode == 'v' or mode == 'V' or mode == '�' then
      -- if we are in visual mode use the live position
      _, csrow, cscol, _ = unpack(vim.fn.getpos("."))
      _, cerow, cecol, _ = unpack(vim.fn.getpos("v"))
      if mode == 'V' then
        -- visual line doesn't provide columns
        cscol, cecol = 0, 999
      end
      -- exit visual mode
      vim.api.nvim_feedkeys(
        vim.api.nvim_replace_termcodes("<Esc>",
          true, false, true), 'n', true)
    else
      -- otherwise, use the last known visual position
      _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
      _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
    end
    -- swap vars if needed
    if cerow < csrow then csrow, cerow = cerow, csrow end
    if cecol < cscol then cscol, cecol = cecol, cscol end
    local lines = vim.fn.getline(csrow, cerow)
    -- local n = cerow-csrow+1
    local n = tbl_length(lines)
    if n <= 0 then return '' end
    lines[n] = string.sub(lines[n], 1, cecol)
    lines[1] = string.sub(lines[1], cscol)
    return table.concat(lines, "\n")
end

local function yankName(options, picker_options)
  zk.pick_notes(options, picker_options, function(notes)
    local pos = vim.api.nvim_win_get_cursor(0)[2]
    local line = vim.api.nvim_get_current_line()

    if picker_options.multi_select == false then
      notes = { notes }
    end
    for _, note in ipairs(notes) do
      local nline = line:sub(0, pos) .. "[" .. note.title  .. "]" .. "(" .. note.path:sub(1,-6) .. ")" .. line:sub(pos + 1)
      vim.api.nvim_set_current_line(nline)
    end
  end)
end


local function yankNameReplace(options, picker_options)
  local selected = get_visual_selection()
  zk.pick_notes(options, picker_options, function(notes)
    local pos = vim.api.nvim_win_get_cursor(0)[2]
    local line = vim.api.nvim_get_current_line()

    if picker_options.multi_select == false then
      notes = { notes }
    end
    for _, note in ipairs(notes) do
      local nline = line:sub(0, pos - #selected) .. "[" .. selected  .. "]" .. "(" .. note.path:sub(1,-6) .. ")" .. line:sub(pos + 1)
      vim.api.nvim_set_current_line(nline)
    end
  end)
end

commands.add("ZkYankName", function(options) yankName(options, { title = "Zk Yank" }) end)
commands.add("ZkYankNameReplace", function(options) yankNameReplace(options, { title = "Zk Yank" }) end)

keymap(0, "i", "[[", "<Cmd>ZkYankName<CR>", opts)
keymap(0, "v", "[[", "<Cmd>ZkYankNameReplace<CR>", opts)

It's not perfect (i.e. throws an error on a multi line selection) but works well enough for me for now.

from zk-nvim.

mickael-menu avatar mickael-menu commented on August 24, 2024

I agree that this could be a very interesting feature to have. As well as generating a new link after picking a note, which might be more convenient than basic auto-completion.

Most of the pieces are there, it would be a matter of sticking them together:

  • We have the note pickers already in zk-nvim.
  • We have the logic for handling a visual selection and replacing its content.
  • You can generate a link according to the user configuration with:
    $ zk list --working-dir subdir --format "{{format-link path 'Custom title'}}" `pwd`/config-lsp.md
    [Custom title](../config-lsp)

The last step might need some extra capabilities in zk, as the zk.list LSP command doesn't take a format parameter, as it returns a JSON dictionary. Maybe adding it and put the formatted result in the JSON dictionary would make sense here.

from zk-nvim.

github-actions avatar github-actions commented on August 24, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs in the next 5 days.

from zk-nvim.

nathanbraun avatar nathanbraun commented on August 24, 2024

I'd like this same feature, except I don't think the picker should start with "a topic" prefilled, as it's easy to insert a link right now with its current title. Seems like you'd want to use this more in cases where the text you're highlighting is a bit different from the note title you're looking for.

from zk-nvim.

dbatten5 avatar dbatten5 commented on August 24, 2024

Hey @nathanbraun what do you mean by "it's easy to insert a link right now"? Is there a command for that?

from zk-nvim.

dbatten5 avatar dbatten5 commented on August 24, 2024

Oh amazing, thanks @nathanbraun that's a great addition. One tiny issue, do you have that when the file picker is opened (fzf on my system), the focus remains on the text buffer, it doesn't move to the file picker? If I the cursor to a different window with eg. <c-j> then the focus moves to the file picker

from zk-nvim.

nathanbraun avatar nathanbraun commented on August 24, 2024

I use telescope and haven't run across that issue. Maybe try that? It's really quite good; no complaints at all.

from zk-nvim.

dbatten5 avatar dbatten5 commented on August 24, 2024

Ah great, maybe I'll try that then. Have you also experienced an issue whereby the link that gets inserted from the above code is the wrong link? The title is always right but sometimes the link is for a different note. Seems to happen intermittently and I can't work out why

from zk-nvim.

nathanbraun avatar nathanbraun commented on August 24, 2024

No but if I had to guess I bet it's something related to link structure, I'm doing it pretty manually, i.e. in this line:

 local nline = line:sub(0, pos) .. "[" .. note.title  .. "]" .. "(" .. note.path:sub(1,-6) .. ")" .. line:sub(pos + 1)

Probably wouldn't work for notes that aren't 4 character strings (e.g. all my notes are like fvmg.wiki or tzvs.wiki etc). I'm sure there's some way to make it more flexible.

Edit: I just tested this with some differently named notes, and it seems to work OK, so not sure what'd cause it, but I still bet it's something related to that -- maybe different file extensions?

from zk-nvim.

dbatten5 avatar dbatten5 commented on August 24, 2024

Ah of course, silly me. My files are named xxx.md so just needed to tweak that substring method to account for that, all working well now thanks

from zk-nvim.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.