Get simple rg example to work
This commit is contained in:
29
README.md
29
README.md
@@ -2,28 +2,29 @@
|
||||
|
||||
Gaze deeply into unknown regions using the power of the moon.
|
||||
|
||||

|
||||
|
||||
## Goals
|
||||
|
||||
|
||||
pipeline different objects
|
||||
### Pipeline Different Objects
|
||||
|
||||
"finder"
|
||||
- executable: rg, git ls-files, ...
|
||||
- things in lua already
|
||||
- vim things
|
||||
(Please note, this section is still in progress)
|
||||
|
||||
"picker"
|
||||
- fzf
|
||||
- sk
|
||||
- does this always need to be fuzzy?
|
||||
"finder":
|
||||
- executable: rg, git ls-files, ...
|
||||
- things in lua already
|
||||
- vim things
|
||||
|
||||
"picker":
|
||||
- fzf
|
||||
- sk
|
||||
- does this always need to be fuzzy?
|
||||
- you'll map what you want to do with vimscript / lua mappings
|
||||
|
||||
"previewer"
|
||||
- sometimes built-in
|
||||
- sometimes a lua callback
|
||||
|
||||
|
||||
"previewer":
|
||||
- sometimes built-in
|
||||
- sometimes a lua callback
|
||||
|
||||
fzf:
|
||||
- have a list of inputs
|
||||
|
||||
31
lua/telescope/builtin.lua
Normal file
31
lua/telescope/builtin.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
--[[
|
||||
A collection of builtin pipelines for telesceope.
|
||||
|
||||
Meant for both example and for easy startup.
|
||||
--]]
|
||||
|
||||
local Finder = require('telescope.finder')
|
||||
local pickers = require('telescope.pickers')
|
||||
|
||||
local builtin = {}
|
||||
|
||||
builtin.rg_vimgrep = setmetatable({}, {
|
||||
__call = function(t, ...)
|
||||
-- builtin.rg_vimgrep("--type lua function")
|
||||
print(t, ...)
|
||||
end
|
||||
})
|
||||
|
||||
builtin.rg_vimgrep.finder = Finder:new {
|
||||
fn_command = function(prompt)
|
||||
return string.format('rg --vimgrep %s', prompt)
|
||||
end,
|
||||
|
||||
responsive = false
|
||||
}
|
||||
|
||||
builtin.rg_vimgrep.picker = pickers.new {
|
||||
}
|
||||
|
||||
|
||||
return builtin
|
||||
13
lua/telescope/extensions/vimgrep.lua
Normal file
13
lua/telescope/extensions/vimgrep.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
local vimgrep = {}
|
||||
|
||||
vimgrep.parse_line = function(line)
|
||||
local sections = vim.split(line, ":")
|
||||
|
||||
return {
|
||||
filename = sections[1],
|
||||
row = tonumber(sections[2]),
|
||||
col = tonumber(sections[3]),
|
||||
}
|
||||
end
|
||||
|
||||
return vimgrep
|
||||
84
lua/telescope/finders.lua
Normal file
84
lua/telescope/finders.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
local a = vim.api
|
||||
|
||||
local finders = {}
|
||||
|
||||
local Finder = {}
|
||||
Finder.__index = Finder
|
||||
|
||||
--- Create a new finder command
|
||||
---
|
||||
--@param fn_command function The function to call
|
||||
function Finder:new(opts)
|
||||
opts = opts or {}
|
||||
|
||||
-- TODO: Add config for:
|
||||
-- - cwd
|
||||
|
||||
-- TODO:
|
||||
-- - `types`
|
||||
-- job
|
||||
-- pipe
|
||||
-- vim.loop.new_pipe (stdin / stdout). stdout => filter pipe
|
||||
-- rg huge_search | fzf --filter prompt_is > buffer. buffer could do stuff do w/ preview callback
|
||||
-- string
|
||||
-- list
|
||||
-- ...
|
||||
return setmetatable({
|
||||
fn_command = opts.fn_command,
|
||||
responsive = opts.responsive,
|
||||
job_id = -1,
|
||||
}, Finder)
|
||||
end
|
||||
|
||||
function Finder:get_results(win, bufnr, prompt)
|
||||
if self.job_id > 0 then
|
||||
-- Make sure we kill old jobs.
|
||||
vim.fn.jobstop(self.job_id)
|
||||
end
|
||||
|
||||
self.job_id = vim.fn.jobstart(self.fn_command(prompt), {
|
||||
-- TODO: Decide if we want this or don't want this.
|
||||
stdout_buffered = true,
|
||||
|
||||
on_stdout = function(_, data, _)
|
||||
a.nvim_buf_set_lines(bufnr, -1, -1, false, data)
|
||||
end,
|
||||
|
||||
on_exit = function()
|
||||
-- TODO: Add possibility to easily highlight prompt within buffer
|
||||
-- without having to do weird stuff and with it actually working...
|
||||
if false then
|
||||
vim.fn.matchadd("Type", "\\<" .. prompt .. "\\>", 1, -1, {window = win})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--[[
|
||||
local function get_rg_results(bufnr, search_string)
|
||||
local start_time = vim.fn.reltime()
|
||||
|
||||
vim.fn.jobstart(string.format('rg %s', search_string), {
|
||||
cwd = '/home/tj/build/neovim',
|
||||
|
||||
on_stdout = function(job_id, data, event)
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, data)
|
||||
end,
|
||||
|
||||
on_exit = function()
|
||||
print("Finished in: ", vim.fn.reltimestr(vim.fn.reltime(start_time)))
|
||||
end,
|
||||
|
||||
stdout_buffer = true,
|
||||
})
|
||||
end
|
||||
--]]
|
||||
end
|
||||
|
||||
--- Return a new Finder
|
||||
--
|
||||
--@return Finder
|
||||
finders.new = function(...)
|
||||
return Finder:new(...)
|
||||
end
|
||||
|
||||
return finders
|
||||
@@ -1,338 +1,37 @@
|
||||
package.loaded['popup'] = nil
|
||||
package.loaded['popup.border'] = nil
|
||||
package.loaded['popup.init'] = nil
|
||||
|
||||
-- TODO: Debounce preview window maybe
|
||||
-- TODO: Make filters
|
||||
-- "fzf --filter"
|
||||
-- jobstart() -> | fzf --filter "input on prompt"
|
||||
|
||||
local a = vim.api
|
||||
local finders = require('telescope.finders')
|
||||
local pickers = require('telescope.pickers')
|
||||
local previewers = require('telescope.previewers')
|
||||
local state = require('telescope.state')
|
||||
|
||||
local popup = require('popup')
|
||||
local telescope = {
|
||||
finders = finders,
|
||||
pickers = pickers,
|
||||
previewers = previewers,
|
||||
state = state,
|
||||
}
|
||||
|
||||
local telescope = {}
|
||||
function __TelescopeOnLeave(prompt_bufnr)
|
||||
local status = state.get_status(prompt_bufnr)
|
||||
local picker = status.picker
|
||||
|
||||
local ns_telescope = a.nvim_create_namespace('telescope')
|
||||
local ns_telescope_highlight = a.nvim_create_namespace('telescope_highlight')
|
||||
|
||||
local Finder = {}
|
||||
Finder.__index = Finder
|
||||
|
||||
function Finder:new(fn_command)
|
||||
-- TODO: Add config for:
|
||||
-- - cwd
|
||||
|
||||
-- TODO:
|
||||
-- - `types`
|
||||
-- job
|
||||
-- pipe
|
||||
-- vim.loop.new_pipe (stdin / stdout). stdout => filter pipe
|
||||
-- rg huge_search | fzf --filter prompt_is > buffer. buffer could do stuff do w/ preview callback
|
||||
-- string
|
||||
-- list
|
||||
-- ...
|
||||
return setmetatable({
|
||||
fn_command = fn_command,
|
||||
job_id = -1,
|
||||
}, Finder)
|
||||
end
|
||||
|
||||
function Finder:display_results(win, bufnr, prompt)
|
||||
if self.job_id > 0 then
|
||||
-- Make sure we kill old jobs.
|
||||
vim.fn.jobstop(self.job_id)
|
||||
end
|
||||
|
||||
self.job_id = vim.fn.jobstart(self.fn_command(prompt), {
|
||||
-- TODO: Decide if we want this or don't want this.
|
||||
stdout_buffered = true,
|
||||
on_stdout = function(_, data, _)
|
||||
a.nvim_buf_set_lines(bufnr, -1, -1, false, data)
|
||||
end,
|
||||
|
||||
on_exit = function()
|
||||
-- TODO: Add possibility to easily highlight prompt within buffer
|
||||
-- without having to do weird stuff and with it actually working...
|
||||
if false then
|
||||
vim.fn.matchadd("Type", "\\<" .. prompt .. "\\>", 1, -1, {window = win})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--[[
|
||||
local function get_rg_results(bufnr, search_string)
|
||||
local start_time = vim.fn.reltime()
|
||||
|
||||
vim.fn.jobstart(string.format('rg %s', search_string), {
|
||||
cwd = '/home/tj/build/neovim',
|
||||
|
||||
on_stdout = function(job_id, data, event)
|
||||
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, data)
|
||||
end,
|
||||
|
||||
on_exit = function()
|
||||
print("Finished in: ", vim.fn.reltimestr(vim.fn.reltime(start_time)))
|
||||
end,
|
||||
|
||||
stdout_buffer = true,
|
||||
})
|
||||
end
|
||||
--]]
|
||||
end
|
||||
|
||||
local Previewer = {}
|
||||
Previewer.__index = Previewer
|
||||
|
||||
function Previewer:new(fn)
|
||||
return setmetatable({
|
||||
fn = fn,
|
||||
}, Previewer)
|
||||
end
|
||||
|
||||
local picker_finders = {}
|
||||
|
||||
local Picker = {}
|
||||
Picker.__index = Picker
|
||||
|
||||
function Picker:new(opts)
|
||||
opts = opts or {}
|
||||
return setmetatable({
|
||||
filter = opts.filter,
|
||||
previewer = opts.previewer,
|
||||
maps = opts.maps,
|
||||
}, Picker)
|
||||
end
|
||||
|
||||
local hack_status = {}
|
||||
|
||||
local previewers = {}
|
||||
|
||||
function Picker:find(finder)
|
||||
local prompt_string = 'MUNITER > '
|
||||
-- Create three windows:
|
||||
-- 1. Prompt window
|
||||
-- 2. Options window
|
||||
-- 3. Preview window
|
||||
|
||||
local width = 100
|
||||
local col = 10
|
||||
local prompt_line = 50
|
||||
|
||||
local result_height = 25
|
||||
local prompt_height = 1
|
||||
|
||||
-- TODO: Add back the borders after fixing some stuff in popup.nvim
|
||||
local results_win = popup.create('', {
|
||||
height = result_height,
|
||||
minheight = result_height,
|
||||
width = width,
|
||||
line = prompt_line - 2 - result_height,
|
||||
col = col,
|
||||
-- border = {},
|
||||
enter = false,
|
||||
})
|
||||
local results_bufnr = a.nvim_win_get_buf(results_win)
|
||||
picker_finders[results_bufnr] = finder
|
||||
|
||||
local preview_win = popup.create('', {
|
||||
height = result_height + prompt_height + 4,
|
||||
minheight = result_height + prompt_height + 4,
|
||||
width = 100,
|
||||
line = prompt_line - 2 - result_height,
|
||||
col = col + width + 2,
|
||||
-- border = {},
|
||||
enter = false,
|
||||
highlight = false,
|
||||
})
|
||||
local preview_bufnr = a.nvim_win_get_buf(preview_win)
|
||||
|
||||
-- TODO: For some reason, highlighting is kind of weird on these windows.
|
||||
-- It may actually be my colorscheme tho...
|
||||
a.nvim_win_set_option(preview_win, 'winhl', '')
|
||||
|
||||
-- TODO: We need to center this and make it prettier...
|
||||
local prompt_win = popup.create('', {
|
||||
height = prompt_height,
|
||||
width = width,
|
||||
line = prompt_line,
|
||||
col = col,
|
||||
border = {},
|
||||
})
|
||||
local prompt_bufnr = a.nvim_win_get_buf(prompt_win)
|
||||
|
||||
a.nvim_buf_set_option(prompt_bufnr, 'buftype', 'prompt')
|
||||
vim.fn.prompt_setprompt(prompt_bufnr, prompt_string)
|
||||
|
||||
-- TODO: Please use the cool autocmds once you get off your lazy bottom and finish the PR ;)
|
||||
local autocmd_string = string.format(
|
||||
[[ autocmd TextChanged,TextChangedI <buffer> :lua __TelescopeOnChange(%s, "%s", %s, %s)]],
|
||||
prompt_bufnr,
|
||||
prompt_string,
|
||||
results_bufnr,
|
||||
results_win)
|
||||
|
||||
local buf_close = string.format(
|
||||
[[ autocmd BufLeave <buffer> :bd! %s ]],
|
||||
prompt_bufnr)
|
||||
|
||||
local results_close = string.format(
|
||||
[[ autocmd BufLeave <buffer> :call nvim_win_close(%s, v:true) ]],
|
||||
results_win)
|
||||
|
||||
local preview_close = string.format(
|
||||
[[ autocmd BufLeave <buffer> :call nvim_win_close(%s, v:true) ]],
|
||||
preview_win)
|
||||
|
||||
vim.cmd([[augroup PickerCommands]])
|
||||
vim.cmd([[ au!]])
|
||||
vim.cmd( autocmd_string)
|
||||
vim.cmd( buf_close)
|
||||
vim.cmd( results_close)
|
||||
vim.cmd( preview_close)
|
||||
vim.cmd([[augroup END]])
|
||||
|
||||
previewers[prompt_bufnr] = self.previewer
|
||||
|
||||
-- TODO: Clear this hack status stuff when closing
|
||||
hack_status[prompt_bufnr] = {
|
||||
prompt_bufnr = prompt_bufnr,
|
||||
prompt_win = prompt_win,
|
||||
results_bufnr = results_bufnr,
|
||||
results_win = results_win,
|
||||
preview_bufnr = preview_bufnr,
|
||||
preview_win = preview_win,
|
||||
}
|
||||
|
||||
local function default_mapper(map_key, table_key)
|
||||
a.nvim_buf_set_keymap(
|
||||
prompt_bufnr,
|
||||
'i',
|
||||
map_key,
|
||||
string.format(
|
||||
[[<C-O>:lua __TelescopeMapping(%s, %s, '%s')<CR>]],
|
||||
prompt_bufnr,
|
||||
results_bufnr,
|
||||
table_key
|
||||
),
|
||||
{
|
||||
silent = true,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
default_mapper('<c-n>', 'control-n')
|
||||
default_mapper('<c-p>', 'control-p')
|
||||
default_mapper('<CR>', 'enter')
|
||||
|
||||
vim.cmd [[startinsert]]
|
||||
end
|
||||
|
||||
-- TODO: All lower case mappings
|
||||
local telescope_selections = {}
|
||||
|
||||
local function update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
a.nvim_buf_clear_namespace(results_bufnr, ns_telescope_highlight, 0, -1)
|
||||
a.nvim_buf_add_highlight(
|
||||
results_bufnr,
|
||||
ns_telescope_highlight,
|
||||
'Error',
|
||||
row,
|
||||
0,
|
||||
-1
|
||||
)
|
||||
|
||||
telescope_selections[prompt_bufnr] = row
|
||||
|
||||
if previewers[prompt_bufnr] then
|
||||
vim.g.got_here = true
|
||||
local status = hack_status[prompt_bufnr]
|
||||
previewers[prompt_bufnr].fn(
|
||||
status.preview_win,
|
||||
status.preview_bufnr,
|
||||
status.results_bufnr,
|
||||
row
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local mappings = {}
|
||||
|
||||
-- TODO: Refactor this to use shared code.
|
||||
-- TODO: Move from top to bottom, etc.
|
||||
-- TODO: It seems like doing this brings us back to the beginning of the prompt, which is not great.
|
||||
mappings["control-n"] = function(prompt_bufnr, results_bufnr)
|
||||
if telescope_selections[prompt_bufnr] == nil then
|
||||
telescope_selections[prompt_bufnr] = 0
|
||||
end
|
||||
|
||||
local row = telescope_selections[prompt_bufnr] + 1
|
||||
update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
end
|
||||
|
||||
mappings["control-p"] = function(prompt_bufnr, results_bufnr)
|
||||
if telescope_selections[prompt_bufnr] == nil then
|
||||
telescope_selections[prompt_bufnr] = 0
|
||||
end
|
||||
|
||||
local row = telescope_selections[prompt_bufnr] - 1
|
||||
update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
end
|
||||
|
||||
mappings["enter"] = function(prompt_bufnr, results_bufnr)
|
||||
local extmark = a.nvim_buf_get_extmarks(
|
||||
results_bufnr,
|
||||
ns_telescope_highlight,
|
||||
0,
|
||||
-1,
|
||||
{}
|
||||
)
|
||||
|
||||
print(vim.inspect(extmark))
|
||||
end
|
||||
|
||||
function __TelescopeMapping(prompt_bufnr, results_bufnr, characters)
|
||||
if mappings[characters] then
|
||||
mappings[characters](prompt_bufnr, results_bufnr)
|
||||
end
|
||||
picker:close_windows(status)
|
||||
end
|
||||
|
||||
-- TODO: Probably could attach this with nvim_buf_attach, and then I don't have to do the ugly global function stuff
|
||||
function __TelescopeOnChange(bufnr, prompt, results_bufnr, results_win)
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)[1]
|
||||
function __TelescopeOnChange(prompt_bufnr, prompt, results_bufnr, results_win)
|
||||
local line = vim.api.nvim_buf_get_lines(prompt_bufnr, 0, -1, false)[1]
|
||||
local prompt_input = string.sub(line, #prompt + 1)
|
||||
print(string.format("|%s|", prompt_input))
|
||||
|
||||
local finder = picker_finders[results_bufnr]
|
||||
a.nvim_buf_set_lines(results_bufnr, 0, -1, false, {})
|
||||
finder:display_results(results_win, results_bufnr, prompt_input)
|
||||
local status = state.get_status(prompt_bufnr)
|
||||
local finder = status.finder
|
||||
|
||||
vim.api.nvim_buf_set_lines(results_bufnr, 0, -1, false, {})
|
||||
local results = finder:get_results(results_win, results_bufnr, prompt_input)
|
||||
end
|
||||
|
||||
-- Uhh, finder should probably just GET the results
|
||||
-- and then update some table.
|
||||
-- When updating the table, we should call filter on those items
|
||||
-- and then only display ones that pass the filter
|
||||
local f = Finder:new(function(prompt)
|
||||
return string.format('rg %s', prompt)
|
||||
end)
|
||||
|
||||
local p = Picker:new {
|
||||
previewer = Previewer:new(function(preview_win, preview_bufnr, results_bufnr, row)
|
||||
local line = a.nvim_buf_get_lines(results_bufnr, row, row + 1, false)[1]
|
||||
local file_name = vim.split(line, ":")[1]
|
||||
|
||||
-- print(file_name)
|
||||
-- vim.fn.termopen(
|
||||
-- string.format("bat --color=always --style=grid %s"),
|
||||
local file_bufnr = vim.fn.bufnr(file_name, true)
|
||||
-- TODO: We should probably call something like this because we're not always getting highlight and all that stuff.
|
||||
-- api.nvim_command('doautocmd filetypedetect BufRead ' .. vim.fn.fnameescape(filename))
|
||||
a.nvim_win_set_buf(preview_win, file_bufnr)
|
||||
end)
|
||||
}
|
||||
p:find(f)
|
||||
|
||||
-- TODO: Make filters
|
||||
-- "fzf --filter"
|
||||
-- jobstart() -> | fzf --filter "input on prompt"
|
||||
-- function Filter:new(command)
|
||||
-- end
|
||||
|
||||
return telescope
|
||||
|
||||
124
lua/telescope/mappings.lua
Normal file
124
lua/telescope/mappings.lua
Normal file
@@ -0,0 +1,124 @@
|
||||
-- TODO: Customize keymap
|
||||
local a = vim.api
|
||||
local ns_telescope_selection = a.nvim_create_namespace('telescope_selection')
|
||||
|
||||
local state = require('telescope.state')
|
||||
|
||||
local mappings = {}
|
||||
local keymap = {}
|
||||
local telescope_selections = {}
|
||||
|
||||
mappings.set_keymap = function(prompt_bufnr, results_bufnr)
|
||||
local function default_mapper(map_key, table_key)
|
||||
a.nvim_buf_set_keymap(
|
||||
prompt_bufnr,
|
||||
'i',
|
||||
map_key,
|
||||
string.format(
|
||||
[[<C-O>:lua __TelescopeMapping(%s, %s, '%s')<CR>]],
|
||||
prompt_bufnr,
|
||||
results_bufnr,
|
||||
table_key
|
||||
),
|
||||
{
|
||||
silent = true,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
default_mapper('<c-n>', 'control-n')
|
||||
default_mapper('<c-p>', 'control-p')
|
||||
default_mapper('<CR>', 'enter')
|
||||
end
|
||||
|
||||
local function update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
local status = state.get_status(prompt_bufnr)
|
||||
|
||||
a.nvim_buf_clear_namespace(results_bufnr, ns_telescope_selection, 0, -1)
|
||||
a.nvim_buf_add_highlight(
|
||||
results_bufnr,
|
||||
ns_telescope_selection,
|
||||
'Error',
|
||||
row,
|
||||
0,
|
||||
-1
|
||||
)
|
||||
|
||||
telescope_selections[prompt_bufnr] = row
|
||||
|
||||
if status.previewer then
|
||||
vim.g.got_here = true
|
||||
|
||||
status.previewer.fn(
|
||||
status.preview_win,
|
||||
status.preview_bufnr,
|
||||
status.results_bufnr,
|
||||
row
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function __TelescopeMapping(prompt_bufnr, results_bufnr, characters)
|
||||
if keymap[characters] then
|
||||
keymap[characters](prompt_bufnr, results_bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: Refactor this to use shared code.
|
||||
-- TODO: Move from top to bottom, etc.
|
||||
-- TODO: It seems like doing this brings us back to the beginning of the prompt, which is not great.
|
||||
keymap["control-n"] = function(prompt_bufnr, results_bufnr)
|
||||
if telescope_selections[prompt_bufnr] == nil then
|
||||
telescope_selections[prompt_bufnr] = 0
|
||||
end
|
||||
|
||||
local row = telescope_selections[prompt_bufnr] + 1
|
||||
update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
end
|
||||
|
||||
keymap["control-p"] = function(prompt_bufnr, results_bufnr)
|
||||
if telescope_selections[prompt_bufnr] == nil then
|
||||
telescope_selections[prompt_bufnr] = 0
|
||||
end
|
||||
|
||||
local row = telescope_selections[prompt_bufnr] - 1
|
||||
update_current_selection(prompt_bufnr, results_bufnr, row)
|
||||
end
|
||||
|
||||
keymap["enter"] = function(prompt_bufnr, results_bufnr)
|
||||
local extmark = a.nvim_buf_get_extmarks(
|
||||
results_bufnr,
|
||||
ns_telescope_selection,
|
||||
0,
|
||||
-1,
|
||||
{}
|
||||
)
|
||||
|
||||
local row = extmark[1][2]
|
||||
if row == nil then
|
||||
print("Could not do anything...")
|
||||
return
|
||||
else
|
||||
local line = a.nvim_buf_get_lines(results_bufnr, row, row + 1, false)[1]
|
||||
if line == nil then
|
||||
print("Could not do anything with blank line...")
|
||||
return
|
||||
end
|
||||
|
||||
local sections = vim.split(line, ":")
|
||||
|
||||
local filename = sections[1]
|
||||
local row = tonumber(sections[2])
|
||||
local col = tonumber(sections[3])
|
||||
|
||||
vim.cmd(string.format([[bdelete! %s]], prompt_bufnr))
|
||||
|
||||
local bufnr = vim.fn.bufnr(filename, true)
|
||||
a.nvim_set_current_buf(bufnr)
|
||||
a.nvim_buf_set_option(bufnr, 'buflisted', true)
|
||||
a.nvim_win_set_cursor(0, {row, col})
|
||||
end
|
||||
end
|
||||
|
||||
return mappings
|
||||
180
lua/telescope/pickers.lua
Normal file
180
lua/telescope/pickers.lua
Normal file
@@ -0,0 +1,180 @@
|
||||
local a = vim.api
|
||||
local popup = require('popup')
|
||||
|
||||
local mappings = require('telescope.mappings')
|
||||
local state = require('telescope.state')
|
||||
|
||||
local pickers = {}
|
||||
|
||||
local Picker = {}
|
||||
Picker.__index = Picker
|
||||
|
||||
function Picker:new(opts)
|
||||
opts = opts or {}
|
||||
return setmetatable({
|
||||
filter = opts.filter,
|
||||
previewer = opts.previewer,
|
||||
maps = opts.maps,
|
||||
}, Picker)
|
||||
end
|
||||
|
||||
|
||||
function Picker:find(finder)
|
||||
local prompt_string = 'Find File'
|
||||
-- Create three windows:
|
||||
-- 1. Prompt window
|
||||
-- 2. Options window
|
||||
-- 3. Preview window
|
||||
|
||||
local width = 100
|
||||
local col = 10
|
||||
local prompt_line = 50
|
||||
|
||||
local result_height = 25
|
||||
local prompt_height = 1
|
||||
|
||||
-- TODO: Add back the borders after fixing some stuff in popup.nvim
|
||||
local results_win, results_opts = popup.create('', {
|
||||
height = result_height,
|
||||
minheight = result_height,
|
||||
width = width,
|
||||
line = prompt_line - 2 - result_height,
|
||||
col = col,
|
||||
border = {},
|
||||
enter = false,
|
||||
})
|
||||
local results_bufnr = a.nvim_win_get_buf(results_win)
|
||||
|
||||
local preview_win, preview_opts = popup.create('', {
|
||||
height = result_height + prompt_height + 2,
|
||||
minheight = result_height + prompt_height + 2,
|
||||
width = 100,
|
||||
line = prompt_line - 2 - result_height,
|
||||
col = col + width + 2,
|
||||
border = {},
|
||||
enter = false,
|
||||
highlight = false,
|
||||
})
|
||||
local preview_bufnr = a.nvim_win_get_buf(preview_win)
|
||||
|
||||
-- TODO: For some reason, highlighting is kind of weird on these windows.
|
||||
-- It may actually be my colorscheme tho...
|
||||
a.nvim_win_set_option(preview_win, 'winhl', 'Normal:Normal')
|
||||
|
||||
-- TODO: We need to center this and make it prettier...
|
||||
local prompt_win, prompt_opts = popup.create('', {
|
||||
height = prompt_height,
|
||||
width = width,
|
||||
line = prompt_line,
|
||||
col = col,
|
||||
border = {},
|
||||
title = prompt_string
|
||||
})
|
||||
local prompt_bufnr = a.nvim_win_get_buf(prompt_win)
|
||||
|
||||
-- a.nvim_buf_set_option(prompt_bufnr, 'buftype', 'prompt')
|
||||
-- vim.fn.prompt_setprompt(prompt_bufnr, prompt_string)
|
||||
|
||||
vim.api.nvim_buf_attach(prompt_bufnr, true, {
|
||||
on_lines = vim.schedule_wrap(function(_, _, _, first_line, last_line)
|
||||
local line = vim.api.nvim_buf_get_lines(prompt_bufnr, first_line, last_line, false)[1]
|
||||
|
||||
vim.api.nvim_buf_set_lines(results_bufnr, 0, -1, false, {})
|
||||
local results = finder:get_results(results_win, results_bufnr, line)
|
||||
end),
|
||||
|
||||
on_detach = function(...)
|
||||
-- print("DETACH:", ...)
|
||||
end,
|
||||
})
|
||||
|
||||
-- -- TODO: Please use the cool autocmds once you get off your lazy bottom and finish the PR ;)
|
||||
-- local autocmd_string = string.format(
|
||||
-- [[ autocmd TextChanged,TextChangedI <buffer> :lua __TelescopeOnChange(%s, "%s", %s, %s)]],
|
||||
-- prompt_bufnr,
|
||||
-- '',
|
||||
-- results_bufnr,
|
||||
-- results_win)
|
||||
|
||||
-- TODO: Use WinLeave as well?
|
||||
local on_buf_leave = string.format(
|
||||
[[ autocmd BufLeave <buffer> ++nested ++once :lua __TelescopeOnLeave(%s)]],
|
||||
prompt_bufnr)
|
||||
|
||||
vim.cmd([[augroup PickerInsert]])
|
||||
vim.cmd([[ au!]])
|
||||
vim.cmd( on_buf_leave)
|
||||
vim.cmd([[augroup END]])
|
||||
|
||||
state.set_status(prompt_bufnr, {
|
||||
prompt_bufnr = prompt_bufnr,
|
||||
prompt_win = prompt_win,
|
||||
prompt_border_win = prompt_opts.border.win_id,
|
||||
|
||||
results_bufnr = results_bufnr,
|
||||
results_win = results_win,
|
||||
results_border_win = results_opts.border.win_id,
|
||||
|
||||
preview_bufnr = preview_bufnr,
|
||||
preview_win = preview_win,
|
||||
preview_border_win = preview_opts.border.win_id,
|
||||
|
||||
picker = self,
|
||||
previewer = self.previewer,
|
||||
finder = finder,
|
||||
})
|
||||
|
||||
-- print(vim.inspect(state.get_status(prompt_bufnr)))
|
||||
mappings.set_keymap(prompt_bufnr, results_bufnr)
|
||||
|
||||
vim.cmd [[startinsert]]
|
||||
end
|
||||
|
||||
function Picker:close_windows(status)
|
||||
-- vim.fn['popup#close_win'](state.prompt_win)
|
||||
-- vim.fn['popup#close_win'](state.results_win)
|
||||
-- vim.fn['popup#close_win'](state.preview_win)
|
||||
local prompt_win = status.prompt_win
|
||||
local results_win = status.results_win
|
||||
local preview_win = status.preview_win
|
||||
|
||||
local prompt_border_win = status.prompt_border_win
|
||||
local results_border_win = status.results_border_win
|
||||
local preview_border_win = status.preview_border_win
|
||||
|
||||
local function del_win(name, win_id, force)
|
||||
local file = io.open("/home/tj/test.txt", "a")
|
||||
file:write(string.format("Closing.... %s %s\n", name, win_id))
|
||||
local ok = pcall(vim.api.nvim_win_close, win_id, force)
|
||||
file:write(string.format("OK: %s\n", ok))
|
||||
file:write("...Done\n\n")
|
||||
file:close()
|
||||
end
|
||||
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
del_win("results_win", results_win, true)
|
||||
del_win("preview_win", preview_win, true)
|
||||
|
||||
del_win("prompt_border_win", prompt_border_win, true)
|
||||
del_win("results_border_win", results_border_win, true)
|
||||
del_win("preview_border_win", preview_border_win, true)
|
||||
|
||||
-- vim.cmd(string.format("bdelete! %s", status.prompt_bufnr))
|
||||
|
||||
-- Major hack?? Why do I have to od this.
|
||||
-- Probably because we're currently IN the buffer.
|
||||
-- Should wait to do this until after we're done.
|
||||
vim.defer_fn(function()
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
end, 10)
|
||||
|
||||
state.clear_status(status.prompt_bufnr)
|
||||
end
|
||||
|
||||
|
||||
|
||||
pickers.new = function(...)
|
||||
return Picker:new(...)
|
||||
end
|
||||
|
||||
return pickers
|
||||
16
lua/telescope/previewers.lua
Normal file
16
lua/telescope/previewers.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
local previewers = {}
|
||||
|
||||
local Previewer = {}
|
||||
Previewer.__index = Previewer
|
||||
|
||||
function Previewer:new(fn)
|
||||
return setmetatable({
|
||||
fn = fn,
|
||||
}, Previewer)
|
||||
end
|
||||
|
||||
previewers.new = function(...)
|
||||
return Previewer:new(...)
|
||||
end
|
||||
|
||||
return previewers
|
||||
18
lua/telescope/state.lua
Normal file
18
lua/telescope/state.lua
Normal file
@@ -0,0 +1,18 @@
|
||||
local state = {}
|
||||
|
||||
state._statuses = {}
|
||||
|
||||
--- Set the status for a particular prompt bufnr
|
||||
function state.set_status(prompt_bufnr, status)
|
||||
state._statuses[prompt_bufnr] = status
|
||||
end
|
||||
|
||||
function state.get_status(prompt_bufnr)
|
||||
return state._statuses[prompt_bufnr] or {}
|
||||
end
|
||||
|
||||
function state.clear_status(prompt_bufnr)
|
||||
state.set_status(prompt_bufnr, nil)
|
||||
end
|
||||
|
||||
return state
|
||||
34
media/simple_rg_example.hnt
Normal file
34
media/simple_rg_example.hnt
Normal file
@@ -0,0 +1,34 @@
|
||||
### Simple demo to show the rg stuff
|
||||
## key_delay 1
|
||||
## feed_full
|
||||
|
||||
:e! ./scratch/simple_rg.lua\<CR>
|
||||
:set foldlevel=100\<CR>
|
||||
:luafile %\<CR>
|
||||
|
||||
## pause
|
||||
## key_delay 80
|
||||
|
||||
Finder
|
||||
|
||||
## key_delay 150
|
||||
|
||||
\<c-n>
|
||||
|
||||
## pause
|
||||
\<c-n>
|
||||
|
||||
## pause
|
||||
\<c-n>
|
||||
|
||||
## pause
|
||||
\<cr>
|
||||
|
||||
## pause
|
||||
\<esc>
|
||||
:" Went to the file!\<esc>
|
||||
|
||||
## pause
|
||||
|
||||
## feed_full
|
||||
:qa!\<CR>
|
||||
BIN
media/simple_rg_v1.gif
Normal file
BIN
media/simple_rg_v1.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
41
scratch/simple_rg.lua
Normal file
41
scratch/simple_rg.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
local telescope = require('telescope')
|
||||
|
||||
-- Uhh, finder should probably just GET the results
|
||||
-- and then update some table.
|
||||
-- When updating the table, we should call filter on those items
|
||||
-- and then only display ones that pass the filter
|
||||
local rg_finder = telescope.finders.new {
|
||||
fn_command = function(prompt)
|
||||
return string.format('rg --vimgrep %s', prompt)
|
||||
end,
|
||||
|
||||
responsive = false
|
||||
}
|
||||
|
||||
|
||||
local p = telescope.pickers.new {
|
||||
previewer = telescope.previewers.new(function(preview_win, preview_bufnr, results_bufnr, row)
|
||||
assert(preview_bufnr)
|
||||
|
||||
local line = vim.api.nvim_buf_get_lines(results_bufnr, row, row + 1, false)[1]
|
||||
local file_name = vim.split(line, ":")[1]
|
||||
|
||||
-- print(file_name)
|
||||
-- vim.fn.termopen(
|
||||
-- string.format("bat --color=always --style=grid %s"),
|
||||
-- vim.fn.fnamemodify(file_name, ":p")
|
||||
local bufnr = vim.fn.bufadd(file_name)
|
||||
vim.fn.bufload(bufnr)
|
||||
|
||||
-- TODO: We should probably call something like this because we're not always getting highlight and all that stuff.
|
||||
-- api.nvim_command('doautocmd filetypedetect BufRead ' .. vim.fn.fnameescape(filename))
|
||||
vim.api.nvim_win_set_buf(preview_win, bufnr)
|
||||
vim.api.nvim_win_set_option(preview_win, 'wrap', false)
|
||||
vim.api.nvim_win_set_option(preview_win, 'winhl', 'Normal:Normal')
|
||||
vim.api.nvim_win_set_option(preview_win, 'winblend', 20)
|
||||
vim.api.nvim_win_set_option(preview_win, 'signcolumn', 'no')
|
||||
vim.api.nvim_win_set_option(preview_win, 'foldlevel', 100)
|
||||
end)
|
||||
}
|
||||
p:find(rg_finder)
|
||||
|
||||
Reference in New Issue
Block a user