Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ luac.out
.LSOverride

# Icon must end with two \r
Icon
Icon


# Thumbnails
._*
Expand Down Expand Up @@ -93,3 +94,4 @@ Sessionx.vim
tags
# Persistent undo
[._]*.un~
.aider*
24 changes: 24 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project
telescope-frecency.nvim is a Neovim Telescope extension implementing Mozilla's Frecency algorithm for intelligent file prioritization.

## Build/Test Commands
- Run all tests: `bin/run-tests`
- Run specific test: `bin/run-tests lua/frecency/tests/test_file.lua`
- Run with verbose logs: `bin/run-tests -v`
- Use custom Neovim binary: `bin/run-tests -e /path/to/nvim`

## Code Style
- Language: Lua
- Indentation: 2 spaces
- Typing: Use LuaLS annotations (---@class, ---@param, etc.)
- Naming: snake_case for variables/functions
- Error handling: Check errors with assertions
- Documentation: Docstrings for public functions
- Async patterns: Use async/await with plenary.async
- Testing: Test files in lua/frecency/tests/ with *_spec.lua suffix
- Imports: Standard Lua require statements
- Type validation: Use vim.validate for config validation
6 changes: 6 additions & 0 deletions lua/frecency/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ local os_util = require "frecency.os_util"
---@field ignore_patterns? string[] default: { "*.git/*", "*/tmp/*", "term://*" }
---@field ignore_register? fun(bufnr: integer): boolean
---@field matcher? "default"|"fuzzy" default: "default"
---@field remove_non_existent_files? boolean default: true
---@field scoring_function? fun(recency: integer, fzy_score: number): number default: see lua/frecency/config.lua
---@field max_timestamps? integer default: 10
---@field path_display? table default: nil
Expand Down Expand Up @@ -54,6 +55,7 @@ local Config = {}
---@field ignore_patterns string[] default: { "*.git/*", "*/tmp/*", "term://*" }
---@field ignore_register? fun(bufnr: integer): boolean default: nil
---@field matcher "default"|"fuzzy" default: "default"
---@field remove_non_existent_files boolean default: true
---@field scoring_function fun(recency: integer, fzy_score: number): number default: see lua/frecency/config.lua
---@field max_timestamps integer default: 10
---@field path_display? table default: nil
Expand Down Expand Up @@ -89,6 +91,7 @@ Config.new = function()
max_timestamps = true,
path_display = true,
preceding = true,
remove_non_existent_files = true,
scoring_function = true,
show_filter_column = true,
show_scores = true,
Expand Down Expand Up @@ -132,6 +135,7 @@ Config.default_values = {
or { "*.git/*", "*/tmp/*", "term://*" },
matcher = "default",
max_timestamps = 10,
remove_non_existent_files = true,
recency_values = {
{ age = 240, value = 100 }, -- past 4 hours
{ age = 1440, value = 80 }, -- past day
Expand Down Expand Up @@ -208,6 +212,7 @@ Config.setup = function(ext_config)
vim.validate("preceding", opts.preceding, function(v)
return v == "opened" or v == "same_repo" or v == nil
end, '"opened" or "same_repo" or nil')
vim.validate("remove_non_existent_files", opts.remove_non_existent_files, "boolean", true)
vim.validate("show_filter_column", opts.show_filter_column, { "boolean", "table" }, true)
vim.validate("show_scores", opts.show_scores, "boolean")
vim.validate("show_unindexed", opts.show_unindexed, "boolean")
Expand Down Expand Up @@ -261,6 +266,7 @@ Config.setup = function(ext_config)
end,
'"opened" or "same_repo" or nil',
},
remove_non_existent_files = { opts.remove_non_existent_files, "b", true },
show_filter_column = { opts.show_filter_column, { "b", "t" }, true },
show_scores = { opts.show_scores, "b" },
show_unindexed = { opts.show_unindexed, "b" },
Expand Down
26 changes: 24 additions & 2 deletions lua/frecency/finder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,34 @@ function Finder:start(epoch)
async.void(function()
-- NOTE: return to the main loop to show the main window
async.util.scheduler()

-- Collect deleted files to remove from database if enabled
local deleted_files = {}
local check_existence = config.remove_non_existent_files

-- Process database entries
for _, file in ipairs(self:get_results(self.paths, epoch)) do
file.path = os_util.normalize_sep(file.path)
local entry = self.entry_maker(file)
self.tx.send(entry)

if not check_existence or fs.exists(file.path) then
local entry = self.entry_maker(file)
self.tx.send(entry)
else
-- File doesn't exist, schedule it for removal from database
table.insert(deleted_files, file.path)
end
end

self.tx.send(nil)

-- Remove deleted files from database in the background after telescope display is complete
if check_existence and #deleted_files > 0 then
log.debug("Removing " .. #deleted_files .. " deleted files from database")
async.void(function()
self.database:remove_files(deleted_files)
end)()
end

if self.need_scan_dir then
vim
.iter(self.paths)
Expand Down