telescope.nvim

repository·master·Indexed 12 days ago

https://github.com/nvim-telescope/telescope.nvim

A highly extendable fuzzy finder for Neovim designed around modularity with pluggable pickers, sorters, and previewers. It supports file, Vim, Git, and LSP pickers, and requires Neovim >=v0.11.7 and plenary.nvim.

Tokens
9.4K
Snippets
23
Records
28
Agent score
48%

What's inside Telescope

  1. Introduction to Telescope development

    master
    To develop custom pickers or extensions for Telescope, you should first understand the core architectural components: pickers, finders, actions, and previewers. It is highly recommended to review the architectural flow-chart available in Neovim help via :h telescope.nvim before diving into implementation. This guide assumes proficiency in the Lua programming language.
  2. Understand Sorters and their role

    master

    A Sorter is a function called by a Picker for every item returned by a Finder. It calculates the "distance" between the current user prompt and the entry provided by the finder. Lower distance values typically result in higher ranking in the results list.

    Available Sorters:
    - `sorters.get_fuzzy_file`: Default for files.
    - `sorters.get_generic_fuzzy_sorter`: Default for everything else.
    - `sorters.get_levenshtein_sorter`: Levenshtein distance algorithm.
    - `sorters.get_fzy_sorter`: fzy algorithm.
    - `sorters.fuzzy_with_index_bias`: Considers when an item was added to the list.
  3. How to replace default actions in a Picker

    master

    To change what happens when a user interacts with the picker (e.g., pressing <CR>), use the attach_mappings key in the picker's configuration table.

    1. Define attach_mappings as a function that receives prompt_bufnr and map.
    2. Use actions.select_default:replace(callback) to override the default selection behavior.
    3. Inside the callback, use actions.close(prompt_bufnr) to close the picker and action_state.get_selected_entry() to retrieve the chosen item.
    4. The attach_mappings function must return true to keep default mappings (like selection movement) or false to replace them entirely. Returning nil will cause an error.

    Note: Replacing actions via select_default:replace ensures that if a user has remapped their default selection key, your picker will respect that mapping.

    local actions = require "telescope.actions"
    local action_state = require "telescope.actions.state"
    
    -- Inside your pickers.new configuration:
    attach_mappings = function(prompt_bufnr, map)
      actions.select_default:replace(function()
        actions.close(prompt_bufnr)
        local selection = action_state.get_selected_entry()
        -- Do something with selection
        print(vim.inspect(selection))
      end)
      return true
    end,
  4. Install telescope.nvim

    master

    To install telescope.nvim, it is recommended to pin to the latest release tag. Using lazy.nvim, you can include plenary.nvim as a required dependency and telescope-fzf-native.nvim as an optional but highly recommended dependency for improved sorting performance.

    Before installing, ensure you meet the requirements:

    {
        'nvim-telescope/telescope.nvim', version = '*',
        dependencies = {
            'nvim-lua/plenary.nvim',
            -- optional but recommended
            { 'nvim-telescope/telescope-fzf-native.nvim', build = 'make' },
        }
    }
  5. Bundle a picker as a Telescope extension

    master

    To make your picker available via the :Telescope <name> command, you must structure your plugin and register it as an extension.

    Directory Structure:

    . 
    └── lua
        ├── plugin_name
        │   └── init.lua
        └── telescope
            └── _extensions
                └── plugin_name.lua

    Note: The _extensions directory name is significant.

    Registration: In lua/telescope/_extensions/plugin_name.lua, return the result of telescope.register_extension:

    return require("telescope").register_extension {
      setup = function(ext_config, config)
        -- access extension config and user config
      end,
      exports = {
        stuff = require("plugin_name").stuff
      },
    }
    • setup: A function called during registration. It provides access to ext_config (extension-specific) and config (user's global telescope config). Use this to set up defaults or override internal functions like sorters.
    • exports: A table of pickers/functions exported by your extension. If you export a single item, name the key after your plugin so it can be accessed via Telescope plugin_name.
    return require("telescope").register_extension {
      setup = function(ext_config, config)
        -- access extension config and user config
      end,
      exports = {
        stuff = require("plugin_name").stuff
      },
    }
  6. Requirements for telescope.nvim

    master

    Before using Telescope, ensure your environment meets these specifications:

    • Neovim: version >=v0.11.7 built with LuaJIT (verify with :version).
    • plenary.nvim: nvim-lua/plenary.nvim is a required dependency.

    Recommended external tools for specific features:

    • ripgrep (BurntSushi/ripgrep): Required for live_grep and grep_string; also used by find_files.
    • fd (sharkdp/fd): Recommended finder.
    • devicons (nvim-tree/nvim-web-devicons): For file icons.
    • Native Sorters: For significantly improved performance, install telescope-fzf-native.nvim or telescope-fzy-native.nvim.
  7. Use Telescope Themes

    master

    Themes are pre-defined groups of settings that change the visual appearance of the picker. You can apply themes in three ways:

    1. Via Lua builtin calls: Pass the theme function as an argument.
    2. Via Vim commands: Use the theme option.
    3. Via global setup: Define a theme for specific pickers in the pickers table.
    " 1. Using Lua builtin with a theme
    noremap <Leader>f :lua require'telescope.builtin'.find_files(require('telescope.themes').get_dropdown({}))<cr>
    
    " 2. Using Vim command with theme option
    Telescope find_files theme=dropdown
    
    " 3. Configuring in setup()
    require('telescope').setup{
      pickers = {
        find_files = {
          theme = "dropdown",
        }
      }
    }
  8. Load and use Telescope Extensions

    master

    Extensions add new functionality or integrations. To use an extension, you must load it using load_extension(). Once loaded, extension pickers are available via the :Telescope command or through the telescope.extensions Lua API.

    -- Loading an extension
    require('telescope').load_extension('fzy_native')
    
    -- Accessing an extension picker via Lua
    -- (Example using 'dap' extension)
    require('telescope').extensions.dap.configurations()
  9. Configure Layout strategies and sizes

    master

    Layouts are controlled by a layout_strategy and a corresponding layout_config. Sizes in layouts are "resolvable": a value like 0.5 represents 50% of the screen width, while 80 represents exactly 80 characters.

    You can configure layouts globally in setup() or per-call in a builtin function.

    -- Per-call configuration
    require('telescope.builtin').find_files({layout_strategy='vertical', layout_config={width=0.5}})
    
    -- Global configuration in setup()
    require('telescope').setup({
      defaults = {
        layout_config = {
          vertical = { width = 0.5 }
        },
      },
    })
  10. Configure telescope.nvim globally and per picker

    master

    Telescope supports two levels of customization:

    1. Global Customization: Applied to all pickers via the setup() method.
    2. Individual Customization: Applied to a specific picker by passing an opts table to the builtin function (e.g., builtin.find_files(opts)).

    The setup() function accepts a table with three main sections: defaults (global), pickers (per-picker defaults), and extensions (extension-specific config).

    require('telescope').setup{
      defaults = {
        -- Default configuration for telescope goes here:
        -- config_key = value,
        mappings = {
          i = {
            -- map actions.which_key to <C-h>
            ["<C-h>"] = "which_key"
          }
        }
      },
      pickers = {
        -- Default configuration for builtin pickers goes here:
        -- picker_name = {
        --   picker_config_key = value,
        --   ...
        -- }
      },
      extensions = {
        -- Your extension configuration goes here:
        -- extension_name = {
        --   extension_config_key = value,
        -- }
      }
    }
  11. Basic usage and keybindings

    master

    You can test the installation by running :Telescope find_files.

    To use Telescope effectively, it is common to map builtin pickers to keybindings. Here is a standard setup using the telescope.builtin module:

    local builtin = require('telescope.builtin')
    vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = 'Telescope find files' })
    vim.keymap.set('n', '<leader>fg', builtin.live_grep, { desc = 'Telescope live grep' })
    vim.keymap.set('n', '<leader>fb', builtin.buffers, { desc = 'Telescope buffers' })
    vim.keymap.set('n', '<leader>fh', builtin.help_tags, { desc = 'Telescope help tags' })