Telescope, Treesitter et les plugins essentiels pour coder dans Neovim

Telescope, Treesitter et les plugins essentiels pour coder dans Neovim

·7 min de lecture·Mis à jour le 6 février 2026

Au-delà du LSP

Un LSP bien configuré ne suffit pas à transformer Neovim en environnement de développement complet. Il faut une couche de plugins qui gèrent la recherche, la manipulation de code et Git.

Telescope : chercher tout

Telescope est un fuzzy finder qui cherche fichiers, texte, buffers, aide — tout — depuis une interface unifiée. C'est le plugin le plus utilisé d'une config typique.

Par défaut, ses performances se dégradent sur un gros projet. L'extension telescope-fzf-native, un binaire compilé en C qui remplace l'algorithme de recherche, change complètement la donne.

Keybindings

local builtin = require("telescope.builtin")

vim.keymap.set("n", "<leader>ff", builtin.find_files, { desc = "Find files" })
vim.keymap.set("n", "<leader>fg", builtin.live_grep, { desc = "Live grep" })
vim.keymap.set("n", "<leader>fb", builtin.buffers, { desc = "Buffers" })
vim.keymap.set("n", "<leader>fh", builtin.help_tags, { desc = "Help tags" })
vim.keymap.set("n", "<leader>fr", builtin.oldfiles, { desc = "Recent files" })
vim.keymap.set("n", "<leader>fw", builtin.grep_string, { desc = "Grep word under cursor" })
vim.keymap.set("n", "<leader>/", builtin.current_buffer_fuzzy_find, { desc = "Fuzzy find in buffer" })

<leader>ff pour ouvrir un fichier, <leader>fg pour balayer le projet en recherche textuelle. Et <leader>/ pour chercher dans le buffer courant, bien supérieur au / vanilla.

Configuration et filtres

require("telescope").setup({
  defaults = {
    path_display = { "truncate" },
    file_ignore_patterns = {
      "node_modules/",
      ".git/",
      ".next/",
      "dist/",
      "%.lock",
      "%.min%.js",
      "%.min%.css",
    },
    mappings = {
      i = {
        ["<C-j>"] = require("telescope.actions").move_selection_next,
        ["<C-k>"] = require("telescope.actions").move_selection_previous,
        ["<C-q>"] = require("telescope.actions").send_selected_to_qflist
          + require("telescope.actions").open_qflist,
      },
    },
  },
})

Les détails qui comptent :

  • Ignore patterns : sans blacklist de node_modules, .git, .next, dist, des lock files et des minifiés, une recherche sur un projet Next.js renvoie des dizaines de milliers de résultats inutiles. Attention, %.lock et %.min.js sont du regex Lua, pas du glob.
  • Path display truncate : rend les chemins longs lisibles.
  • C-j/C-k en insert mode : navigation dans les résultats sans quitter le mode insertion.
  • C-q : envoie les résultats à la quickfix list, très utile pour un search-and-replace multi-fichiers.

La preview utilise Treesitter pour la coloration syntaxique, pas du regex approximatif.

Treesitter : plus qu'une coloration syntaxique

Treesitter est un parser incrémental qui comprend la structure du code : où commencent et finissent les fonctions, où sont les commentaires, comment les blocs s'imbriquent. Du vrai parsing d'AST, pas du regex.

require("nvim-treesitter.configs").setup({
  ensure_installed = {
    "bash", "c", "css", "dockerfile", "go", "html",
    "javascript", "json", "lua", "markdown", "markdown_inline",
    "python", "rust", "tsx", "typescript", "vim", "vimdoc", "yaml",
  },
  auto_install = true,
  highlight = { enable = true },
  indent = { enable = true },
})

Dix-huit parsers couvrant l'essentiel des langages du quotidien, et auto_install = true pour que les autres s'installent tout seuls au besoin.

Deux compléments qui s'appuient dessus :

  • nvim-ts-autotag ferme automatiquement les balises HTML/JSX, et met à jour la balise fermante quand on modifie l'ouvrante. Indispensable en React.
  • tailwind-tools.nvim affiche un aperçu des couleurs dans le buffer, masque (« conceal ») les longues listes de classes pour la lisibilité, et trie l'ordre des classes automatiquement.

Les indispensables de l'édition

nvim-autopairs

{
  "windwp/nvim-autopairs",
  event = "InsertEnter",
  config = function()
    local npairs = require("nvim-autopairs")
    npairs.setup({
      check_ts = true,
    })
    -- Intégration avec nvim-cmp
    local cmp_autopairs = require("nvim-autopairs.completion.cmp")
    require("cmp").event:on("confirm_done", cmp_autopairs.on_confirm_done())
  end,
}

Fermeture automatique des parenthèses, crochets, accolades et guillemets. check_ts = true interroge Treesitter avant de fermer : pas de parenthèse orpheline dans un commentaire, pas de guillemet cassé dans une string. Et l'intégration cmp ferme aussi les paires quand on accepte une complétion.

Comment.nvim

{
  "numToStr/Comment.nvim",
  opts = {},
}

gcc toggle une ligne, gc suivi d'un motion en couvre plus (gcap pour un paragraphe, gc3j pour trois lignes). Le plugin choisit le symbole de commentaire selon le langage du fichier.

nvim-surround

{
  "kylechui/nvim-surround",
  version = "*",
  event = "VeryLazy",
  opts = {},
}
  • ys{motion}{char} — ajouter un wrapper. ysiw" entoure le mot sous le curseur de guillemets.
  • cs{old}{new} — changer. cs"' remplace les guillemets doubles par des simples.
  • ds{char} — supprimer. ds( enlève les parenthèses autour de l'expression.

todo-comments.nvim

{
  "folke/todo-comments.nvim",
  event = "VimEnter",
  dependencies = { "nvim-lua/plenary.nvim" },
  opts = { signs = false },
}

Highlight les TODO, FIXME et BUG en couleurs distinctes pour qu'ils restent visibles dans le code.

Formatting avec Conform.nvim

{
  "stevearc/conform.nvim",
  event = "BufWritePre",
  config = function()
    require("conform").setup({
      formatters_by_ft = {
        javascript = { "prettier" },
        typescript = { "prettier" },
        typescriptreact = { "prettier" },
        javascriptreact = { "prettier" },
        css = { "prettier" },
        html = { "prettier" },
        json = { "prettier" },
        yaml = { "prettier" },
        markdown = { "prettier" },
        lua = { "stylua" },
        python = { "ruff_format" },
      },
      format_on_save = {
        timeout_ms = 3000,
        lsp_format = "fallback",
      },
    })

    vim.keymap.set({ "n", "v" }, "<leader>cf", function()
      require("conform").format({ async = true, lsp_format = "fallback" })
    end, { desc = "Format file or selection" })
  end,
}

Prettier pour tout ce qui est web, Stylua pour le Lua (y compris la config Neovim), ruff_format pour Python. Le format on save a un timeout de 3 secondes et retombe sur le LSP si le formateur dédié échoue. <leader>cf pour un formatage manuel.

Les binaires sont installés automatiquement par Mason via mason-conform.

Gitsigns : Git dans la marge

Gitsigns affiche les changements Git ligne par ligne dans la colonne de signes.

{
  "lewis6991/gitsigns.nvim",
  opts = {
    on_attach = function(bufnr)
      local gitsigns = require("gitsigns")
      local map = function(mode, l, r, opts)
        opts = opts or {}
        opts.buffer = bufnr
        vim.keymap.set(mode, l, r, opts)
      end

      -- Naviguer entre les changements
      map("n", "]h", gitsigns.next_hunk, { desc = "Next hunk" })
      map("n", "[h", gitsigns.prev_hunk, { desc = "Previous hunk" })

      -- Actions sur les hunks
      map("n", "<leader>hs", gitsigns.stage_hunk, { desc = "Stage hunk" })
      map("n", "<leader>hr", gitsigns.reset_hunk, { desc = "Reset hunk" })
      map("n", "<leader>hp", gitsigns.preview_hunk, { desc = "Preview hunk" })
      map("n", "<leader>hb", gitsigns.blame_line, { desc = "Blame line" })
    end,
  },
}

Les symboles du gutter indiquent ajouté, modifié ou supprimé. Les keybindings permettent de naviguer entre les hunks (]h / [h), de les stage ou reset individuellement, de voir le diff avant de commiter, ou de blâmer une ligne — le tout sans quitter Neovim.

Pour finir

Telescope pour chercher n'importe quoi instantanément, Treesitter pour comprendre le code en profondeur, Conform pour formater sans y penser, Gitsigns pour voir l'histoire du code dans la marge. Aucun plugin flashy : chacun fait une chose et la fait bien, exactement la philosophie Unix qu'on retrouve dans Neovim.

PartagerLinkedInXBluesky

Articles similaires