Skip to content

Commit f83f2af

Browse files
committed
feat: sort telescope by usage frequency
1 parent a775191 commit f83f2af

1 file changed

Lines changed: 80 additions & 29 deletions

File tree

lua/text-transform/telescope.lua

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
local D = require("text-transform.util.debug")
12
local state = require("text-transform.state")
23
local replacers = require("text-transform.replacers")
34

45
local pickers = require("telescope.pickers")
56
local finders = require("telescope.finders")
6-
local conf = require("telescope.config").values
7+
local telescope_conf = require("telescope.config").values
78
local actions = require("telescope.actions")
89
local action_state = require("telescope.actions.state")
910
local dropdown = require("telescope.themes").get_dropdown({})
11+
local Sorter = require("telescope.sorters").Sorter
12+
local generic_sorter = telescope_conf.generic_sorter()
1013

1114
local TextTransform = {}
1215

@@ -20,25 +23,77 @@ local items = {
2023
{ label = "CONST_CASE", value = "const_case" },
2124
}
2225

23-
-- local default_frequency = {
24-
-- camel_case = 7,
25-
-- snake_case = 6,
26-
-- pascal_case = 5,
27-
-- kebab_case = 4,
28-
-- dot_case = 3,
29-
-- title_case = 2,
30-
-- const_case = 1,
31-
-- }
32-
--
33-
-- local frequency_file = vim.fn.stdpath("config") .. "/text-transform-frequency.json"
34-
-- local frequency
35-
-- if vim.fn.filereadable(frequency_file) == 0 then
36-
-- frequency = default_frequency
37-
-- vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
38-
-- else
39-
-- frequency = vim.fn.json_decode(vim.fn.readfile(frequency_file))
40-
-- end
26+
local default_frequency = {
27+
camel_case = 1,
28+
snake_case = 1,
29+
pascal_case = 1,
30+
kebab_case = 1,
31+
dot_case = 1,
32+
title_case = 1,
33+
const_case = 1,
34+
}
35+
36+
local frequency_file = vim.fn.stdpath("config") .. "/text-transform-frequency.json"
37+
local frequency
38+
39+
local function load_frequency()
40+
if frequency then
41+
return frequency
42+
end
43+
if vim.fn.filereadable(frequency_file) == 0 then
44+
frequency = default_frequency
45+
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
46+
else
47+
frequency = vim.fn.json_decode(vim.fn.readfile(frequency_file))
48+
end
49+
D.log("telescope", "frequency loaded: %s", vim.inspect(frequency))
50+
return frequency
51+
end
52+
53+
local function inc_frequency(name)
54+
frequency[name] = (frequency[name] or 0) + 1
55+
D.log("telescope", "new frequency: %s %d", name, frequency[name])
56+
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
57+
end
58+
59+
local function entry_maker(entry)
60+
return {
61+
value = entry.value,
62+
display = entry.label,
63+
ordinal = entry.label,
64+
frequency = frequency[entry.value] or 1,
65+
}
66+
end
67+
68+
local frequency_sorter = Sorter:new({
69+
---@diagnostic disable-next-line: unused-local
70+
scoring_function = function(self, prompt, line)
71+
local entry
72+
for _, item in ipairs(items) do
73+
if item.label == line then
74+
entry = entry_maker(item)
75+
break
76+
end
77+
end
78+
-- Basic filtering based on prompt matching, non-matching items score below 0 to exclude them
79+
local basic_score = generic_sorter:score(prompt, entry) or 0
80+
-- D.log("telescope", "basic_score: %s", basic_score)
81+
if basic_score < 0 then
82+
return basic_score
83+
end
84+
85+
-- D.log("telescope", "entry: %s", vim.inspect(entry))
86+
-- D.log("telescope", "prompt: %s", prompt)
87+
-- Calculate score based on frequency, higher frequency should have lower score
88+
local freq_score = (entry.frequency or 1) -- Multiply by -1 because we want higher frequency to have lower score
89+
90+
-- D.log("telescope", "freq_score: %s", freq_score)
91+
D.log("telescope", "%s final_score: %s", line, 99999999 - freq_score * 100 + basic_score)
4192

93+
-- Combine scores, with frequency having the primary influence if present
94+
return 99999999 - freq_score * 100 + basic_score -- Division to ensure frequency has a higher weight
95+
end,
96+
})
4297
---@diagnostic disable-next-line: unused-local
4398
-- for _i, k in pairs(default_ordered_keys) do
4499
-- local v = map[k]
@@ -56,9 +111,11 @@ local items = {
56111
--- made.
57112
function TextTransform.popup()
58113
state.save_positions()
114+
load_frequency()
59115

60116
local filtered = {}
61-
local config = _G.TextTransform.options
117+
print(vim.inspect(_G.TextTransform.config))
118+
local config = _G.TextTransform.config
62119

63120
for _, item in ipairs(items) do
64121
if not config.replacers[item.value] or not config.replacers[item.value].enabled then
@@ -72,19 +129,13 @@ function TextTransform.popup()
72129
prompt_title = "Change Case",
73130
finder = finders.new_table({
74131
results = items,
75-
entry_maker = function(entry)
76-
return {
77-
value = entry.value,
78-
display = entry.label,
79-
ordinal = entry.label,
80-
-- ordinal = frequency[entry.value] or 0,
81-
}
82-
end,
132+
entry_maker = entry_maker,
83133
}),
84-
sorter = conf.generic_sorter({}),
134+
sorter = frequency_sorter,
85135
attach_mappings = function(prompt_bufnr)
86136
actions.select_default:replace(function()
87137
local selection = action_state.get_selected_entry()
138+
inc_frequency(selection.value)
88139
actions.close(prompt_bufnr)
89140
vim.schedule(function()
90141
replacers.replace_selection(selection.value)

0 commit comments

Comments
 (0)