nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.
MIT License
16.01k stars 838 forks source link

How to move up & down an entry inside Telescope? #3365

Open wojciech-kulik opened 3 days ago

wojciech-kulik commented 3 days ago

Description

(I tried reaching out on Gitter first, but it seems like it's abandoned)

I need to add shortcuts to move telescope results up & down. However, I'm struggling with glitches, because replacing results moves the selection to the top, so the list jumps back & forth. Setting selected item without a small delay doesn't work. :( Is there any other solution?

Neovim version

NVIM v0.11.0-dev-1161+g6ef80eb42c
Build type: RelWithDebInfo
LuaJIT 2.1.1731601260

Operating system and version

macOS 15.1

Telescope version / branch / rev

main

checkhealth telescope

Checking for required plugins ~
- OK plenary installed.
- OK nvim-treesitter installed.

Checking external dependencies ~
- OK rg: found ripgrep 14.1.1
- OK fd: found fd 10.2.0

===== Installed extensions ===== ~

Telescope Extension: `fzf` ~
- OK lib working as expected
- OK file_sorter correctly configured
- OK generic_sorter correctly configured

Steps to reproduce

local telescopeFinders = require("telescope.finders")
local telescopePickers = require("telescope.pickers")
local telescopeConfig = require("telescope.config").values
local actionState = require("telescope.actions.state")
local activePicker = nil

local function swap_entries(entries, index1, index2)
  local tmp = entries[index1]
  entries[index1] = entries[index2]
  entries[index2] = tmp
end

local function show()
  local entries = { "a", "b", "c", "d", "e", "f", "g" }

  activePicker = telescopePickers.new(require("telescope.themes").get_dropdown({}), {
    prompt_title = "SMTH",
    finder = telescopeFinders.new_table({ results = entries }),
    sorter = telescopeConfig.generic_sorter(),
    file_ignore_patterns = {},
    attach_mappings = function(prompt_bufnr, _)
      vim.keymap.set({ "n", "i" }, "<M-y>", function()
        local currentEntry = actionState.get_selected_entry()
        if currentEntry then
          local index = currentEntry.index
          if index == 1 then
            return
          end

          swap_entries(entries, index, index - 1)

          if activePicker then
            activePicker:refresh(
              telescopeFinders.new_table({ results = entries }),
              { new_prefix = telescopeConfig.prompt_prefix }
            )
            activePicker:set_selection(index - 2)
          end
        end
      end, { buffer = prompt_bufnr })

      return true
    end,
  })

  activePicker:find()
end

show()

Expected behavior

The shortcut should move the item up without scrolling and jumping to the top.

Actual behavior

It seems like set_selection doesn't work directly after refresh. Is there any other way to move up & down selected entry without glitches and with keeping the selection on the moved entry?

Minimal config

return {
  "nvim-telescope/telescope.nvim",
  dependencies = {
    "nvim-lua/plenary.nvim",
    "nvim-telescope/telescope-ui-select.nvim",
    { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
  },
  event = "VeryLazy",
  config = function()
    local telescope = require("telescope")

    telescope.setup({
      extensions = {
        ["ui-select"] = {
          require("telescope.themes").get_dropdown({}),
        },
      },
    })

    telescope.load_extension("fzf")
    telescope.load_extension("ui-select")
  end,
}
Conni2461 commented 3 days ago

But why would need to do that? It seems like you want to manully sort (move around) the resilts list.

I cant imagine a usecase where you want to do that

wojciech-kulik commented 3 days ago

I use Telescope in my plugin to present to the user a list of his devices with the ability to reorder the list and delete some devices - basically to manage the list.

Conni2461 commented 3 days ago

Yeah but is telescope the correct solution for your problem or wouldnt it be better to build a ui yourself? Because we are primarly a fuzzy finder over lists and i dont see us implementing bindings or actions to manipulate the entymanager

wojciech-kulik commented 3 days ago

The same question could be asked for any other integration, Telescope has been used for many creative things :). Fuzzy finder is helpful to search devices, that's why I use it. Also, I use it for many other things, so it makes sense to keep my plugin consistent.

I understand that it might be out of the scope of Telescope to support it. I'm just asking if there is any better way to achieve that in Telescope, but based on your answers I assume there isn't. So the only remaining question is why set_selection doesn't work after refresh function and is it an expected behavior? (btw. I worked around it in my plugin by adding a small delay)