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

FR: Allow ability to update existing named instances with prefills #165

Closed
choovick opened this issue Jul 27, 2024 · 10 comments
Closed

FR: Allow ability to update existing named instances with prefills #165

choovick opened this issue Jul 27, 2024 · 10 comments

Comments

@choovick
Copy link

Maybe pushing it but here it goes.

Use case: I would like to have a persistent single instance of grug-far, but I would like to change scope of the search from nvim-tree re-opening or re-triggering it updating prefills

Example:

vim.keymap.set("n", "z", function()
	local node = lib.get_node_at_cursor()
	if node then
		-- get directory of current file if it's a file
		local path
		if node.type == "directory" then
			-- Keep the full path for directories
			path = node.absolute_path
		else
			-- Get the directory of the file
			path = vim.fn.fnamemodify(node.absolute_path, ":h")
		end

		-- open grug-far with the path
		require("grug-far").grug_far({
			prefills = {
				search = "",
				replacement = "",
				filesFilter = "",
				flags = "",
				paths = path,
			},
			instanceName = "far",
			staticTitle = "Find and Replace",
		})
	end
end, opts("Search in directory"))

Current behaviour:
on grug_far: A grug-far instance with instanceName="far" already exists!
on trigger: Just triggers, but prefills are not updated

Desired:
on grug_far: buffer with instance name located, non empty prefills updated (this is basically a focus option as well)
on trigger: tiggers, with prefills updated

@MagicDuck
Copy link
Owner

on grug_far: A grug-far instance with instanceName="far" already exists!

i am guessing if we kill the instance with that name and recreate it, that would achieve the desired effect.
I need to do some thinking if we need separate api like instance_exists and close_instance or not.

on trigger: Just triggers, but prefills are not updated

By trigger I assume you mean toggle_instance call, correct?

@choovick
Copy link
Author

choovick commented Jul 29, 2024

i am guessing if we kill the instance with that name and recreate it, that would achieve the desired effect.
I need to do some thinking if we need separate api like instance_exists and close_instance or not.

Yep, killing and re-creating will work, should you will loose other prefills, but thats ok for my use case.

on trigger: Just triggers, but prefills are not updated

Correct toggle_instance, should be cool if that supports prefills updates.

toggle_instance is great, but options like focus_instance, close_instance, update_instance would be really cool as well.

@MagicDuck
Copy link
Owner

MagicDuck commented Jul 30, 2024

@choovick FYI, still needs unit tests, but I've added some API in #172
I have leant more in the direction of adding specific functions that do simple things as opposed to making the existing ones more complex since that tends to be harder to deal with long term. Here's an excerpt from the help:

require('grug-far').has_instance({instanceName})               *grug-far.has_instance()*
        Checks if grug-far instance with given name exists

        Parameters: ~
            {instanceName}(string) 
	
	Return:
	    {exists}(boolean) 

require('grug-far').is_instance_open({instanceName})           *grug-far.is_instance_open()*
        Checks if grug-far instance with given name is open.

        Parameters: ~
            {instanceName}(string) 
	
	Return:
	    {is_open}(boolean) 

require('grug-far').close_instance({instanceName})           *grug-far.close_instance()*
        Closes (kills) grug-far instance with given name.

        Parameters: ~
            {instanceName}(string) 

require('grug-far').open_instance({instanceName})           *grug-far.open_instance()*
        Opens grug-far instance with given name if window is closed.
	Otherwise focuses the window.

        Parameters: ~
            {instanceName}(string) 

require('grug-far').update_instance_prefills({instanceName}, {prefills}, {clearOld})
                                                  *grug-far.update_instance_prefills()*
        Updates grug-far instance with given input prefill.
	If clearOld=true is given, the old input values are ignored.

        Parameters: ~
            {instanceName}(string) 
            {prefills}(PrefillsTableOverride) table 
	       {search=, replacement=, filesFilter=, flags=, paths=}
            {clearOld}(boolean) if given, old input values are ignored

I did a quick test similar to what you have where each re-trigger increases a count that gets filled in and it seems to work:

      local count = 1
      vim.keymap.set('n', '<leader>so', function()
        local prefills = { search = 'something ' .. count }
        if not grugFar.has_instance('far') then
          grugFar.grug_far({
            instanceName = 'far',
            prefills = prefills,
          })
        else
          grugFar.open_instance('far')
          grugFar.update_instance_prefills('far', prefills, true)
        end

        count = count + 1
    end)

You can try the branch if you have time and let me know if you find any issue 😄 . I'll try to get to the tests soon...

@choovick
Copy link
Author

api looks good, i'll play around with it now and will report.

@choovick
Copy link
Author

Recording.at.2024-07-30.00.23.40.mp4
vim.keymap.set("n", "z", function()
        local node = lib.get_node_at_cursor()
        local grugFar = require("grug-far")
        if node then
          -- get directory of current file if it's a file
          local path
          if node.type == "directory" then
            -- Keep the full path for directories
            path = node.absolute_path
          else
            -- Get the directory of the file
            path = vim.fn.fnamemodify(node.absolute_path, ":h")
          end

          local prefills = {
            paths = path,
          }

          if not grugFar.has_instance("tree") then
            grugFar.grug_far({
              instanceName = "tree",
              prefills = prefills,
              staticTitle = "Find and Replace from Tree",
            })
          else
            grugFar.open_instance("tree")
            -- updating the prefills without clearing the search
            grugFar.update_instance_prefills("tree", prefills, false)
          end
        end
      end, opts("Search in directory"))

works like a charm!

You need to slow down btw. Its not acceptable to have a repo with all issues addressed.

@MagicDuck
Copy link
Owner

great! Thanks for trying it out!
Yeah, it's my first open source project and am also a bit OCD, haha. It's funny cause like a couple of months ago I was saying to myself that this project was pretty much complete and there was nothing more that could be added to it. I am always amazed how people find ways to use it. If it had only been me using it, it would have long stopped evolving 😆 .

@MagicDuck
Copy link
Owner

it's merged now 😄 .
Just FYI that I've also updated grug_far() and with_visual_selection() to return an automatically generated instanceName if one is not given (something like __grug_far_instance_<count>) as that can be preferable in some situations where you just want an unique instance and don't want to bother with the name.
So the example above could be rewritten as:

      local count = 1
      local gfInstance
      vim.keymap.set('n', '<leader>so', function()
        local prefills = { search = 'something ' .. count }
        if not grugFar.has_instance(gfInstance) then
          gfInstance = grugFar.grug_far({ prefills = prefills })
        else
          grugFar.open_instance(gfInstance)
          grugFar.update_instance_prefills(gfInstance, prefills, true)
        end

        count = count + 1
      end)

Anyways, just one small request if you get a chance, could you create a PR to add a prettified example of your more advanced usage to the Cookbook section of the README.md?

@MagicDuck
Copy link
Owner

MagicDuck commented Jul 31, 2024

@choovick btw, one last note, if you want to support paths with spaces in their names you need to do this in your code snippet above:

path:sub(“ “, “\\ “)

@choovick
Copy link
Author

@choovick btw, one last note, if you want to support paths with spaces in their names you need to do this in your code snippet above:

path:sub(“ “, “\\ “)

Yep, found that out pretty quickly! I will make PR for the README.md with my use case

@MagicDuck
Copy link
Owner

MagicDuck commented Jul 31, 2024

awesome, thanks! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants