summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/builtin.lua83
-rw-r--r--lua/telescope/make_entry.lua107
-rw-r--r--lua/telescope/pickers.lua15
-rw-r--r--lua/telescope/pickers/entry_display.lua100
-rw-r--r--lua/telescope/utils.lua12
5 files changed, 303 insertions, 14 deletions
diff --git a/lua/telescope/builtin.lua b/lua/telescope/builtin.lua
index e90797d..d4030ae 100644
--- a/lua/telescope/builtin.lua
+++ b/lua/telescope/builtin.lua
@@ -24,14 +24,13 @@ if 2 > vim.o.report then
end
--- TODO: Give some bonus weight to files we've picked before
--- TODO: Give some bonus weight to oldfiles
-
local actions = require('telescope.actions')
local finders = require('telescope.finders')
+local log = require('telescope.log')
local make_entry = require('telescope.make_entry')
-local previewers = require('telescope.previewers')
+local path = require('telescope.path')
local pickers = require('telescope.pickers')
+local previewers = require('telescope.previewers')
local sorters = require('telescope.sorters')
local utils = require('telescope.utils')
@@ -46,11 +45,17 @@ local builtin = {}
builtin.git_files = function(opts)
opts = opts or {}
+ local show_untracked = utils.get_default(opts.show_untracked, true)
+
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
else
--- Find root of git directory and remove trailing newline characters
- opts.cwd = string.gsub(vim.fn.system("git rev-parse --show-toplevel"), '[\n\r]+', '')
+ opts.cwd = vim.fn.systemlist("git rev-parse --show-toplevel")[1]
+
+ if not vim.fn.isdirectory(opts.cwd) then
+ error("Not a working directory for git_files:", opts.cwd)
+ end
end
-- By creating the entry maker after the cwd options,
@@ -60,7 +65,7 @@ builtin.git_files = function(opts)
pickers.new(opts, {
prompt_title = 'Git File',
finder = finders.new_oneshot_job(
- { "git", "ls-tree", "--full-tree", "-r", "--name-only", "HEAD" },
+ { "git", "ls-files", "--exclude-standard", "--cached", show_untracked and "--others" },
opts
),
previewer = previewers.cat.new(opts),
@@ -412,6 +417,72 @@ builtin.command_history = function(opts)
}):find()
end
+builtin.vim_options = function(opts)
+ opts = opts or {}
+
+ -- Load vim options.
+ local vim_opts = loadfile(utils.data_directory() .. path.separator .. 'options' .. path.separator .. 'options.lua')().options
+
+ pickers.new(opts, {
+ prompt = 'options',
+ finder = finders.new_table {
+ results = vim_opts,
+ entry_maker = make_entry.gen_from_vimoptions(opts),
+ },
+ -- TODO: previewer for Vim options
+ -- previewer = previewers.help.new(opts),
+ sorter = sorters.get_fzy_sorter(),
+ attach_mappings = function(prompt_bufnr, map)
+ local edit_option = function()
+ local selection = actions.get_selected_entry(prompt_bufnr)
+ local esc = ""
+
+
+ if vim.fn.mode() == "i" then
+ -- TODO: don't make this local
+ esc = vim.api.nvim_replace_termcodes("<esc>", true, false, true)
+ end
+
+ -- TODO: Make this actually work.
+
+ -- actions.close(prompt_bufnr)
+ -- vim.api.nvim_win_set_var(vim.fn.nvim_get_current_win(), "telescope", 1)
+ -- print(prompt_bufnr)
+ -- print(vim.fn.bufnr())
+ -- vim.cmd([[ autocmd BufEnter <buffer> ++nested ++once startinsert!]])
+ -- print(vim.fn.winheight(0))
+
+ -- local prompt_winnr = vim.fn.getbufinfo(prompt_bufnr)[1].windows[1]
+ -- print(prompt_winnr)
+
+ -- local float_opts = {}
+ -- float_opts.relative = "editor"
+ -- float_opts.anchor = "sw"
+ -- float_opts.focusable = false
+ -- float_opts.style = "minimal"
+ -- float_opts.row = vim.api.nvim_get_option("lines") - 2 -- TODO: include `cmdheight` and `laststatus` in this calculation
+ -- float_opts.col = 2
+ -- float_opts.height = 10
+ -- float_opts.width = string.len(selection.last_set_from)+15
+ -- local buf = vim.fn.nvim_create_buf(false, true)
+ -- vim.fn.nvim_buf_set_lines(buf, 0, 0, false, {"default value: abcdef", "last set from: " .. selection.last_set_from})
+ -- local status_win = vim.fn.nvim_open_win(buf, false, float_opts)
+ -- -- vim.api.nvim_win_set_option(status_win, "winblend", 100)
+ -- vim.api.nvim_win_set_option(status_win, "winhl", "Normal:PmenuSel")
+ -- -- vim.api.nvim_set_current_win(status_win)
+ -- vim.cmd[[redraw!]]
+ -- vim.cmd("autocmd CmdLineLeave : ++once echom 'beep'")
+ vim.api.nvim_feedkeys(string.format("%s:set %s=%s", esc, selection.name, selection.current_value), "m", true)
+ end
+
+ map('i', '<CR>', edit_option)
+ map('n', '<CR>', edit_option)
+
+ return true
+ end
+ }):find()
+end
+
builtin.help_tags = function(opts)
opts = opts or {}
diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua
index 76e5275..7707122 100644
--- a/lua/telescope/make_entry.lua
+++ b/lua/telescope/make_entry.lua
@@ -1,6 +1,7 @@
local has_devicons, devicons = pcall(require, 'nvim-web-devicons')
local conf = require('telescope.config').values
+local entry_display = require('telescope.pickers.entry_display')
local path = require('telescope.path')
local utils = require('telescope.utils')
@@ -465,4 +466,110 @@ function make_entry.gen_from_marks(_)
end
end
+function make_entry.gen_from_vimoptions(opts)
+ -- TODO: Can we just remove this from `options.lua`?
+ function N_(s)
+ return s
+ end
+
+ local process_one_opt = function(o)
+ local ok, value_origin
+
+ local option = {
+ name = "",
+ description = "",
+ current_value = "",
+ default_value = "",
+ value_type = "",
+ set_by_user = false,
+ last_set_from = "",
+ }
+
+ local is_global = false
+ for _, v in ipairs(o.scope) do
+ if v == "global" then
+ is_global = true
+ end
+ end
+
+ if not is_global then
+ return
+ end
+
+ if is_global then
+ option.name = o.full_name
+
+ ok, option.current_value = pcall(vim.api.nvim_get_option, o.full_name)
+ if not ok then
+ return
+ end
+
+ local str_funcname = o.short_desc()
+ option.description = assert(loadstring("return " .. str_funcname))()
+ -- if #option.description > opts.desc_col_length then
+ -- opts.desc_col_length = #option.description
+ -- end
+
+ if o.defaults ~= nil then
+ option.default_value = o.defaults.if_true.vim or o.defaults.if_true.vi
+ end
+
+ if type(option.default_value) == "function" then
+ option.default_value = "Macro: " .. option.default_value()
+ end
+
+ option.value_type = (type(option.current_value) == "boolean" and "bool" or type(option.current_value))
+
+ if option.current_value ~= option.default_value then
+ option.set_by_user = true
+ value_origin = vim.fn.execute("verbose set " .. o.full_name .. "?")
+ if string.match(value_origin, "Last set from") then
+ -- TODO: parse file and line number as separate items
+ option.last_set_from = value_origin:gsub("^.*Last set from ", "")
+ end
+ end
+
+ return option
+ end
+ end
+
+ -- TODO: don't call this 'line'
+ local displayer = entry_display.create {
+ separator = "│",
+ items = {
+ { width = 25 },
+ { width = 50 },
+ { remaining = true },
+ },
+ }
+
+ local make_display = function(entry)
+
+ return displayer {
+ entry.name,
+ string.format(
+ "[%s] %s",
+ entry.value_type,
+ utils.display_termcodes(tostring(entry.current_value))),
+ entry.description,
+ }
+ end
+
+ return function(line)
+ local entry = process_one_opt(line)
+ if not entry then
+ return
+ end
+
+ entry.valid = true
+ entry.display = make_display
+ entry.value = line
+ entry.ordinal = line.full_name
+ -- entry.raw_value = d.raw_value
+ -- entry.last_set_from = d.last_set_from
+
+ return entry
+ end
+end
+
return make_entry
diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua
index d4b5d71..fea687d 100644
--- a/lua/telescope/pickers.lua
+++ b/lua/telescope/pickers.lua
@@ -7,12 +7,14 @@ local actions = require('telescope.actions')
local config = require('telescope.config')
local debounce = require('telescope.debounce')
local resolve = require('telescope.config.resolve')
-local layout_strategies = require('telescope.pickers.layout_strategies')
local log = require('telescope.log')
local mappings = require('telescope.mappings')
local state = require('telescope.state')
local utils = require('telescope.utils')
+local layout_strategies = require('telescope.pickers.layout_strategies')
+local entry_display = require('telescope.pickers.entry_display')
+
local EntryManager = require('telescope.entry_manager')
local get_default = utils.get_default
@@ -307,7 +309,9 @@ function Picker:find()
local results_win, results_opts = popup.create('', popup_opts.results)
local results_bufnr = a.nvim_win_get_buf(results_win)
+
self.results_bufnr = results_bufnr
+ self.results_win = results_win
-- TODO: Should probably always show all the line for results win, so should implement a resize for the windows
a.nvim_win_set_option(results_win, 'wrap', false)
@@ -785,13 +789,8 @@ function Picker:entry_adder(index, entry, score)
return
end
- local display, display_highlights
- if type(entry.display) == 'function' then
- self:_increment("display_fn")
- display, display_highlights = entry:display()
- elseif type(entry.display) == 'string' then
- display = entry.display
- else
+ local display, display_highlights = entry_display.resolve(self, entry)
+ if not display then
log.info("Weird entry", entry)
return
end
diff --git a/lua/telescope/pickers/entry_display.lua b/lua/telescope/pickers/entry_display.lua
new file mode 100644
index 0000000..c661b89
--- /dev/null
+++ b/lua/telescope/pickers/entry_display.lua
@@ -0,0 +1,100 @@
+local log = require('telescope.log')
+
+local entry_display = {}
+
+-- index are used to determine the correct order
+-- elements = {
+-- [1] = { element, max width }, -- max width should be greater than 0
+-- [2] = { a, 0 } -- Use 0 to disable max width
+-- [3] = { b, 0 } -- If b is nil, skip this column, should skip column for all rows
+-- },
+-- separator = " " -- either arbitrary string, when you wanna use the same separator between all elements
+-- separator = { " ", ":" } -- or table, where [1] is separator between elements[1] and elements[2], etc
+
+-- TODO: Remove this and move ONLY to create method.
+
+local table_format = function(picker, elements, separator)
+ -- TODO: Truncate...
+ local win_width = vim.api.nvim_win_get_width(picker.results_win)
+
+ local output = ""
+ for k, v in ipairs(elements) do
+ local text = v[1]
+ local width = v[2]
+ if text ~= nil then
+ if k > 1 then
+ output = output .. (type(separator) == "table" and separator[k - 1] or separator)
+ end
+ if width then
+ if width == 0 then
+ output = output .. string.format("%s", text)
+ elseif width < 1 then
+ output = output .. string.format("%-" .. math.floor(width * win_width) .. "s", text)
+ else
+ output = output .. string.format("%-" .. width .."s", text)
+ end
+ else
+ output = output .. text
+ end
+ end
+ end
+ return output
+end
+
+local function truncate(str, len)
+ -- TODO: This doesn't handle multi byte chars...
+ if vim.fn.strdisplaywidth(str) > len - 1 then
+ str = str:sub(1, len)
+ str = str .. "…"
+ end
+ return str
+end
+
+entry_display.create = function(configuration)
+ local generator = {}
+ for _, v in ipairs(configuration.items) do
+ if v.width then
+ local justify = not v.right_justify and "-" or ""
+ local format_str = "%" .. justify .. v.width .. "s"
+ table.insert(generator, function(item)
+ return string.format(format_str, truncate(item, v.width))
+ end)
+ else
+ table.insert(generator, function(item)
+ return item
+ end)
+ end
+ end
+
+ return function(self, picker)
+ local results = {}
+ for k, v in ipairs(self) do
+ table.insert(results, generator[k](v, picker))
+ end
+
+ return table.concat(results, configuration.separator or "│")
+ end
+end
+
+
+entry_display.resolve = function(self, entry)
+ local display, display_highlights
+ if type(entry.display) == 'function' then
+ self:_increment("display_fn")
+ display, display_highlights = entry:display(self)
+
+ if type(display) == 'string' then
+ return display, display_highlights
+ end
+ else
+ display = entry.display
+ end
+
+ if type(display) == 'string' then
+ return display, display_highlights
+ elseif type(display) == 'table' then
+ return table_format(self, display, "│"), display_highlights
+ end
+end
+
+return entry_display
diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua
index 58d8183..1daea57 100644
--- a/lua/telescope/utils.lua
+++ b/lua/telescope/utils.lua
@@ -178,4 +178,16 @@ function utils.max_split(s, pattern, maxsplit)
return t
end
+
+function utils.data_directory()
+ local sourced_file = require('plenary.debug_utils').sourced_filepath()
+ local base_directory = vim.fn.fnamemodify(sourced_file, ":h:h:h")
+
+ return base_directory .. pathlib.separator .. 'data' .. pathlib.separator
+end
+
+function utils.display_termcodes(str)
+ return str:gsub(string.char(9), "<TAB>"):gsub("", "<C-F>"):gsub(" ", "<Space>")
+end
+
return utils