zk-org / zk-nvim

Neovim extension for zk
https://github.com/zk-org/zk
GNU General Public License v3.0
503 stars 41 forks source link

Delete File via Telescope Picker #59

Closed thecontinium closed 2 years ago

thecontinium commented 2 years ago

Is it possible to add the capability to delete a selection of files in the telescope picker ?

cheers

mickael-menu commented 2 years ago

I'm not sure this should be part of the core commands, but you can implement it yourself using the zk.pick_notes API which will call your callback with the selected notes.

https://github.com/mickael-menu/zk-nvim#high-level-api

For an example on how to process the result, check out the implementation of zk.edit which is using pick_notes: https://github.com/mickael-menu/zk-nvim/blob/614ec31800174e0f6dc1aeaa528eafb9de1193a5/lua/zk.lua#L125-L134

Feel free to share your solution if you figure it out using zk.pick_notes, that could be helpful for others.

thecontinium commented 2 years ago

This does the trick. I couldn't get the indexing to be quiet; how can I do that ?

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

local function delete(options, picker_options)
  zk.pick_notes(options, picker_options, function(notes)
    if picker_options.multi_select == false then
      notes = { notes }
    end
    for _, note in ipairs(notes) do
      vim.fn.delete(note.absPath)
    end
    zk.index({})
  end)
end

commands.add("ZkDelete", function(options) delete(options, { title = "Zk Delete" }) end)
vim.api.nvim_set_keymap("n", "<LocalLeader>kd", "<cmd>ZkDelete {sort = {'modified'} }<CR>", { noremap = true })

Any idea on how to add a "Are you sure you want to delete y/n [n] ?" prompt ?

This is an alternative generic approach at the telescope setup level by assigning a key for delete but I'm not sure of the best way to get the indexing to run when we are deleting a file in a zk picker. The advantage of this is that it would work in all the zk pickers rather than introducing a special delete picker.

function myactions.delete_file(prompt_bufnr)
    local picker = require("telescope.actions.state").get_current_picker(prompt_bufnr)
    local entries = {}
    if #picker:get_multi_selection() > 0 then
        for _, entry in ipairs(picker:get_multi_selection()) do
            table.insert(entries, entry.path)
        end
    else
        table.insert(entries, require("telescope.actions.state").get_selected_entry().path)
    end

    for _, path in ipairs(entries) do
        -- vim.pretty_print(path)
        vim.fn.delete(path)
    end
end

and set the mapping in the setup something like this:

require("telescope").setup({
            mappings = {
                n = {
                    ["dd"] = myactions.delete_file,
                },
}
)
eric-hansen commented 2 years ago

Any idea on how to add a "Are you sure you want to delete y/n [n] ?" prompt ?

Couldn't you do vim.fn.input("...") before the if picker_options.multi_select == false then and if it's not a certain value exit out of the function?

mickael-menu commented 2 years ago

Thanks for sharing your solution!

I couldn't get the indexing to be quiet; how can I do that ?

It looks like we're missing an option for this here (PRs welcome! 😉):

https://github.com/mickael-menu/zk-nvim/blob/614ec31800174e0f6dc1aeaa528eafb9de1193a5/lua/zk.lua#L81-L87

In the meantime, you can call the lower level API directly with require(zk.api).index() as demonstrated above.

Any idea on how to add a "Are you sure you want to delete y/n [n] ?" prompt ?

The vim.fn.input solution mentioned by @eric-hansen is the only one I know without resorting to third-party plugins.

You could also use vim.ui.select with Yes and No options to need only to hit Enter.

This is an alternative generic approach at the telescope setup level by assigning a key for delete but I'm not sure of the best way to get the indexing to run when we are deleting a file in a zk picker.

Can't you run the zk.index() API right after the delete, like with the other solution?

thecontinium commented 2 years ago

Thanks for your advice.

Regarding the quiet option I think the problem is on the server not the lsp client.

See here https://github.com/mickael-menu/zk/blob/9c06068cce3aeb77723194601e307312b6bd5870/internal/adapter/lsp/cmd_index.go#L11

There is no decoding of “quiet” ?

-- The Continium

On 30 June 2022 at 06:56:49, Mickaël Menu @.**@.>) wrote:

Thanks for sharing your solution!

I couldn't get the indexing to be quiet; how can I do that ?

It looks like we're missing an option for this here (PRs welcome! 😉):

https://github.com/mickael-menu/zk-nvim/blob/614ec31800174e0f6dc1aeaa528eafb9de1193a5/lua/zk.lua#L81-L87

In the meantime, you can call the lower level API directly with require(zk.api).index() as demonstrated above.

Any idea on how to add a "Are you sure you want to delete y/n [n] ?" prompt ?

The vim.fn.input solution mentioned by @eric-hansenhttps://github.com/eric-hansen is the only one I know without resorting to third-party plugins.

You could also use vim.ui.select with Yes and No options to need only to hit Enter.

This is an alternative generic approach at the telescope setup level by assigning a key for delete but I'm not sure of the best way to get the indexing to run when we are deleting a file in a zk picker.

Can't you run the zk.index() API right after the delete, like with the other solution?

— Reply to this email directly, view it on GitHubhttps://github.com/mickael-menu/zk-nvim/issues/59#issuecomment-1170797813, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACHXEBU3FVSSJSNUWZDYHM3VRUZKDANCNFSM52FQXJ2A. You are receiving this because you authored the thread.Message ID: @.***>

mickael-menu commented 2 years ago

There is no decoding of “quiet” ?

Yes because the LSP command is quiet by default. It will return a JSON representation of the indexed notes ("stats"), that zk-nvim is printing in NeoVim here:

https://github.com/mickael-menu/zk-nvim/blob/614ec31800174e0f6dc1aeaa528eafb9de1193a5/lua/zk.lua#L85

The equivalent in the CLI is here: https://github.com/mickael-menu/zk/blob/68e6b70eaefdf8344065fcec39d5419dc80d6a02/internal/cli/cmd/index.go#L35-L37

mickael-menu commented 2 years ago

But more than a quiet option, I think what we should have in zk-nvim is just a callback that receive the stats object. Then the user can decide what to do with it (most likely ignore it). Showing the dump of stats is probably too technical for this API.

thecontinium commented 2 years ago

ok - thanks.

thecontinium commented 2 years ago

With this pull request the following which includes verification for delete and using the cb to indicate how many files were removed from the index


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

local function delete(options, picker_options, index_options, index_cb)
  zk.pick_notes(options, picker_options, function(notes)
    if picker_options.multi_select == false then
      notes = { notes }
    end
    local confo = string.format("Are you sure you want to delete these %s files [y/N)] ", #notes)
    if vim.fn.input(confo, "") == "y" then
      for _, note in ipairs(notes) do
        vim.fn.delete(note.absPath)
      end
      zk.index(index_options, index_cb)
    end
  end)
end

commands.add("ZkDelete", function(options) delete(options, { title = "Zk Delete" }, {}, function(stats) vim.notify(string.format("%s files removed from the index", vim.inspect(stats.removedCount))) end) end)
vim.api.nvim_set_keymap("n", "<LocalLeader>kd", "<cmd>ZkDelete {sort = {'modified'} }<CR>", { noremap = true })
thecontinium commented 2 years ago

Can't you run the zk.index() API right after the delete, like with the other solution?

Because the generic solution is for all pickers including non zk pickers I don't want to call index for all deletions on files that are not being managed by zk.

Can I use the path of the file to test if zk is managing the file or is there a better way ?

mickael-menu commented 2 years ago

Ha, I see. Calling zk.index on paths out of any notebook should be fast enough, you could also check that the extension is md.

We probably need a way to allow custom mappings in the telescope config. We should be able to customize per-picker using attach_mappings here https://github.com/mickael-menu/zk-nvim/blob/58fee43929e43eef6c9864c8b0c5450a45c7edad/lua/zk/pickers/telescope.lua#L71

thecontinium commented 2 years ago

Here is a version ( just using config ) that allows you to add custom key mappings only to a zk picker. It can be tidied up but could be generalised to map keys to any homegrown functions. In this case it adds a single key mapping "dz" which deletes and then indexes zk notes through a command ZkDeletableNotes

local function delete_zk_files(prompt_bufnr)
  local picker = require("telescope.actions.state").get_current_picker(prompt_bufnr)
  local entries = {}
  if #picker:get_multi_selection() > 0 then
    for _, entry in ipairs(picker:get_multi_selection()) do
      table.insert(entries, entry)
    end
  else
   table.insert(entries, require("telescope.actions.state").get_selected_entry().path)
  end
  local confo = string.format("Are you sure you want to delete these %s files [y/N)] ", #entries)
  if vim.fn.input(confo, "") == "y" then
    for _, path in ipairs(entries) do
      vim.fn.delete(path)
    end
    zk.index({}, function(stats) vim.notify(string.format("zk index reomved %s files from the index", vim.inspect(stats.removedCount))) end)
      require("telescope.actions").close(prompt_bufnr)
  end
end

commands.add("ZKDeletableNotes", function(options)
  zk.edit(options, {title = "ZK Deletable Notes ",
                    telescope = { attach_mappings = function(_, map)
                                                    local mappings = { n = { ["dz"] = delete_zk_files,}}
                                                    for mode, tbl in pairs(mappings) do
                                                      for key, action in pairs(tbl) do
                                                        map(mode, key, action)
                                                      end
                                                    end
                                                    return true
                                                    end }}) end)
mickael-menu commented 2 years ago

I didn't know you could customize the attach_mappings directly from the zk APIs, neat!

thecontinium commented 2 years ago

Closing this now. Cheers.