Last active 6 hours ago

fzf.lua Raw
1return {
2 'ibhagwan/fzf-lua',
3 dependencies = { 'nvim-tree/nvim-web-devicons' },
4 event = 'VeryLazy',
5 config = function()
6 local actions = require('fzf-lua').actions
7 -- Helper function to create horizontal layout
8 local function with_horizontal_layout(fzf_func, opts)
9 return function()
10 local config = vim.tbl_deep_extend('force', opts or {}, {
11 winopts = {
12 fullscreen = true,
13 preview = {
14 layout = 'horizontal',
15 horizontal = 'down:60%',
16 scrollbar = 'float',
17 scrolloff = '-4',
18 },
19 border = 'rounded',
20 },
21 })
22 fzf_func(config)
23 end
24 end
25 local opts = {
26 previewers = {
27 builtin = {
28 syntax_limit_b = 1024 * 100,
29 },
30 },
31 hls = {
32 match = 'FzfLuaFzfMatch',
33 },
34 fzf_opts = {
35 ['--cycle'] = true,
36 },
37 winopts = {
38 fullscreen = true,
39 preview = {
40 vertical = 'right:60%', -- show preview on the right, take 60% of space
41 layout = 'vertical',
42 scrollbar = 'float',
43 scrolloff = '-4',
44 },
45 border = 'rounded',
46 },
47 grep = {
48 rg_glob = true,
49 glob_flag = '--iglob',
50 glob_separator = '%s%-%-',
51 cmd = 'rg --line-number --column --no-heading --color=always',
52 rg_opts = table.concat({
53 '--hidden',
54 '--no-ignore-vcs',
55 '--glob=!**/.local/**',
56 '--glob=!**/.rustup/**',
57 '--glob=!**/node_modules/**',
58 '--glob=!**/.cargo/**',
59 '--glob=!**/.continue/**',
60 '--glob=!**/.mozilla/**',
61 '--glob=!**/go/pkg/mod/**',
62 '--glob=!**/Code/User/**',
63 '--glob=!**/.git/**',
64 '--glob=!**/.npm/**',
65 '--glob=!**/.cache/**',
66 }, ' '),
67 },
68 files = {
69 cmd = table.concat({
70 'fd --type f --hidden --follow',
71 '--exclude .git',
72 '--exclude node_modules',
73 '--exclude .cargo',
74 '--exclude .mozilla',
75 '--exclude .cache',
76 '--exclude .npm',
77 '--exclude .rustup',
78 '--exclude .dotnet',
79 '--exclude go/pkg/mod',
80 '--exclude Code/User',
81 '--exclude .local',
82 '--exclude .continue',
83 }, ' '),
84 formatter = 'path.dirname_first',
85 -- formatter = 'path.filename_first',
86 cwd_prompt_shorten_len = 50, -- shorten prompt beyond this length
87 cwd_prompt_shorten_val = 3, -- shortened path parts length cwd_prompt_shorten_len = 50,
88 },
89 defaults = {
90 git_icons = true,
91 file_icons = true,
92 color_icons = true,
93 },
94 keymap = {
95 builtin = {
96 true,
97 ['<C-d>'] = 'preview-page-down',
98 ['<C-u>'] = 'preview-page-up',
99 },
100 fzf = {
101 true,
102 ['ctrl-d'] = 'preview-page-down',
103 ['ctrl-u'] = 'preview-page-up',
104 ['ctrl-q'] = 'select-all+accept',
105 },
106 },
107 actions = {
108 files = {
109 ['enter'] = actions.file_edit_or_qf,
110 ['ctrl-x'] = actions.file_split,
111 ['ctrl-v'] = actions.file_vsplit,
112 ['ctrl-t'] = actions.file_tabedit,
113 ['alt-q'] = actions.file_sel_to_qf,
114 },
115 },
116 }
117
118 -- https://github.com/ibhagwan/fzf-lua?tab=readme-ov-file#highlight-groups
119 vim.api.nvim_set_hl(0, 'FzfLuaBorder', { fg = '#54546D' })
120 vim.api.nvim_set_hl(0, 'FzfLuaDirPart', { fg = '#8DA2C2', italic = true })
121 vim.api.nvim_set_hl(0, 'FzfLuaFilePart', { fg = '#7CB879', bold = true })
122
123 local fzf = require 'fzf-lua'
124 fzf.register_ui_select()
125 fzf.setup(opts)
126
127 local bind_opts = { noremap = true, silent = true }
128
129 local bind = function(keys, func, desc, mode)
130 vim.keymap.set(mode or 'n', keys, func, vim.tbl_extend('force', bind_opts, { desc = desc }))
131 end
132
133 bind('<leader>fzf', fzf.builtin, 'fzf ❤️')
134 bind('<leader>ff', fzf.resume, 'Resume Previous fzf Search')
135
136 -- Files
137 bind('<A-f>', fzf.files, 'Find Files')
138 bind('<leader>F', function()
139 fzf.files {
140 cwd = vim.fn.expand '%:h',
141 -- This command uses a regex to find only files in the top-level
142 -- directory, which solves both the recursion and './' prefix issues.
143 cmd = 'fd --type f --hidden --max-depth 2',
144 }
145 end, 'Find Files (Buffer Dir, Non-Recursive)')
146 bind('<leader>f/', function()
147 fzf.files { cwd = '/' }
148 end, 'Search root / directory')
149 bind('<leader>fh', function()
150 fzf.files { cwd = os.getenv 'home', hidden = true }
151 end, 'Search $HOME directory')
152 bind('<leader>fm', function()
153 fzf.files { cwd = '$HOME/notes' }
154 end, 'Search $HOME/notes directory')
155 bind('<leader>fn', function()
156 fzf.files { cwd = vim.fn.stdpath 'config' }
157 end, 'Search $HOME/.config/nvim directory')
158
159 -- Grep
160 bind('<A-g>', with_horizontal_layout(fzf.live_grep), 'Grep')
161 bind('<leader>fM', function()
162 fzf.live_grep_native { cwd = '$HOME/notes' }
163 end, 'Grep Notes')
164 bind('<A-/>', fzf.blines, 'Buffer Lines')
165 bind('<leader>gw', fzf.grep_cword, 'Grep Word')
166 bind('<leader>fc', fzf.grep_cword, 'Grep Word (Alt)')
167 bind('<leader>f.', fzf.grep_cWORD, 'Grep WORD')
168 bind('<leader>ft', '<cmd>TodoFzfLua<CR>', 'Search TODOs')
169
170 -- Buffers / Recents
171 bind('<leader><leader>', fzf.buffers, 'Buffers')
172 bind('<leader>f,', fzf.oldfiles, 'Recent Files')
173
174 -- Git
175 bind('<leader>gca', fzf.git_commits, 'Git Commits')
176 bind('<leader>gh', fzf.git_bcommits, 'Git Buffer Commits')
177
178 -- Misc
179 bind('<leader>K', fzf.keymaps, 'Keymaps')
180 bind('<leader>fd', with_horizontal_layout(fzf.diagnostics_document), 'Document Diagnostics')
181 bind('<leader>fD', with_horizontal_layout(fzf.diagnostics_workspace), 'Workspace Diagnostics')
182 bind('<leader>fq', fzf.quickfix, 'Quickfix List')
183 bind('<leader>H', fzf.help_tags, 'Help Tags')
184 bind('<leader>mar', fzf.marks, 'Marks')
185 bind('<leader>e', fzf.zoxide, 'Zoxide')
186 bind('<leader>fs', function()
187 fzf.spell_suggest {
188 winopts = {
189 height = 0.4,
190 width = 0.5,
191 row = 1, -- relative to cursor
192 col = 0,
193 relative = 'cursor',
194 preview = { hidden = 'hidden' },
195 },
196 }
197 end, 'Spelling Suggest (Cursor)')
198 end,
199}