Home

Awesome

smart-open.nvim

A telescope.nvim extension designed to provide the best possible suggestions for quickly opening files in Neovim. smart-open will improve its suggestions over time, adapting to your usage.

Warning ⚠️ smart-open is beta at this time. Contributions welcome.

Preview

Isn't this yet another fuzzy file finding plugin?

In a way, but most other solutions require multiple mappings to search:

The goal of smart-open is to give you highly relevant results with as few keystrokes as possible--so much so that only a single mapping is needed for searching everything while still managing to be quick about it.

How it works

The source of suggestions is a combination of files under the current working directory, and your history. Ranking takes the following factors into account:

This ranking algorithm is self-tuning. Over time, the weights of the factors above will be adjusted based upon your interaction with it. The tuning process is especially sensitive to selecting a suggestion that is not at the top. Weights will be adjusted relative to the higher-ranked suggestions that were not selected.

Calculating and tuning all these factors might sound slow, but this is not the case. Results return quickly and the impact of these calculations are optimized to be negligible.

Notes

Acknowledgements

Using an implementation of Mozilla's Frecency algorithm (used in Firefox's address bar), files edited frecently are given higher precedence in the list index.

As the extension learns your editing habits over time, the sorting of the list is dynamically altered to prioritize the files you're likely to need.

Requirements

Timestamps, scoring weights, and file records are stored in an SQLite3 database for persistence and speed.

Installation

Lazy.nvim

Put the following in your lazy.setup(...):

{
  "danielfalk/smart-open.nvim",
  branch = "0.2.x",
  config = function()
    require("telescope").load_extension("smart_open")
  end,
  dependencies = {
    "kkharji/sqlite.lua",
    -- Only required if using match_algorithm fzf
    { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
    -- Optional.  If installed, native fzy will be used when match_algorithm is fzy
    { "nvim-telescope/telescope-fzy-native.nvim" },
  },
}

Packer.nvim

use {
  "danielfalk/smart-open.nvim",
  branch = "0.2.x",
  config = function()
    require"telescope".load_extension("smart_open")
  end,
  requires = {
    {"kkharji/sqlite.lua"},
    -- Only required if using match_algorithm fzf
    { "nvim-telescope/telescope-fzf-native.nvim", run = "make" },
    -- Optional.  If installed, native fzy will be used when match_algorithm is fzy
    { "nvim-telescope/telescope-fzy-native.nvim" },
  }
}

sqlite3 (required)

sqlite3 must be installed locally. (if you are on mac it might be installed already)

Windows

Download precompiled and set let g:sqlite_clib_path = path/to/sqlite3.dll (note: /)

Linux

Arch
sudo pacman -S sqlite # Arch
sudo apt-get install sqlite3 libsqlite3-dev # Ubuntu
Fedora
sudo dnf install sqlite sqlite-devel sqlite-tcl

Nix (home-manager)

programs.neovim.plugins = [
    {
      plugin = pkgs.vimPlugins.sqlite-lua;
      config = "let g:sqlite_clib_path = '${pkgs.sqlite.out}/lib/libsqlite3.so'";
    }
];

If no database is found when running Neovim with the plugin installed, a new one is created and entries from shada v:oldfiles are automatically imported.

Usage

:Telescope smart_open

..or to map to a key:

vim.keymap.set("n", "<leader><leader>", function ()
  require("telescope").extensions.smart_open.smart_open()
end, { noremap = true, silent = true })

Options

Options can be set when opening the picker. For example:

require('telescope').extensions.smart_open.smart_open {
  cwd_only = true,
  filename_first = false,
}

Configuration

See default configuration for full details on configuring Telescope.

Example Configuration:

telescope.setup {
  extensions = {
    smart_open = {
      match_algorithm = "fzf",
      disable_devicons = false,
    },
  },
}

Known Limitations

For files not already in your history, smart-open uses ripgrep for scanning the current directory. (The command is roughly: rg --files --glob-case-insensitive --hidden --ignore-file=<cwd>/.ff-ignore -g <ignore_patterns...>).

As a result, files added to git, but also ignored by git, will not be included. While not common, this is something that git allows. If this becomes a problem you can work around it by either changing your git ignore patterns, editing the file in neovim in some other way, (thereby adding it to the history), or by using ripgrep's .ignore file for overriding git.

Highlight Groups

Directory