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

Focus on correct entry #104

Open
ZhiyuanLck opened this issue Feb 24, 2022 · 9 comments
Open

Focus on correct entry #104

ZhiyuanLck opened this issue Feb 24, 2022 · 9 comments
Labels
enhancement New feature or request

Comments

@ZhiyuanLck
Copy link
Contributor

Considering the following cases:

  1. When we go to the parent directory, the selection is reset to the first entry, can we provide an option to make it focus on the directory where we backwards?
  2. When a file is created, will it be better if we can focus on the new entry?
@ZhiyuanLck ZhiyuanLck added the enhancement New feature or request label Feb 24, 2022
@fdschmidt93
Copy link
Member

I'd generally be happy to enable these sorts of things, but it's very difficult to do so ergonomically with the async nature of pickers.

#78 (comment) elaborates what I mean as virtually the same problem arises.

Generally speaking, it's achievable right now, but you essentially need vim.defer_fn (or maybe it works with plenary.async, haven't managed with vim.schedule though)

The below works if set right below current_picker:refresh of fb_actions.create in lua/telescope/_extensions/file_browser/actions.lua.

    current_picker:register_completion_callback(function()
      local selection_index = find_entry(current_picker, file.filename)
      vim.defer_fn(function() current_picker:set_selection(current_picker:get_row(selection_index)) end, 10)
      local num_cb = #current_picker._completion_callbacks
      current_picker._completion_callbacks[num_cb] = nil
    end)

where find_entry iterates the entries and finds the index of the currently created one.

While the above function works, it feels like quite a callback rabbit hole. What I would like much more is if we could synchronize the picker refresh. That would allow for a lot of these things to become a breeze and combine it with a lot of other things as mentioned in the above referenced issue.

@fdschmidt93
Copy link
Member

Ok, I'm working a bit more on file browser today and finally have properly understood why we have issues here.

It's quite funny. In some sections, we maybe overcautiously reset the prompt as well. Unfortunately, this essentially causes the finder loop to be triggered twice (telescope too fast brr), which clears completion callbacks like above prematurely. Not sure whether that should be solved upstream.

cc @Conni2461 just for general awareness that resetting prompt in picker:refresh possibly inadvertently triggers finding loop twice, which adversely affects sort of hacky one-shot completion callbacks (picker:_on_complete). Not sure if it's a "bug" or practically behaving as intended. I can work around it for file browser by only releasing the completion callback on the second trigger.

@Conni2461
Copy link
Member

triggers finding loop twice

I've seen this behavior when working on refresh but could not figure out why, i'll open an issue and try to figure it out at some point :)

@matthewgrossman
Copy link

Do you have a recommendation for how to reproduce this behavior on the configuration side (as opposed to making the above modification to a fork)? Happy to help implement in this repo if you think it's still straightforward or feasible

regardless, another vote for this functionality. I'm using this plugin as a replacement for ranger within neovim, and I often find myself exploring file hierarchies by going up, realizing I went too far, then needing to go back down, etc. Having the selection after fb_actions.goto_parent_dir smartly place itself on the child_dir makes this process much better, especially in large parent directories.

@fdschmidt93
Copy link
Member

Just to align, you are referring to

When we go to the parent directory, the selection is reset to the first entry, can we provide an option to make it focus on the directory where we backwards?

Yes, I'd say this is now straightforward / feasible after fixing this upstream and happy to accept a PR for this.

We'd need an option essentially here

action_set.select:replace_if(function()
-- test whether selected entry is directory
local entry = action_state.get_selected_entry()
return entry and entry.Path:is_dir()
end, function()
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
local entry = action_state.get_selected_entry()
local path = vim.loop.fs_realpath(entry.path)
if finder.files and finder.collapse_dirs then
local upwards = path == Path:new(finder.path):parent():absolute()
while true do
local dirs = scan.scan_dir(path, { add_dirs = true, depth = 1, hidden = true })
if #dirs == 1 and vim.fn.isdirectory(dirs[1]) then
path = upwards and Path:new(path):parent():absolute() or dirs[1]
-- make sure it's upper bound (#dirs == 1 implicitly reflects lower bound)
if path == Path:new(path):parent():absolute() then
break
end
else
break
end
end
end
finder.files = true
finder.path = path
fb_utils.redraw_border_title(current_picker)
current_picker:refresh(finder, { reset_prompt = true, multi = current_picker._multi })
end)
return true
end,
} or _TelescopeFileBrowserConfig

that enables a selection callback pretty much like when a file is created, like here

fb_actions.create = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
local finder = current_picker.finder
local default = get_target_dir(finder) .. os_sep
vim.ui.input({ prompt = "Insert the file name: ", default = default, completion = "file" }, function(input)
vim.cmd [[ redraw ]] -- redraw to clear out vim.ui.prompt to avoid hit-enter prompt
local file = create(input, finder)
if file then
-- values from finder for values don't have trailing os sep for folders
local path = file:absolute()
path = file:is_dir() and path:sub(1, -2) or path
fb_utils.selection_callback(current_picker, path)
current_picker:refresh(finder, { reset_prompt = true, multi = current_picker._multi })
end
end)
end

The way this selection callback works conceptually:

  • Create file
  • Create finder callback that sets the telescope selection to the entry that matches the absolute path of the newly created file and releases callback afterwards
  • Releasing required as callback is always called as completion of a finder loop (eg triggered by initialization or completing loop after newly added character) invokes the callback, and we only want it upon initialization

PR very welcome :) I hope the above is sufficient guidance to get you started, let me know if you are interested to work on this and would need further guidance etc.

@matthewgrossman
Copy link

matthewgrossman commented Nov 7, 2022

Finally getting back to this, sorry for the delay 😬

I appreciate the detailed pointers, definitely helped. I got something working locally in my own branch in this PR (3-liner, super simple): #193

Some quick questions:

When you say

We'd need an option essentially here

you mean such that we can let users opt in/out of this behavior? or are you referring to an additional param of some sort?

Also, is the first action_set.select:replace_if code snippet you posted the preferable place because it'll generically handle selecting the right entry, rather than my solution special-casing goto_parent_dir?

Can take discussion to PR as well, if that's preferable

@louwers
Copy link

louwers commented Jan 1, 2023

After removing a file or directory, the focus jumps to the bottom for me.

Should I make a new issue out of this?

@fdschmidt93
Copy link
Member

Yes please so we can pin down the actual issue. I'll review the selection callbacks as part of tree feature + large RFC in #210 anyways and so would be good to know what to look out for.

@sohanemon
Copy link

any luck? its 2024-04-28

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

No branches or pull requests

6 participants