🔭 Telescope for Neovim

Shaik Zahid
7 min readFeb 7, 2023

--

Fuzzy finder for Neovim

Telescope is a highly extendable fuzzy finder over lists. Built on the latest awesome features from Neovim core. Telescope is centered around modularity, allowing for easy customization.

Requirements

Installation

  • Add references to our plugins.lua file in lua directory.
return {

-- Bufferline
{
'akinsho/bufferline.nvim',
dependencies = {
'nvim-tree/nvim-web-devicons'
},
},

-- Colorscheme
{
'folke/tokyonight.nvim',
},

-- Hop (Better Navigation)
{
"phaazon/hop.nvim",
lazy = true,
},


-- Lualine
{
'nvim-lualine/lualine.nvim',
dependencies = {
'nvim-tree/nvim-web-devicons'
},
},

-- Nvimtree (File Explorer)
{
'nvim-tree/nvim-tree.lua',
lazy = true,
dependencies = {
'nvim-tree/nvim-web-devicons',
},
},

-- Telescope (Fuzzy Finder)
-- Added these plugins to install Telescope
{
'nvim-telescope/telescope.nvim',
lazy = true,
dependencies = {
{'nvim-lua/plenary.nvim'},
}
},

-- Which-key
{
'folke/which-key.nvim',
lazy = true,
},

}
  • Now invoke Lazy(Package Manager) using Space + p command in Normal mode to install Telescope and its dependencies.
  • Install the plugins using “shift + i” and we can go on to the next steps of configuring Telescope.

Configuration

  • Create a new file telescope-config.lua in your lua directory and add this code.
-- telescope-config.lua

local status_ok, telescope = pcall(require, "telescope")
if not status_ok then
return
end


local actions = require("telescope.actions")
require('telescope').setup{
defaults = {
-- Default configuration for telescope goes here:
-- config_key = value,

prompt_prefix = " ",
selection_caret = " ",
path_display = { "smart" },


mappings = {
i = {
["<C-n>"] = actions.cycle_history_next,
["<C-p>"] = actions.cycle_history_prev,

["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,

["<C-c>"] = actions.close,

["<Down>"] = actions.move_selection_next,
["<Up>"] = actions.move_selection_previous,

["<CR>"] = actions.select_default,
["<C-x>"] = actions.select_horizontal,
["<C-v>"] = actions.select_vertical,
["<C-t>"] = actions.select_tab,

["<C-u>"] = actions.preview_scrolling_up,
["<C-d>"] = actions.preview_scrolling_down,

["<PageUp>"] = actions.results_scrolling_up,
["<PageDown>"] = actions.results_scrolling_down,

["<Tab>"] = actions.toggle_selection + actions.move_selection_worse,
["<S-Tab>"] = actions.toggle_selection + actions.move_selection_better,
["<C-q>"] = actions.send_to_qflist + actions.open_qflist,
["<M-q>"] = actions.send_selected_to_qflist + actions.open_qflist,
["<C-l>"] = actions.complete_tag,
["<C-_>"] = actions.which_key, -- keys from pressing <C-/>
},

n = {
["<esc>"] = actions.close,
["<CR>"] = actions.select_default,
["<C-x>"] = actions.select_horizontal,
["<C-v>"] = actions.select_vertical,
["<C-t>"] = actions.select_tab,

["<Tab>"] = actions.toggle_selection + actions.move_selection_worse,
["<S-Tab>"] = actions.toggle_selection + actions.move_selection_better,
["<C-q>"] = actions.send_to_qflist + actions.open_qflist,
["<M-q>"] = actions.send_selected_to_qflist + actions.open_qflist,

["j"] = actions.move_selection_next,
["k"] = actions.move_selection_previous,
["H"] = actions.move_to_top,
["M"] = actions.move_to_middle,
["L"] = actions.move_to_bottom,

["<Down>"] = actions.move_selection_next,
["<Up>"] = actions.move_selection_previous,
["gg"] = actions.move_to_top,
["G"] = actions.move_to_bottom,

["<C-u>"] = actions.preview_scrolling_up,
["<C-d>"] = actions.preview_scrolling_down,

["<PageUp>"] = actions.results_scrolling_up,
["<PageDown>"] = actions.results_scrolling_down,

["?"] = actions.which_key,
},
}
},
pickers = {
-- Default configuration for builtin pickers goes here:
-- picker_name = {
-- picker_config_ key = value,
-- ...
-- }
-- Now the picker_config_key will be applied every time you call this
-- builtin picker
},
extensions = {
-- Your extension configuration goes here:
-- extension_name = {
-- extension_config_key = value,
-- }
-- please take a look at the readme of the extension you want to configure
}
}

Update the Main Configuration

-- init.lua

require "options"
require "keymaps"
require "lazy-config"
require "bufferline-config"
require "hop-config"
require "nvim-tree-config"
require "lualine-config"
require "telescope-config" -- Added this line to initial file
require "whichkey"

Telescope Keybindings in Which-key

  • Update the mappings variable in whichkey.lua with Telescope keys

-- Telescope
f = {
name = "File Search",
c = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },
f = { "<cmd>lua require('telescope.builtin').find_files()<cr>", "Find files" },
t = { "<cmd>Telescope live_grep <cr>", "Find Text Pattern In All Files" },
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
},

s = {
name = "Search",
h = { "<cmd>Telescope help_tags<cr>", "Find Help" },
m = { "<cmd>Telescope man_pages<cr>", "Man Pages" },
r = { "<cmd>Telescope registers<cr>", "Registers" },
k = { "<cmd>Telescope keymaps<cr>", "Keymaps" },
c = { "<cmd>Telescope commands<cr>", "Commands" },
},


  • The updated whichkey.lua file will look like this…
-- whichkey.lua

local status_ok, which_key = pcall(require, "which-key")
if not status_ok then
return
end

local setup = {
plugins = {
marks = true, -- shows a list of your marks on ' and `
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
spelling = {
enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
suggestions = 20, -- how many suggestions should be shown in the list?
},
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
-- No actual key bindings are created
presets = {
operators = false, -- adds help for operators like d, y, ... and registers them for motion / text object completion
motions = true, -- adds help for motions
text_objects = true, -- help for text objects triggered after entering an operator
windows = true, -- default bindings on <c-w>
nav = true, -- misc bindings to work with windows
z = true, -- bindings for folds, spelling and others prefixed with z
g = true, -- bindings for prefixed with g
},
},
-- add operators that will trigger motion and text object completion
-- to enable all native operators, set the preset / operators plugin above
-- operators = { gc = "Comments" },
key_labels = {
-- override the label used to display some keys. It doesn't effect WK in any other way.
-- For example:
-- ["<space>"] = "SPC",
-- ["<cr>"] = "RET",
-- ["<tab>"] = "TAB",
},
icons = {
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
separator = "➜", -- symbol used between a key and it's label
group = "+", -- symbol prepended to a group
},
popup_mappings = {
scroll_down = "<c-d>", -- binding to scroll down inside the popup
scroll_up = "<c-u>", -- binding to scroll up inside the popup
},
window = {
border = "rounded", -- none, single, double, shadow
position = "bottom", -- bottom, top
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]
padding = { 2, 2, 2, 2 }, -- extra window padding [top, right, bottom, left]
winblend = 0,
},
layout = {
height = { min = 4, max = 25 }, -- min and max height of the columns
width = { min = 20, max = 50 }, -- min and max width of the columns
spacing = 3, -- spacing between columns
align = "left", -- align columns left, center or right
},
ignore_missing = true, -- enable this to hide mappings for which you didn't specify a label
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "call", "lua", "^:", "^ " }, -- hide mapping boilerplate
show_help = true, -- show help message on the command line when the popup is visible
triggers = "auto", -- automatically setup triggers
-- triggers = {"<leader>"} -- or specify a list manually
triggers_blacklist = {
-- list of mode / prefixes that should never be hooked by WhichKey
-- this is mostly relevant for key maps that start with a native binding
-- most people should not need to change this
i = { "j", "k" },
v = { "j", "k" },
},
}

local opts = {
mode = "n", -- NORMAL mode
prefix = "<leader>",
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
silent = true, -- use `silent` when creating keymaps
noremap = true, -- use `noremap` when creating keymaps
nowait = true, -- use `nowait` when creating keymaps
}

local mappings = {

["e"] = { "<cmd>NvimTreeToggle<cr>", "Explorer" }, -- File Explorer
["k"] = { "<cmd>bdelete<CR>", "Kill Buffer" }, -- Close current file
["p"] = { "<cmd>Lazy<CR>", "Plugin Manager" }, -- Invoking plugin manager
["q"] = { "<cmd>wqall!<CR>", "Quit" }, -- Quit Neovim after saving the file
["w"] = { "<cmd>w!<CR>", "Save" }, -- Save current file

-- Telescope
f = {
name = "File Search",
c = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },
f = { "<cmd>lua require('telescope.builtin').find_files()<cr>", "Find files" },
t = { "<cmd>Telescope live_grep <cr>", "Find Text Pattern In All Files" },
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
},

s = {
name = "Search",
h = { "<cmd>Telescope help_tags<cr>", "Find Help" },
m = { "<cmd>Telescope man_pages<cr>", "Man Pages" },
r = { "<cmd>Telescope registers<cr>", "Registers" },
k = { "<cmd>Telescope keymaps<cr>", "Keymaps" },
c = { "<cmd>Telescope commands<cr>", "Commands" },
},
}

which_key.setup(setup)
which_key.register(mappings, opts)

  • Which-key looks like this…

Telescope Keybindings

  • Space + f + c :- List available colorschemes
  • Space + f + f :- Find files
  • Space + f + t :- Find text pattern anywhere
  • Space + f + r :- Explore recent files
  • Space + s + h :- List help Docs
  • Space + s + m :- List man pages
  • Space + s + k :- List available keys with their description.
  • Space + s + c :- List all commands.

Telescope Alternatives

Neovim From Scratch

  • If you want a complete installation and configuration of Neovim from Scratch, then you can head over to my NEOVIM SERIES.
  • This series is updated regularly, with updates and inclusion of newer plugins which improves the wholesome IDE experience of Neovim.

--

--