Merge pull request #1945 from nvim-telescope/dev

full changelog `:help telescope.changelog-1945`
This commit is contained in:
Simon Hauser
2022-07-01 23:29:24 +02:00
committed by GitHub
40 changed files with 3938 additions and 6672 deletions

View File

@@ -299,6 +299,8 @@ Built-in functions. Ready to be bound to any key you like.
| Functions | Description | | Functions | Description |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| |---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `builtin.lsp_references` | Lists LSP references for word under the cursor | | `builtin.lsp_references` | Lists LSP references for word under the cursor |
| `builtin.lsp_incoming_calls` | Lists LSP incoming calls for word under the cursor |
| `builtin.lsp_outgoing_calls` | Lists LSP outgoing calls for word under the cursor |
| `builtin.lsp_document_symbols` | Lists LSP document symbols in the current buffer | | `builtin.lsp_document_symbols` | Lists LSP document symbols in the current buffer |
| `builtin.lsp_workspace_symbols` | Lists LSP document symbols in the current workspace | | `builtin.lsp_workspace_symbols` | Lists LSP document symbols in the current workspace |
| `builtin.lsp_dynamic_workspace_symbols` | Dynamically Lists LSP for all workspace symbols | | `builtin.lsp_dynamic_workspace_symbols` | Dynamically Lists LSP for all workspace symbols |

File diff suppressed because it is too large Load Diff

View File

@@ -142,6 +142,7 @@ telescope.setup({opts}) *telescope.setup()*
- "follow" - "follow"
- "row" - "row"
- "closest" - "closest"
- "none"
*telescope.defaults.scroll_strategy* *telescope.defaults.scroll_strategy*
scroll_strategy: ~ scroll_strategy: ~
@@ -496,8 +497,17 @@ telescope.setup({opts}) *telescope.setup()*
highlighting, which falls back to regex-based highlighting. highlighting, which falls back to regex-based highlighting.
`true`: treesitter highlighting for all available filetypes `true`: treesitter highlighting for all available filetypes
`false`: regex-based highlighting for all filetypes `false`: regex-based highlighting for all filetypes
`table`: table of filetypes for which to attach treesitter `table`: following nvim-treesitters highlighting options:
highlighting It contains two keys:
- enable boolean|table: if boolean, enable all ts
highlighing with that flag,
disable still considered.
Containing a list of filetypes,
that are enabled, disabled
ignored because it doesnt make
any sense in this case.
- disable table: containing a list of filetypes
that are disabled
Default: true Default: true
- msg_bg_fillchar: Character to fill background of unpreviewable buffers with - msg_bg_fillchar: Character to fill background of unpreviewable buffers with
Default: "" Default: ""
@@ -655,6 +665,17 @@ telescope.setup({opts}) *telescope.setup()*
Example: { "%.npz" } -- ignore all npz files Example: { "%.npz" } -- ignore all npz files
See: https://www.lua.org/manual/5.1/manual.html#5.4.1 for more See: https://www.lua.org/manual/5.1/manual.html#5.4.1 for more
information about lua regex information about lua regex
Note: `file_ignore_patterns` will be used in all pickers that have a
file associated. This might lead to the problem that lsp_ pickers
aren't displaying results because they might be ignored by
`file_ignore_patterns`. For example, setting up node_modules as ignored
will never show node_modules in any results, even if you are
interested in lsp_ results.
If you only want `file_ignore_patterns` for `find_files` and
`grep_string`/`live_grep` it is suggested that you setup `gitignore`
and have fd and or ripgrep installed because both tools will not show
`gitignore`d files on default.
Default: nil Default: nil
@@ -809,26 +830,28 @@ builtin.live_grep({opts}) *telescope.builtin.live_grep()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{cwd} (string) root dir to search from (default: {cwd} (string) root dir to search from
cwd, use utils.buffer_dir() to (default: cwd, use
search relative to open buffer) utils.buffer_dir() to search
relative to open buffer)
{grep_open_files} (boolean) if true, restrict search to open {grep_open_files} (boolean) if true, restrict search to open
files only, mutually exclusive with files only, mutually exclusive
`search_dirs` with `search_dirs`
{search_dirs} (table) directory/directories to search in, {search_dirs} (table) directory/directories/files to
mutually exclusive with search, mutually exclusive with
`grep_open_files` `grep_open_files`
{glob_pattern} (string) argument to be used with `--glob`, {glob_pattern} (string|table) argument to be used with
e.g. "*.toml", can use the opposite `--glob`, e.g. "*.toml", can use
"!*.toml" the opposite "!*.toml"
{type_filter} (string) argument to be used with `--type`, {type_filter} (string) argument to be used with
e.g. "rust", see `rg --type-list` `--type`, e.g. "rust", see `rg
{additional_args} (function) function(opts) which returns a table --type-list`
of additional arguments to be passed {additional_args} (function) function(opts) which returns a
on table of additional arguments to
be passed on
{max_results} (number) define a upper result value {max_results} (number) define a upper result value
{disable_coordinates} (boolean) don't show the line & row numbers {disable_coordinates} (boolean) don't show the line & row
(default: false) numbers (default: false)
builtin.grep_string({opts}) *telescope.builtin.grep_string()* builtin.grep_string({opts}) *telescope.builtin.grep_string()*
@@ -843,7 +866,8 @@ builtin.grep_string({opts}) *telescope.builtin.grep_string()*
cwd, use utils.buffer_dir() to cwd, use utils.buffer_dir() to
search relative to open buffer) search relative to open buffer)
{search} (string) the query to search {search} (string) the query to search
{search_dirs} (table) directory/directories to search in {search_dirs} (table) directory/directories/files to
search
{use_regex} (boolean) if true, special characters won't be {use_regex} (boolean) if true, special characters won't be
escaped, allows for using regex escaped, allows for using regex
(default: false) (default: false)
@@ -866,19 +890,25 @@ builtin.find_files({opts}) *telescope.builtin.find_files()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{cwd} (string) root dir to search from (default: cwd, use {cwd} (string) root dir to search from (default:
utils.buffer_dir() to search relative to cwd, use utils.buffer_dir() to
open buffer) search relative to open buffer)
{find_command} (table) command line arguments for `find_files` to {find_command} (function|table) cmd to use for the search. Can be
use for the search, overrides default: a fn(opts) -> tbl (default:
config autodetect)
{follow} (boolean) if true, follows symlinks (i.e. uses `-L` {follow} (boolean) if true, follows symlinks (i.e.
flag for the `find` command) uses `-L` flag for the `find`
{hidden} (boolean) determines whether to show hidden files or command)
not (default: false) {hidden} (boolean) determines whether to show hidden
{no_ignore} (boolean) show files ignored by .gitignore, .ignore, files or not (default: false)
etc. (default: false) {no_ignore} (boolean) show files ignored by .gitignore,
{search_dirs} (table) directory/directories to search in .ignore, etc. (default: false)
{no_ignore_parent} (boolean) show files ignored by .gitignore,
.ignore, etc. in parent dirs.
(default: false)
{search_dirs} (table) directory/directories/files to
search
{search_file} (string) specify a filename to search for
builtin.fd() *telescope.builtin.fd()* builtin.fd() *telescope.builtin.fd()*
@@ -977,7 +1007,7 @@ builtin.git_files({opts}) *telescope.builtin.git_files()*
(default: true) (default: true)
{show_untracked} (boolean) if true, adds `--others` flag to {show_untracked} (boolean) if true, adds `--others` flag to
command and shows untracked files command and shows untracked files
(default: true) (default: false)
{recurse_submodules} (boolean) if true, adds the {recurse_submodules} (boolean) if true, adds the
`--recurse-submodules` flag to command `--recurse-submodules` flag to command
(default: false) (default: false)
@@ -1097,6 +1127,8 @@ builtin.builtin({opts}) *telescope.builtin.builtin()*
Options: ~ Options: ~
{include_extensions} (boolean) if true will show the pickers of the {include_extensions} (boolean) if true will show the pickers of the
installed extensions (default: false) installed extensions (default: false)
{use_default_opts} (boolean) if the selected picker should use its
default options (default: false)
builtin.resume({opts}) *telescope.builtin.resume()* builtin.resume({opts}) *telescope.builtin.resume()*
@@ -1178,8 +1210,10 @@ builtin.quickfix({opts}) *telescope.builtin.quickfix()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default: true) {show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
{nr} (number) specify the quickfix list number {nr} (number) specify the quickfix list number
@@ -1202,8 +1236,10 @@ builtin.loclist({opts}) *telescope.builtin.loclist()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default: true) {show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.oldfiles({opts}) *telescope.builtin.oldfiles()* builtin.oldfiles({opts}) *telescope.builtin.oldfiles()*
@@ -1402,8 +1438,10 @@ builtin.tagstack({opts}) *telescope.builtin.tagstack()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default: true) {show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.jumplist({opts}) *telescope.builtin.jumplist()* builtin.jumplist({opts}) *telescope.builtin.jumplist()*
@@ -1414,8 +1452,10 @@ builtin.jumplist({opts}) *telescope.builtin.jumplist()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default: true) {show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.lsp_references({opts}) *telescope.builtin.lsp_references()* builtin.lsp_references({opts}) *telescope.builtin.lsp_references()*
@@ -1432,6 +1472,34 @@ builtin.lsp_references({opts}) *telescope.builtin.lsp_references()*
{include_current_line} (boolean) include current line (default: {include_current_line} (boolean) include current line (default:
false) false)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename
section (default: 30)
builtin.lsp_incoming_calls({opts}) *telescope.builtin.lsp_incoming_calls()*
Lists LSP incoming calls for word under the cursor, jumps to reference on
`<cr>`
Parameters: ~
{opts} (table) options to pass to the picker
Options: ~
{show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false)
builtin.lsp_outgoing_calls({opts}) *telescope.builtin.lsp_outgoing_calls()*
Lists LSP outgoing calls for word under the cursor, jumps to reference on
`<cr>`
Parameters: ~
{opts} (table) options to pass to the picker
Options: ~
{show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false)
builtin.lsp_definitions({opts}) *telescope.builtin.lsp_definitions()* builtin.lsp_definitions({opts}) *telescope.builtin.lsp_definitions()*
@@ -1443,11 +1511,12 @@ builtin.lsp_definitions({opts}) *telescope.builtin.lsp_definitions()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{jump_type} (string) how to goto definition if there is only {jump_type} (string) how to goto definition if there is only one,
one, values: "tab", "split", "vsplit", values: "tab", "split", "vsplit", "never"
"never" {show_line} (boolean) show results text (default: true)
{ignore_filename} (boolean) dont show filenames (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.lsp_type_definitions({opts}) *telescope.builtin.lsp_type_definitions()* builtin.lsp_type_definitions({opts}) *telescope.builtin.lsp_type_definitions()*
@@ -1459,11 +1528,12 @@ builtin.lsp_type_definitions({opts}) *telescope.builtin.lsp_type_definitions()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{jump_type} (string) how to goto definition if there is only {jump_type} (string) how to goto definition if there is only one,
one, values: "tab", "split", "vsplit", values: "tab", "split", "vsplit", "never"
"never" {show_line} (boolean) show results text (default: true)
{ignore_filename} (boolean) dont show filenames (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.lsp_implementations({opts}) *telescope.builtin.lsp_implementations()* builtin.lsp_implementations({opts}) *telescope.builtin.lsp_implementations()*
@@ -1475,11 +1545,13 @@ builtin.lsp_implementations({opts}) *telescope.builtin.lsp_implementations()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{jump_type} (string) how to goto implementation if there is {jump_type} (string) how to goto implementation if there is only
only one, values: "tab", "split", one, values: "tab", "split", "vsplit",
"vsplit", "never" "never"
{ignore_filename} (boolean) dont show filenames (default: true) {show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false) {trim_text} (boolean) trim results text (default: false)
{fname_width} (number) defines the width of the filename section
(default: 30)
builtin.lsp_document_symbols({opts}) *telescope.builtin.lsp_document_symbols()* builtin.lsp_document_symbols({opts}) *telescope.builtin.lsp_document_symbols()*
@@ -1493,8 +1565,6 @@ builtin.lsp_document_symbols({opts}) *telescope.builtin.lsp_document_symbols()*
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default:
true)
{show_line} (boolean) if true, shows the content of the {show_line} (boolean) if true, shows the content of the
line the tag is found on (default: line the tag is found on (default:
false) false)
@@ -1517,8 +1587,6 @@ builtin.lsp_workspace_symbols({opts}) *telescope.builtin.lsp_workspace_symbols()
Options: ~ Options: ~
{query} (string) for what to query the workspace {query} (string) for what to query the workspace
(default: "") (default: "")
{ignore_filename} (boolean) dont show filenames (default:
false)
{show_line} (boolean) if true, shows the content of the {show_line} (boolean) if true, shows the content of the
line the tag is found on (default: line the tag is found on (default:
false) false)
@@ -1539,8 +1607,6 @@ builtin.lsp_dynamic_workspace_symbols({opts}) *telescope.builtin.lsp_dynamic_wor
{opts} (table) options to pass to the picker {opts} (table) options to pass to the picker
Options: ~ Options: ~
{ignore_filename} (boolean) dont show filenames (default:
false)
{show_line} (boolean) if true, shows the content of the {show_line} (boolean) if true, shows the content of the
line the symbol is found on line the symbol is found on
(default: false) (default: false)
@@ -1891,14 +1957,17 @@ Provides "resolver functions" to allow more customisable inputs for options.
resolver.resolve_height() *telescope.resolve.resolve_height()* resolver.resolve_height() *telescope.resolve.resolve_height()*
Converts input to a function that returns the height. The input must take Converts input to a function that returns the height. The input must take
one of four forms: one of five forms:
1. 0 <= number < 1 1. 0 <= number < 1
This means total height as a percentage. This means total height as a percentage.
2. 1 <= number 2. 1 <= number
This means total height as a fixed number. This means total height as a fixed number.
3. function 3. function
Must have signature: function(self, max_columns, max_lines): number Must have signature: function(self, max_columns, max_lines): number
4. table of the form: {padding = `foo`} 4. table of the form: { val, max = ..., min = ... }
val has to be in the first form 0 <= val < 1 and only one is given,
`min` or `max` as fixed number
5. table of the form: {padding = `foo`}
where `foo` has one of the previous three forms. where `foo` has one of the previous three forms.
The height is then set to be the remaining space after padding. For The height is then set to be the remaining space after padding. For
example, if the window has height 50, and the input is {padding = 5}, example, if the window has height 50, and the input is {padding = 5},
@@ -1911,14 +1980,17 @@ resolver.resolve_height() *telescope.resolve.resolve_height()*
resolver.resolve_width() *telescope.resolve.resolve_width()* resolver.resolve_width() *telescope.resolve.resolve_width()*
Converts input to a function that returns the width. The input must take Converts input to a function that returns the width. The input must take
one of four forms: one of five forms:
1. 0 <= number < 1 1. 0 <= number < 1
This means total width as a percentage. This means total width as a percentage.
2. 1 <= number 2. 1 <= number
This means total width as a fixed number. This means total width as a fixed number.
3. function 3. function
Must have signature: function(self, max_columns, max_lines): number Must have signature: function(self, max_columns, max_lines): number
4. table of the form: {padding = `foo`} 4. table of the form: { val, max = ..., min = ... }
val has to be in the first form 0 <= val < 1 and only one is given,
`min` or `max` as fixed number
5. table of the form: {padding = `foo`}
where `foo` has one of the previous three forms. where `foo` has one of the previous three forms.
The width is then set to be the remaining space after padding. For The width is then set to be the remaining space after padding. For
example, if the window has width 100, and the input is {padding = 5}, example, if the window has width 100, and the input is {padding = 5},
@@ -1944,6 +2016,134 @@ resolver.resolve_anchor_pos() *telescope.resolve.resolve_anchor_pos()*
================================================================================
*telescope.make_entry*
Each picker has a finder made up of two parts, the results which are the data
to be displayed, and the entry_maker. These entry_makers are functions returned
from make_entry functions. These will be referrd to as entry_makers in the
following documentation.
Every entry maker returns a function which accepts the data to be used for an
entry. This function will return an entry table (or nil, meaning skip this
entry) which contains of the - following important keys:
- value any: value key can be anything but still required
- valid bool: is an optional key because it defaults to true but if the key is
set to false it will not be displayed by the picker. (optional)
- ordinal string: is the text that is used for filtering (required)
- display string|function: is either a string of the text that is being
displayed or a function receiving the entry at a later stage, when the entry
is actually being displayed. A function can be useful here if complex
calculation have to be done. `make_entry` can also return a second value a
highlight array which will then apply to the line. Highlight entry in this
array has the following signature `{ { start_col, end_col }, hl_group }`
(required).
- filename string: will be interpreted by the default `<cr>` action as open
this file (optional)
- bufnr number: will be interpreted by the default `<cr>` action as open this
buffer (optional)
- lnum number: lnum value which will be interpreted by the default `<cr>`
action as a jump to this line (optional)
- col number: col value which will be interpreted by the default `<cr>` action
as a jump to this column (optional)
More information on easier displaying, see |telescope.pickers.entry_display|
TODO: Document something we call `entry_index`
================================================================================
*telescope.pickers.entry_display*
Entry Display is used to format each entry shown in the result panel.
Entry Display create() will give us a function based on the configuration of
column widths we pass into it. We then can use this function n times to return
a string based on structured input.
Note that if you call `create()` inside `make_display` it will be called for
every single entry. So it is suggested to do this outside of `make_display` for
the best performance.
The create function will use the column widths passed to it in
configaration.items. Each item in that table is the number of characters in the
column. It's also possible for the final column to not have a fixed width, this
will be shown in the configuartion as 'remaining = true'.
An example of this configuration is shown for the buffers picker
>
local displayer = entry_display.create {
separator = " ",
items = {
{ width = opts.bufnr_width },
{ width = 4 },
{ width = icon_width },
{ remaining = true },
},
}
<
This shows 4 columns, the first is defined in the opts as the width we'll use
when display_string the number of the buffer. The second has a fixed width of 4
and the 3rd column's widht will be decided by the width of the icons we use.
The fourth column will use the remaining space. Finally we have also defined
the seperator between each column will be the space " ".
An example of how the display reference will be used is shown, again for the
buffers picker:
>
return displayer {
{ entry.bufnr, "TelescopeResultsNumber" },
{ entry.indicator, "TelescopeResultsComment" },
{ icon, hl_group },
display_bufname .. ":" .. entry.lnum,
}
<
There are two types of values each column can have. Either a simple String or a
table containing the String as well as the hl_group.
The displayer can return values, string and an optional highlights. String is
all the text to be displayed for this entry as a single string. If parts of the
string are to be highlighted they will be described in the highlights table.
For better understanding of how create() and displayer are used it's best to
look at the code in make_entry.lua.
================================================================================
*telescope.utils*
Utilities for writing telescope pickers
utils.transform_path({opts}, {path}) *telescope.utils.transform_path()*
Transform path is a util function that formats a path based on path_display
found in `opts` or the default value from config. It is meant to be used in
make_entry to have a uniform interface for builtins as well as extensions
utilizing the same user configuration Note: It is only supported inside
`make_entry`/`make_display` the use of this function outside of telescope
might yield to undefined behavior and will not be addressed by us
Parameters: ~
{opts} (table) The opts the users passed into the picker. Might
contains a path_display key
{path} (string) The path that should be formated
Return: ~
string: The transformed path ready to be displayed
utils.notify({funname}, {opts}) *telescope.utils.notify()*
Telescope Wrapper around vim.notify
Parameters: ~
{funname} (string) name of the function that will be
{opts} (table) opts.level string, opts.msg string, opts.once bool
================================================================================ ================================================================================
*telescope.actions* *telescope.actions*
@@ -2285,6 +2485,8 @@ actions.edit_register({prompt_bufnr}) *telescope.actions.edit_register()*
actions.paste_register({prompt_bufnr}) *telescope.actions.paste_register()* actions.paste_register({prompt_bufnr}) *telescope.actions.paste_register()*
Paste the selected register into the buffer Paste the selected register into the buffer
Note: only meant to be used inside builtin.registers
Parameters: ~ Parameters: ~
{prompt_bufnr} (number) The prompt bufnr {prompt_bufnr} (number) The prompt bufnr
@@ -2770,7 +2972,8 @@ Generally used from within other |telescope.actions|
utils.map_entries({prompt_bufnr}, {f}) *telescope.actions.utils.map_entries()* utils.map_entries({prompt_bufnr}, {f}) *telescope.actions.utils.map_entries()*
Apply `f` to the entries of the current picker. Apply `f` to the entries of the current picker.
- Notes: - Notes:
- Mapped entries may include results not visible in the results popup. - Mapped entries include all currently filtered results, not just the
visible onces.
- Indices are 1-indexed, whereas rows are 0-indexed. - Indices are 1-indexed, whereas rows are 0-indexed.
- Warning: `map_entries` has no return value. - Warning: `map_entries` has no return value.
- The below example showcases how to collect results - The below example showcases how to collect results

View File

@@ -195,5 +195,64 @@ https://github.com/stevearc/dressing.nvim which has support for multiple
different backends including telescope. different backends including telescope.
*telescope.changelog-1945*
Date: July 01, 2022
PR: https://github.com/nvim-telescope/telescope.nvim/pull/1945
This is our dev branch which contains a lot of PRs, a lot of fixes,
refactoring and general quality of life improvements. It also contains new
features, the most noteworthy are the following (mostly developed by the
community):
- feat: none strategy & control attachment (#1867)
- feat: force buffer delete for terminal and improvements for
Picker:delete_selection (#1943)
- feat(tags): process tagfiles on the fly (#1989)
- feat(builtin.lsp): implement builtin handlers for
lsp.(incoming|outgoing)_calls (#1484)
- feat: clear previewer if no item is selected (#2004)
- feat: add min max boundary to width, height resolver (#2002)
- feat: Add entry_index for entry_makers (#1850)
- feat: refine with new_table (#1115)
The last one is one of the most existing new features, because it allows you
to go from live_grep into a fuzzy environment with the following mapping
`<C-Space>`. It's a general interface we now implemented for `live_grep` and
`lsp_dynamic_workspace_symbols` but it could also be easily implemented for
other builtins, by us or the user. It's now available for extension developers.
We will add documentation in the next couple of days and improve it by adding
more options to configure it after the initial 0.1 release.
But with all longer development phases, there are also some breaking changes.
This is the main reason we moved development to a separate branch, for the
past two months. We can't promise that there won't be more breaking changes,
but it is the plan that this is the last set of breaking changes prior to the
0.1 release on July, 12. We are deeply sorry for the inconvenience. The
following breaking changes are included in this PR:
- break(git_files): change `show_untracked` default to false. Can be changed
back with `:Telescope git_files show_untracked=true`
- break: deprecate `utils.get_default` `utils.if_nil`, will be removed prior
to 0.1, so if you use it in your config, please move to `vim.F.if_nil`
- break: drops `ignore_filename` option, use `path_display= { "hidden" }`
instead
- break: prefix internal interfaces with __ so
`require("telescope.builtin.files").find_files` will show a notify error but
still works for now. The error will be removed prior to 0.1! You should use
`require("telescope.builtin").find_files` because we wrap all the functions
that are exposed in this module.
- break: defaults.preview.treesitter rework that allows you to either enable a
list of languages, or enable all and disable some. Please read
`:help telescope.defaults.preview` for more information.
Something like this is now possible:
>
treesitter = {
enable = false,
-- or
enable = { "c" },
-- disable can be set if enable isn't set
disable = { "perl", "javascript" },
},
<
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View File

@@ -24,6 +24,10 @@
---@brief ]] ---@brief ]]
local actions = require "telescope.actions" local actions = require "telescope.actions"
local config = require "telescope.config"
local action_state = require "telescope.actions.state"
local finders = require "telescope.finders"
local action_generate = {} local action_generate = {}
--- Display the keymaps of registered actions similar to which-key.nvim.<br> --- Display the keymaps of registered actions similar to which-key.nvim.<br>
@@ -54,4 +58,56 @@ action_generate.which_key = function(opts)
end end
end end
action_generate.refine = function(prompt_bufnr, opts)
opts = opts or {}
opts.prompt_to_prefix = vim.F.if_nil(opts.prompt_to_prefix, false)
opts.prefix_hl_group = vim.F.if_nil(opts.prompt_hl_group, "TelescopePromptPrefix")
opts.prompt_prefix = vim.F.if_nil(opts.promt_prefix, config.values.prompt_prefix)
opts.reset_multi_selection = vim.F.if_nil(opts.reset_multi_selection, false)
opts.reset_prompt = vim.F.if_nil(opts.reset_prompt, true)
opts.sorter = vim.F.if_nil(opts.sorter, config.values.generic_sorter {})
local current_picker = action_state.get_current_picker(prompt_bufnr)
-- title
if opts.prompt_title then
current_picker.prompt_border:change_title(opts.prompt_title)
end
if opts.results_title then
current_picker.results_border:change_title(opts.results_title)
end
local results = {}
for entry in current_picker.manager:iter() do
table.insert(results, entry)
end
-- if opts.sorter == false, keep older sorter
if opts.sorter then
current_picker.sorter:_destroy()
current_picker.sorter = opts.sorter
current_picker.sorter:_init()
end
local new_finder = finders.new_table {
results = results,
entry_maker = function(x)
return x
end,
}
if not opts.reset_multi_selection and action_state.get_current_line() ~= "" then
opts.multi = current_picker._multi
end
if opts.prompt_to_prefix then
local prompt = action_state.get_current_line()
local current_prefix = current_picker.prompt_prefix
local suffix = current_prefix ~= opts.prompt_prefix and current_prefix or ""
opts.new_prefix = suffix .. prompt .. " " .. opts.prompt_prefix
end
current_picker:refresh(new_finder, opts)
end
return action_generate return action_generate

View File

@@ -431,6 +431,8 @@ actions.edit_register = function(prompt_bufnr)
end end
--- Paste the selected register into the buffer --- Paste the selected register into the buffer
---
--- Note: only meant to be used inside builtin.registers
---@param prompt_bufnr number: The prompt bufnr ---@param prompt_bufnr number: The prompt bufnr
actions.paste_register = function(prompt_bufnr) actions.paste_register = function(prompt_bufnr)
local selection = action_state.get_selected_entry() local selection = action_state.get_selected_entry()
@@ -1020,7 +1022,9 @@ end
actions.delete_buffer = function(prompt_bufnr) actions.delete_buffer = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr) local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection) current_picker:delete_selection(function(selection)
vim.api.nvim_buf_delete(selection.bufnr, { force = false }) local force = vim.api.nvim_buf_get_option(selection.bufnr, "buftype") == "terminal"
local ok = pcall(vim.api.nvim_buf_delete, selection.bufnr, { force = force })
return ok
end) end)
end end
@@ -1059,22 +1063,22 @@ end
---@param prompt_bufnr number: The prompt bufnr ---@param prompt_bufnr number: The prompt bufnr
actions.which_key = function(prompt_bufnr, opts) actions.which_key = function(prompt_bufnr, opts)
opts = opts or {} opts = opts or {}
opts.max_height = utils.get_default(opts.max_height, 0.4) opts.max_height = vim.F.if_nil(opts.max_height, 0.4)
opts.only_show_current_mode = utils.get_default(opts.only_show_current_mode, true) opts.only_show_current_mode = vim.F.if_nil(opts.only_show_current_mode, true)
opts.mode_width = utils.get_default(opts.mode_width, 1) opts.mode_width = vim.F.if_nil(opts.mode_width, 1)
opts.keybind_width = utils.get_default(opts.keybind_width, 7) opts.keybind_width = vim.F.if_nil(opts.keybind_width, 7)
opts.name_width = utils.get_default(opts.name_width, 30) opts.name_width = vim.F.if_nil(opts.name_width, 30)
opts.line_padding = utils.get_default(opts.line_padding, 1) opts.line_padding = vim.F.if_nil(opts.line_padding, 1)
opts.separator = utils.get_default(opts.separator, " -> ") opts.separator = vim.F.if_nil(opts.separator, " -> ")
opts.close_with_action = utils.get_default(opts.close_with_action, true) opts.close_with_action = vim.F.if_nil(opts.close_with_action, true)
opts.normal_hl = utils.get_default(opts.normal_hl, "TelescopePrompt") opts.normal_hl = vim.F.if_nil(opts.normal_hl, "TelescopePrompt")
opts.border_hl = utils.get_default(opts.border_hl, "TelescopePromptBorder") opts.border_hl = vim.F.if_nil(opts.border_hl, "TelescopePromptBorder")
opts.winblend = utils.get_default(opts.winblend, config.values.winblend) opts.winblend = vim.F.if_nil(opts.winblend, config.values.winblend)
opts.column_padding = utils.get_default(opts.column_padding, " ") opts.column_padding = vim.F.if_nil(opts.column_padding, " ")
-- Assigning into 'opts.column_indent' would override a number with a string and -- Assigning into 'opts.column_indent' would override a number with a string and
-- cause issues with subsequent calls, keep a local copy of the string instead -- cause issues with subsequent calls, keep a local copy of the string instead
local column_indent = table.concat(utils.repeated_table(utils.get_default(opts.column_indent, 4), " ")) local column_indent = table.concat(utils.repeated_table(vim.F.if_nil(opts.column_indent, 4), " "))
-- close on repeated keypress -- close on repeated keypress
local km_bufs = (function() local km_bufs = (function()
@@ -1111,9 +1115,9 @@ actions.which_key = function(prompt_bufnr, opts)
local make_display = function(mapping) local make_display = function(mapping)
return displayer { return displayer {
{ mapping.mode, utils.get_default(opts.mode_hl, "TelescopeResultsConstant") }, { mapping.mode, vim.F.if_nil(opts.mode_hl, "TelescopeResultsConstant") },
{ mapping.keybind, utils.get_default(opts.keybind_hl, "TelescopeResultsVariable") }, { mapping.keybind, vim.F.if_nil(opts.keybind_hl, "TelescopeResultsVariable") },
{ mapping.name, utils.get_default(opts.name_hl, "TelescopeResultsFunction") }, { mapping.name, vim.F.if_nil(opts.name_hl, "TelescopeResultsFunction") },
} }
end end

View File

@@ -13,7 +13,7 @@ local utils = {}
--- Apply `f` to the entries of the current picker. --- Apply `f` to the entries of the current picker.
--- - Notes: --- - Notes:
--- - Mapped entries may include results not visible in the results popup. --- - Mapped entries include all currently filtered results, not just the visible onces.
--- - Indices are 1-indexed, whereas rows are 0-indexed. --- - Indices are 1-indexed, whereas rows are 0-indexed.
--- - Warning: `map_entries` has no return value. --- - Warning: `map_entries` has no return value.
--- - The below example showcases how to collect results --- - The below example showcases how to collect results

View File

@@ -0,0 +1,150 @@
local conf = require("telescope.config").values
local finders = require "telescope.finders"
local make_entry = require "telescope.make_entry"
local pickers = require "telescope.pickers"
local utils = require "telescope.utils"
local diagnostics = {}
local convert_diagnostic_type = function(severities, severity)
-- convert from string to int
if type(severity) == "string" then
-- make sure that e.g. error is uppercased to ERROR
return severities[severity:upper()]
end
-- otherwise keep original value, incl. nil
return severity
end
local diagnostics_to_tbl = function(opts)
opts = vim.F.if_nil(opts, {})
local items = {}
local severities = vim.diagnostic.severity
local current_buf = vim.api.nvim_get_current_buf()
opts.severity = convert_diagnostic_type(severities, opts.severity)
opts.severity_limit = convert_diagnostic_type(severities, opts.severity_limit)
opts.severity_bound = convert_diagnostic_type(severities, opts.severity_bound)
local diagnosis_opts = { severity = {}, namespace = opts.namespace }
if opts.severity ~= nil then
if opts.severity_limit ~= nil or opts.severity_bound ~= nil then
utils.notify("builtin.diagnostics", {
msg = "Invalid severity parameters. Both a specific severity and a limit/bound is not allowed",
level = "ERROR",
})
return {}
end
diagnosis_opts.severity = opts.severity
else
if opts.severity_limit ~= nil then
diagnosis_opts.severity["min"] = opts.severity_limit
end
if opts.severity_bound ~= nil then
diagnosis_opts.severity["max"] = opts.severity_bound
end
end
opts.root_dir = opts.root_dir == true and vim.loop.cwd() or opts.root_dir
local bufnr_name_map = {}
local filter_diag = function(diagnostic)
if bufnr_name_map[diagnostic.bufnr] == nil then
bufnr_name_map[diagnostic.bufnr] = vim.api.nvim_buf_get_name(diagnostic.bufnr)
end
local root_dir_test = not opts.root_dir
or string.sub(bufnr_name_map[diagnostic.bufnr], 1, #opts.root_dir) == opts.root_dir
local listed_test = not opts.no_unlisted or vim.api.nvim_buf_get_option(diagnostic.bufnr, "buflisted")
return root_dir_test and listed_test
end
local preprocess_diag = function(diagnostic)
return {
bufnr = diagnostic.bufnr,
filename = bufnr_name_map[diagnostic.bufnr],
lnum = diagnostic.lnum + 1,
col = diagnostic.col + 1,
text = vim.trim(diagnostic.message:gsub("[\n]", "")),
type = severities[diagnostic.severity] or severities[1],
}
end
for _, d in ipairs(vim.diagnostic.get(opts.bufnr, diagnosis_opts)) do
if filter_diag(d) then
table.insert(items, preprocess_diag(d))
end
end
-- sort results by bufnr (prioritize cur buf), severity, lnum
table.sort(items, function(a, b)
if a.bufnr == b.bufnr then
if a.type == b.type then
return a.lnum < b.lnum
else
return a.type < b.type
end
else
-- prioritize for current bufnr
if a.bufnr == current_buf then
return true
end
if b.bufnr == current_buf then
return false
end
return a.bufnr < b.bufnr
end
end)
return items
end
diagnostics.get = function(opts)
if opts.bufnr ~= 0 then
opts.bufnr = nil
end
if opts.bufnr == nil then
opts.path_display = vim.F.if_nil(opts.path_display, {})
end
if type(opts.bufnr) == "string" then
opts.bufnr = tonumber(opts.bufnr)
end
local locations = diagnostics_to_tbl(opts)
if vim.tbl_isempty(locations) then
utils.notify("builtin.diagnostics", {
msg = "No diagnostics found",
level = "INFO",
})
return
end
opts.path_display = vim.F.if_nil(opts.path_display, "hidden")
pickers.new(opts, {
prompt_title = opts.bufnr == nil and "Workspace Diagnostics" or "Document Diagnostics",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_diagnostics(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "type",
sorter = conf.generic_sorter(opts),
},
}):find()
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
v(opts)
end
end
return mod
end
return apply_checks(diagnostics)

View File

@@ -0,0 +1,522 @@
local action_state = require "telescope.actions.state"
local action_set = require "telescope.actions.set"
local finders = require "telescope.finders"
local make_entry = require "telescope.make_entry"
local pickers = require "telescope.pickers"
local previewers = require "telescope.previewers"
local sorters = require "telescope.sorters"
local utils = require "telescope.utils"
local conf = require("telescope.config").values
local log = require "telescope.log"
local Path = require "plenary.path"
local flatten = vim.tbl_flatten
local filter = vim.tbl_filter
local files = {}
local escape_chars = function(string)
return string.gsub(string, "[%(|%)|\\|%[|%]|%-|%{%}|%?|%+|%*|%^|%$|%.]", {
["\\"] = "\\\\",
["-"] = "\\-",
["("] = "\\(",
[")"] = "\\)",
["["] = "\\[",
["]"] = "\\]",
["{"] = "\\{",
["}"] = "\\}",
["?"] = "\\?",
["+"] = "\\+",
["*"] = "\\*",
["^"] = "\\^",
["$"] = "\\$",
["."] = "\\.",
})
end
-- Special keys:
-- opts.search_dirs -- list of directory to search in
-- opts.grep_open_files -- boolean to restrict search to open files
files.live_grep = function(opts)
local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
local search_dirs = opts.search_dirs
local grep_open_files = opts.grep_open_files
opts.cwd = opts.cwd and vim.fn.expand(opts.cwd) or vim.loop.cwd()
local filelist = {}
if grep_open_files then
local bufnrs = filter(function(b)
if 1 ~= vim.fn.buflisted(b) then
return false
end
return true
end, vim.api.nvim_list_bufs())
if not next(bufnrs) then
return
end
for _, bufnr in ipairs(bufnrs) do
local file = vim.api.nvim_buf_get_name(bufnr)
table.insert(filelist, Path:new(file):make_relative(opts.cwd))
end
elseif search_dirs then
for i, path in ipairs(search_dirs) do
search_dirs[i] = vim.fn.expand(path)
end
end
local additional_args = {}
if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
additional_args = opts.additional_args(opts)
end
if opts.type_filter then
additional_args[#additional_args + 1] = "--type=" .. opts.type_filter
end
if type(opts.glob_pattern) == "string" then
additional_args[#additional_args + 1] = "--glob=" .. opts.glob_pattern
elseif type(opts.glob_pattern) == "table" then
for i = 1, #opts.glob_pattern do
additional_args[#additional_args + 1] = "--glob=" .. opts.glob_pattern[i]
end
end
local live_grepper = finders.new_job(function(prompt)
-- TODO: Probably could add some options for smart case and whatever else rg offers.
if not prompt or prompt == "" then
return nil
end
local search_list = {}
if search_dirs then
table.insert(search_list, search_dirs)
end
if grep_open_files then
search_list = filelist
end
return flatten { vimgrep_arguments, additional_args, "--", prompt, search_list }
end, opts.entry_maker or make_entry.gen_from_vimgrep(opts), opts.max_results, opts.cwd)
pickers.new(opts, {
prompt_title = "Live Grep",
finder = live_grepper,
previewer = conf.grep_previewer(opts),
-- TODO: It would be cool to use `--json` output for this
-- and then we could get the highlight positions directly.
sorter = sorters.highlighter_only(opts),
attach_mappings = function(_, map)
map("i", "<c-space>", function(prompt_bufnr)
local line = action_state.get_current_line()
require("telescope.actions.generate").refine(prompt_bufnr, {
prompt_title = "Find Word (" .. line .. ")",
sorter = conf.generic_sorter(opts),
})
end)
return true
end,
}):find()
end
-- Special keys:
-- opts.search -- the string to search.
-- opts.search_dirs -- list of directory to search in
-- opts.use_regex -- special characters won't be escaped
files.grep_string = function(opts)
-- TODO: This should probably check your visual selection as well, if you've got one
local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
local search_dirs = opts.search_dirs
local word = opts.search or vim.fn.expand "<cword>"
local search = opts.use_regex and word or escape_chars(word)
local word_match = opts.word_match
opts.entry_maker = opts.entry_maker or make_entry.gen_from_vimgrep(opts)
local title_word = word:gsub("\n", "\\n")
local additional_args = {}
if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
additional_args = opts.additional_args(opts)
end
local args = flatten {
vimgrep_arguments,
additional_args,
word_match,
"--",
search,
}
if search_dirs then
for _, path in ipairs(search_dirs) do
table.insert(args, vim.fn.expand(path))
end
end
pickers.new(opts, {
prompt_title = "Find Word (" .. title_word .. ")",
finder = finders.new_oneshot_job(args, opts),
previewer = conf.grep_previewer(opts),
sorter = conf.generic_sorter(opts),
}):find()
end
files.find_files = function(opts)
local find_command = (function()
if opts.find_command then
if type(opts.find_command) == "function" then
return opts.find_command(opts)
end
return opts.find_command
elseif 1 == vim.fn.executable "fd" then
return { "fd", "--type", "f" }
elseif 1 == vim.fn.executable "fdfind" then
return { "fdfind", "--type", "f" }
elseif 1 == vim.fn.executable "rg" then
return { "rg", "--files" }
elseif 1 == vim.fn.executable "find" and vim.fn.has "win32" == 0 then
return { "find", ".", "-type", "f" }
elseif 1 == vim.fn.executable "where" then
return { "where", "/r", ".", "*" }
end
end)()
if not find_command then
utils.notify("builtin.find_files", {
msg = "You need to install either find, fd, or rg",
level = "ERROR",
})
return
end
local command = find_command[1]
local hidden = opts.hidden
local no_ignore = opts.no_ignore
local no_ignore_parent = opts.no_ignore_parent
local follow = opts.follow
local search_dirs = opts.search_dirs
local search_file = opts.search_file
if search_dirs then
for k, v in pairs(search_dirs) do
search_dirs[k] = vim.fn.expand(v)
end
end
if command == "fd" or command == "fdfind" or command == "rg" then
if hidden then
table.insert(find_command, "--hidden")
end
if no_ignore then
table.insert(find_command, "--no-ignore")
end
if no_ignore_parent then
table.insert(find_command, "--no-ignore-parent")
end
if follow then
table.insert(find_command, "-L")
end
if search_file then
if command == "rg" then
table.insert(find_command, "-g")
table.insert(find_command, "*" .. search_file .. "*")
else
table.insert(find_command, search_file)
end
end
if search_dirs then
if command ~= "rg" and not search_file then
table.insert(find_command, ".")
end
for _, v in pairs(search_dirs) do
table.insert(find_command, v)
end
end
elseif command == "find" then
if not hidden then
table.insert(find_command, { "-not", "-path", "*/.*" })
find_command = flatten(find_command)
end
if no_ignore ~= nil then
log.warn "The `no_ignore` key is not available for the `find` command in `find_files`."
end
if no_ignore_parent ~= nil then
log.warn "The `no_ignore_parent` key is not available for the `find` command in `find_files`."
end
if follow then
table.insert(find_command, 2, "-L")
end
if search_file then
table.insert(find_command, "-name")
table.insert(find_command, "*" .. search_file .. "*")
end
if search_dirs then
table.remove(find_command, 2)
for _, v in pairs(search_dirs) do
table.insert(find_command, 2, v)
end
end
elseif command == "where" then
if hidden ~= nil then
log.warn "The `hidden` key is not available for the Windows `where` command in `find_files`."
end
if no_ignore ~= nil then
log.warn "The `no_ignore` key is not available for the Windows `where` command in `find_files`."
end
if no_ignore_parent ~= nil then
log.warn "The `no_ignore_parent` key is not available for the Windows `where` command in `find_files`."
end
if follow ~= nil then
log.warn "The `follow` key is not available for the Windows `where` command in `find_files`."
end
if search_dirs ~= nil then
log.warn "The `search_dirs` key is not available for the Windows `where` command in `find_files`."
end
if search_file ~= nil then
log.warn "The `search_file` key is not available for the Windows `where` command in `find_files`."
end
end
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
end
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
pickers.new(opts, {
prompt_title = "Find Files",
finder = finders.new_oneshot_job(find_command, opts),
previewer = conf.file_previewer(opts),
sorter = conf.file_sorter(opts),
}):find()
end
local function prepare_match(entry, kind)
local entries = {}
if entry.node then
table.insert(entries, entry)
else
for name, item in pairs(entry) do
vim.list_extend(entries, prepare_match(item, name))
end
end
return entries
end
-- TODO: finish docs for opts.show_line
files.treesitter = function(opts)
opts.show_line = vim.F.if_nil(opts.show_line, true)
local has_nvim_treesitter, _ = pcall(require, "nvim-treesitter")
if not has_nvim_treesitter then
utils.notify("builtin.treesitter", {
msg = "User need to install nvim-treesitter needs to be installed",
level = "ERROR",
})
return
end
local parsers = require "nvim-treesitter.parsers"
if not parsers.has_parser(parsers.get_buf_lang(opts.bufnr)) then
utils.notify("builtin.treesitter", {
msg = "No parser for the current buffer",
level = "ERROR",
})
return
end
local ts_locals = require "nvim-treesitter.locals"
local results = {}
for _, definition in ipairs(ts_locals.get_definitions(opts.bufnr)) do
local entries = prepare_match(ts_locals.get_local_nodes(definition))
for _, entry in ipairs(entries) do
entry.kind = vim.F.if_nil(entry.kind, "")
table.insert(results, entry)
end
end
if vim.tbl_isempty(results) then
return
end
pickers.new(opts, {
prompt_title = "Treesitter Symbols",
finder = finders.new_table {
results = results,
entry_maker = opts.entry_maker or make_entry.gen_from_treesitter(opts),
},
previewer = conf.grep_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "kind",
sorter = conf.generic_sorter(opts),
},
}):find()
end
files.current_buffer_fuzzy_find = function(opts)
-- All actions are on the current buffer
local filename = vim.fn.expand(vim.api.nvim_buf_get_name(opts.bufnr))
local filetype = vim.api.nvim_buf_get_option(opts.bufnr, "filetype")
local lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)
local lines_with_numbers = {}
for lnum, line in ipairs(lines) do
table.insert(lines_with_numbers, {
lnum = lnum,
bufnr = opts.bufnr,
filename = filename,
text = line,
})
end
local ts_ok, ts_parsers = pcall(require, "nvim-treesitter.parsers")
if ts_ok then
filetype = ts_parsers.ft_to_lang(filetype)
end
local _, ts_configs = pcall(require, "nvim-treesitter.configs")
local parser_ok, parser = pcall(vim.treesitter.get_parser, opts.bufnr, filetype)
local query_ok, query = pcall(vim.treesitter.get_query, filetype, "highlights")
if parser_ok and query_ok and ts_ok and ts_configs.is_enabled("highlight", filetype, opts.bufnr) then
local root = parser:parse()[1]:root()
local highlighter = vim.treesitter.highlighter.new(parser)
local highlighter_query = highlighter:get_query(filetype)
local line_highlights = setmetatable({}, {
__index = function(t, k)
local obj = {}
rawset(t, k, obj)
return obj
end,
})
for id, node in query:iter_captures(root, opts.bufnr, 0, -1) do
local hl = highlighter_query:_get_hl_from_capture(id)
if hl and type(hl) ~= "number" then
local row1, col1, row2, col2 = node:range()
if row1 == row2 then
local row = row1 + 1
for index = col1, col2 do
line_highlights[row][index] = hl
end
else
local row = row1 + 1
for index = col1, #lines[row] do
line_highlights[row][index] = hl
end
while row < row2 + 1 do
row = row + 1
for index = 0, #(lines[row] or {}) do
line_highlights[row][index] = hl
end
end
end
end
end
opts.line_highlights = line_highlights
end
pickers.new(opts, {
prompt_title = "Current Buffer Fuzzy",
finder = finders.new_table {
results = lines_with_numbers,
entry_maker = opts.entry_maker or make_entry.gen_from_buffer_lines(opts),
},
sorter = conf.generic_sorter(opts),
previewer = conf.grep_previewer(opts),
attach_mappings = function()
action_set.select:enhance {
post = function()
local selection = action_state.get_selected_entry()
vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
end,
}
return true
end,
}):find()
end
files.tags = function(opts)
local tagfiles = opts.ctags_file and { opts.ctags_file } or vim.fn.tagfiles()
for i, ctags_file in ipairs(tagfiles) do
tagfiles[i] = vim.fn.expand(ctags_file, true)
end
if vim.tbl_isempty(tagfiles) then
utils.notify("builtin.tags", {
msg = "No tags file found. Create one with ctags -R",
level = "ERROR",
})
return
end
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_ctags(opts))
pickers.new(opts, {
prompt_title = "Tags",
finder = finders.new_oneshot_job(flatten { "cat", tagfiles }, opts),
previewer = previewers.ctags.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function()
action_set.select:enhance {
post = function()
local selection = action_state.get_selected_entry()
if not selection then
return
end
if selection.scode then
-- un-escape / then escape required
-- special chars for vim.fn.search()
-- ] ~ *
local scode = selection.scode:gsub([[\/]], "/"):gsub("[%]~*]", function(x)
return "\\" .. x
end)
vim.cmd "norm! gg"
vim.fn.search(scode)
vim.cmd "norm! zz"
else
vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
end
end,
}
return true
end,
}):find()
end
files.current_buffer_tags = function(opts)
return files.tags(vim.tbl_extend("force", {
prompt_title = "Current Buffer Tags",
only_current_file = true,
path_display = "hidden",
}, opts))
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
v(opts)
end
end
return mod
end
return apply_checks(files)

View File

@@ -0,0 +1,411 @@
local actions = require "telescope.actions"
local action_state = require "telescope.actions.state"
local finders = require "telescope.finders"
local make_entry = require "telescope.make_entry"
local pickers = require "telescope.pickers"
local previewers = require "telescope.previewers"
local utils = require "telescope.utils"
local entry_display = require "telescope.pickers.entry_display"
local strings = require "plenary.strings"
local Path = require "plenary.path"
local conf = require("telescope.config").values
local git = {}
git.files = function(opts)
if opts.is_bare then
utils.notify("builtin.git_files", {
msg = "This operation must be run in a work tree",
level = "ERROR",
})
return
end
local show_untracked = vim.F.if_nil(opts.show_untracked, false)
local recurse_submodules = vim.F.if_nil(opts.recurse_submodules, false)
if show_untracked and recurse_submodules then
utils.notify("builtin.git_files", {
msg = "Git does not support both --others and --recurse-submodules",
level = "ERROR",
})
return
end
-- By creating the entry maker after the cwd options,
-- we ensure the maker uses the cwd options when being created.
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_file(opts))
local git_command = vim.F.if_nil(opts.git_command, { "git", "ls-files", "--exclude-standard", "--cached" })
pickers.new(opts, {
prompt_title = "Git Files",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
git_command,
show_untracked and "--others" or nil,
recurse_submodules and "--recurse-submodules" or nil,
},
opts
),
previewer = conf.file_previewer(opts),
sorter = conf.file_sorter(opts),
}):find()
end
git.commits = function(opts)
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_commits(opts))
local git_command = vim.F.if_nil(opts.git_command, { "git", "log", "--pretty=oneline", "--abbrev-commit", "--", "." })
pickers.new(opts, {
prompt_title = "Git Commits",
finder = finders.new_oneshot_job(git_command, opts),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function(_, map)
actions.select_default:replace(actions.git_checkout)
map("i", "<c-r>m", actions.git_reset_mixed)
map("n", "<c-r>m", actions.git_reset_mixed)
map("i", "<c-r>s", actions.git_reset_soft)
map("n", "<c-r>s", actions.git_reset_soft)
map("i", "<c-r>h", actions.git_reset_hard)
map("n", "<c-r>h", actions.git_reset_hard)
return true
end,
}):find()
end
git.stash = function(opts)
opts.show_branch = vim.F.if_nil(opts.show_branch, true)
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_stash(opts))
pickers.new(opts, {
prompt_title = "Git Stash",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
"git",
"--no-pager",
"stash",
"list",
},
opts
),
previewer = previewers.git_stash_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_apply_stash)
return true
end,
}):find()
end
local get_current_buf_line = function(winnr)
local lnum = vim.api.nvim_win_get_cursor(winnr)[1]
return vim.trim(vim.api.nvim_buf_get_lines(vim.api.nvim_win_get_buf(winnr), lnum - 1, lnum, false)[1])
end
git.bcommits = function(opts)
opts.current_line = (opts.current_file == nil) and get_current_buf_line(opts.winnr) or nil
opts.current_file = vim.F.if_nil(opts.current_file, vim.api.nvim_buf_get_name(opts.bufnr))
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_commits(opts))
local git_command = vim.F.if_nil(
opts.git_command,
{ "git", "log", "--pretty=oneline", "--abbrev-commit", "--follow" }
)
pickers.new(opts, {
prompt_title = "Git BCommits",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
git_command,
opts.current_file,
},
opts
),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_checkout_current_buffer)
local transfrom_file = function()
return opts.current_file and Path:new(opts.current_file):make_relative(opts.cwd) or ""
end
local get_buffer_of_orig = function(selection)
local value = selection.value .. ":" .. transfrom_file()
local content = utils.get_os_command_output({ "git", "--no-pager", "show", value }, opts.cwd)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, content)
vim.api.nvim_buf_set_name(bufnr, "Original")
return bufnr
end
local vimdiff = function(selection, command)
local ft = vim.bo.filetype
vim.cmd "diffthis"
local bufnr = get_buffer_of_orig(selection)
vim.cmd(string.format("%s %s", command, bufnr))
vim.bo.filetype = ft
vim.cmd "diffthis"
vim.api.nvim_create_autocmd("WinClosed", {
buffer = bufnr,
nested = true,
once = true,
callback = function()
vim.api.nvim_buf_delete(bufnr, { force = true })
end,
})
end
actions.select_vertical:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, "leftabove vert sbuffer")
end)
actions.select_horizontal:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, "belowright sbuffer")
end)
actions.select_tab:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vim.cmd("tabedit " .. transfrom_file())
vimdiff(selection, "leftabove vert sbuffer")
end)
return true
end,
}):find()
end
git.branches = function(opts)
local format = "%(HEAD)"
.. "%(refname)"
.. "%(authorname)"
.. "%(upstream:lstrip=2)"
.. "%(committerdate:format-local:%Y/%m/%d %H:%M:%S)"
local output = utils.get_os_command_output(
{ "git", "for-each-ref", "--perl", "--format", format, opts.pattern },
opts.cwd
)
local results = {}
local widths = {
name = 0,
authorname = 0,
upstream = 0,
committerdate = 0,
}
local unescape_single_quote = function(v)
return string.gsub(v, "\\([\\'])", "%1")
end
local parse_line = function(line)
local fields = vim.split(string.sub(line, 2, -2), "''", true)
local entry = {
head = fields[1],
refname = unescape_single_quote(fields[2]),
authorname = unescape_single_quote(fields[3]),
upstream = unescape_single_quote(fields[4]),
committerdate = fields[5],
}
local prefix
if vim.startswith(entry.refname, "refs/remotes/") then
prefix = "refs/remotes/"
elseif vim.startswith(entry.refname, "refs/heads/") then
prefix = "refs/heads/"
else
return
end
local index = 1
if entry.head ~= "*" then
index = #results + 1
end
entry.name = string.sub(entry.refname, string.len(prefix) + 1)
for key, value in pairs(widths) do
widths[key] = math.max(value, strings.strdisplaywidth(entry[key] or ""))
end
if string.len(entry.upstream) > 0 then
widths.upstream_indicator = 2
end
table.insert(results, index, entry)
end
for _, line in ipairs(output) do
parse_line(line)
end
if #results == 0 then
return
end
local displayer = entry_display.create {
separator = " ",
items = {
{ width = 1 },
{ width = widths.name },
{ width = widths.authorname },
{ width = widths.upstream_indicator },
{ width = widths.upstream },
{ width = widths.committerdate },
},
}
local make_display = function(entry)
return displayer {
{ entry.head },
{ entry.name, "TelescopeResultsIdentifier" },
{ entry.authorname },
{ string.len(entry.upstream) > 0 and "=>" or "" },
{ entry.upstream, "TelescopeResultsIdentifier" },
{ entry.committerdate },
}
end
pickers.new(opts, {
prompt_title = "Git Branches",
finder = finders.new_table {
results = results,
entry_maker = function(entry)
entry.value = entry.name
entry.ordinal = entry.name
entry.display = make_display
return make_entry.set_default_entry_mt(entry, opts)
end,
},
previewer = previewers.git_branch_log.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function(_, map)
actions.select_default:replace(actions.git_checkout)
map("i", "<c-t>", actions.git_track_branch)
map("n", "<c-t>", actions.git_track_branch)
map("i", "<c-r>", actions.git_rebase_branch)
map("n", "<c-r>", actions.git_rebase_branch)
map("i", "<c-a>", actions.git_create_branch)
map("n", "<c-a>", actions.git_create_branch)
map("i", "<c-s>", actions.git_switch_branch)
map("n", "<c-s>", actions.git_switch_branch)
map("i", "<c-d>", actions.git_delete_branch)
map("n", "<c-d>", actions.git_delete_branch)
map("i", "<c-y>", actions.git_merge_branch)
map("n", "<c-y>", actions.git_merge_branch)
return true
end,
}):find()
end
git.status = function(opts)
if opts.is_bare then
utils.notify("builtin.git_status", {
msg = "This operation must be run in a work tree",
level = "ERROR",
})
return
end
local gen_new_finder = function()
local expand_dir = vim.F.if_nil(opts.expand_dir, true)
local git_cmd = { "git", "status", "-s", "--", "." }
if expand_dir then
table.insert(git_cmd, #git_cmd - 1, "-u")
end
local output = utils.get_os_command_output(git_cmd, opts.cwd)
if #output == 0 then
print "No changes found"
utils.notify("builtin.git_status", {
msg = "No changes found",
level = "WARN",
})
return
end
return finders.new_table {
results = output,
entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_status(opts)),
}
end
local initial_finder = gen_new_finder()
if not initial_finder then
return
end
pickers.new(opts, {
prompt_title = "Git Status",
finder = initial_finder,
previewer = previewers.git_file_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function(prompt_bufnr, map)
actions.git_staging_toggle:enhance {
post = function()
action_state.get_current_picker(prompt_bufnr):refresh(gen_new_finder(), { reset_prompt = true })
end,
}
map("i", "<tab>", actions.git_staging_toggle)
map("n", "<tab>", actions.git_staging_toggle)
return true
end,
}):find()
end
local set_opts_cwd = function(opts)
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
else
opts.cwd = vim.loop.cwd()
end
-- Find root of git directory and remove trailing newline characters
local git_root, ret = utils.get_os_command_output({ "git", "rev-parse", "--show-toplevel" }, opts.cwd)
local use_git_root = vim.F.if_nil(opts.use_git_root, true)
if ret ~= 0 then
local in_worktree = utils.get_os_command_output({ "git", "rev-parse", "--is-inside-work-tree" }, opts.cwd)
local in_bare = utils.get_os_command_output({ "git", "rev-parse", "--is-bare-repository" }, opts.cwd)
if in_worktree[1] ~= "true" and in_bare[1] ~= "true" then
error(opts.cwd .. " is not a git directory")
elseif in_worktree[1] ~= "true" and in_bare[1] == "true" then
opts.is_bare = true
end
else
if use_git_root then
opts.cwd = git_root[1]
end
end
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = vim.F.if_nil(opts, {})
set_opts_cwd(opts)
v(opts)
end
end
return mod
end
return apply_checks(git)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,389 @@
local channel = require("plenary.async.control").channel
local action_state = require "telescope.actions.state"
local sorters = require "telescope.sorters"
local conf = require("telescope.config").values
local finders = require "telescope.finders"
local make_entry = require "telescope.make_entry"
local pickers = require "telescope.pickers"
local utils = require "telescope.utils"
local lsp = {}
lsp.references = function(opts)
local filepath = vim.api.nvim_buf_get_name(opts.bufnr)
local lnum = vim.api.nvim_win_get_cursor(opts.winnr)[1]
local params = vim.lsp.util.make_position_params(opts.winnr)
local include_current_line = vim.F.if_nil(opts.include_current_line, false)
params.context = { includeDeclaration = vim.F.if_nil(opts.include_declaration, true) }
vim.lsp.buf_request(opts.bufnr, "textDocument/references", params, function(err, result, ctx, _)
if err then
vim.api.nvim_err_writeln("Error when finding references: " .. err.message)
return
end
local locations = {}
if result then
local results = vim.lsp.util.locations_to_items(result, vim.lsp.get_client_by_id(ctx.client_id).offset_encoding)
if include_current_line then
locations = vim.tbl_filter(function(v)
-- Remove current line from result
return not (v.filename == filepath and v.lnum == lnum)
end, vim.F.if_nil(results, {}))
else
locations = vim.F.if_nil(results, {})
end
end
if vim.tbl_isempty(locations) then
return
end
pickers.new(opts, {
prompt_title = "LSP References",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
local function call_hierarchy(opts, method, title, direction, item)
vim.lsp.buf_request(opts.bufnr, method, { item = item }, function(err, result)
if err then
vim.api.nvim_err_writeln("Error handling " .. title .. ": " .. err)
return
end
if not result or vim.tbl_isempty(result) then
return
end
local locations = {}
for _, ch_call in pairs(result) do
local ch_item = ch_call[direction]
for _, range in pairs(ch_call.fromRanges) do
table.insert(locations, {
filename = vim.uri_to_fname(ch_item.uri),
text = ch_item.name,
lnum = range.start.line + 1,
col = range.start.character + 1,
})
end
end
pickers.new(opts, {
prompt_title = title,
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then
return
end
if #call_hierarchy_items == 1 then
return call_hierarchy_items[1]
end
local items = {}
for i, item in pairs(call_hierarchy_items) do
local entry = item.detail or item.name
table.insert(items, string.format("%d. %s", i, entry))
end
local choice = vim.fn.inputlist(items)
if choice < 1 or choice > #items then
return
end
return choice
end
local function calls(opts, direction)
local params = vim.lsp.util.make_position_params()
vim.lsp.buf_request(opts.bufnr, "textDocument/prepareCallHierarchy", params, function(err, result)
if err then
vim.api.nvim_err_writeln("Error when preparing call hierarchy: " .. err)
return
end
local call_hierarchy_item = pick_call_hierarchy_item(result)
if not call_hierarchy_item then
return
end
if direction == "from" then
call_hierarchy(opts, "callHierarchy/incomingCalls", "LSP Incoming Calls", direction, call_hierarchy_item)
else
call_hierarchy(opts, "callHierarchy/outgoingCalls", "LSP Outgoing Calls", direction, call_hierarchy_item)
end
end)
end
lsp.incoming_calls = function(opts)
calls(opts, "from")
end
lsp.outgoing_calls = function(opts)
calls(opts, "to")
end
local function list_or_jump(action, title, opts)
local params = vim.lsp.util.make_position_params(opts.winnr)
vim.lsp.buf_request(opts.bufnr, action, params, function(err, result, ctx, _)
if err then
vim.api.nvim_err_writeln("Error when executing " .. action .. " : " .. err.message)
return
end
local flattened_results = {}
if result then
-- textDocument/definition can return Location or Location[]
if not vim.tbl_islist(result) then
flattened_results = { result }
end
vim.list_extend(flattened_results, result)
end
local offset_encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding
if #flattened_results == 0 then
return
elseif #flattened_results == 1 and opts.jump_type ~= "never" then
if opts.jump_type == "tab" then
vim.cmd "tabedit"
elseif opts.jump_type == "split" then
vim.cmd "new"
elseif opts.jump_type == "vsplit" then
vim.cmd "vnew"
end
vim.lsp.util.jump_to_location(flattened_results[1], offset_encoding)
else
local locations = vim.lsp.util.locations_to_items(flattened_results, offset_encoding)
pickers.new(opts, {
prompt_title = title,
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end
end)
end
lsp.definitions = function(opts)
return list_or_jump("textDocument/definition", "LSP Definitions", opts)
end
lsp.type_definitions = function(opts)
return list_or_jump("textDocument/typeDefinition", "LSP Type Definitions", opts)
end
lsp.implementations = function(opts)
return list_or_jump("textDocument/implementation", "LSP Implementations", opts)
end
lsp.document_symbols = function(opts)
local params = vim.lsp.util.make_position_params(opts.winnr)
vim.lsp.buf_request(opts.bufnr, "textDocument/documentSymbol", params, function(err, result, _, _)
if err then
vim.api.nvim_err_writeln("Error when finding document symbols: " .. err.message)
return
end
if not result or vim.tbl_isempty(result) then
utils.notify("builtin.lsp_document_symbols", {
msg = "No results from textDocument/documentSymbol",
level = "INFO",
})
return
end
local locations = vim.lsp.util.symbols_to_items(result or {}, opts.bufnr) or {}
locations = utils.filter_symbols(locations, opts)
if locations == nil then
-- error message already printed in `utils.filter_symbols`
return
end
if vim.tbl_isempty(locations) then
utils.notify("builtin.lsp_document_symbols", {
msg = "No document_symbol locations found",
level = "INFO",
})
return
end
opts.path_display = { "hidden" }
pickers.new(opts, {
prompt_title = "LSP Document Symbols",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "symbol_type",
sorter = conf.generic_sorter(opts),
},
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
lsp.workspace_symbols = function(opts)
local params = { query = opts.query or "" }
vim.lsp.buf_request(opts.bufnr, "workspace/symbol", params, function(err, server_result, _, _)
if err then
vim.api.nvim_err_writeln("Error when finding workspace symbols: " .. err.message)
return
end
local locations = vim.lsp.util.symbols_to_items(server_result or {}, opts.bufnr) or {}
locations = utils.filter_symbols(locations, opts)
if locations == nil then
-- error message already printed in `utils.filter_symbols`
return
end
if vim.tbl_isempty(locations) then
utils.notify("builtin.lsp_workspace_symbols", {
msg = "No results from workspace/symbol. Maybe try a different query: "
.. "'Telescope lsp_workspace_symbols query=example'",
level = "INFO",
})
return
end
opts.ignore_filename = vim.F.if_nil(opts.ignore_filename, false)
pickers.new(opts, {
prompt_title = "LSP Workspace Symbols",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "symbol_type",
sorter = conf.generic_sorter(opts),
},
}):find()
end)
end
local function get_workspace_symbols_requester(bufnr, opts)
local cancel = function() end
return function(prompt)
local tx, rx = channel.oneshot()
cancel()
_, cancel = vim.lsp.buf_request(bufnr, "workspace/symbol", { query = prompt }, tx)
-- Handle 0.5 / 0.5.1 handler situation
local err, res = rx()
assert(not err, err)
local locations = vim.lsp.util.symbols_to_items(res or {}, bufnr) or {}
if not vim.tbl_isempty(locations) then
locations = utils.filter_symbols(locations, opts) or {}
end
return locations
end
end
lsp.dynamic_workspace_symbols = function(opts)
pickers.new(opts, {
prompt_title = "LSP Dynamic Workspace Symbols",
finder = finders.new_dynamic {
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
fn = get_workspace_symbols_requester(opts.bufnr, opts),
},
previewer = conf.qflist_previewer(opts),
sorter = sorters.highlighter_only(opts),
attach_mappings = function(_, map)
map("i", "<c-space>", function(prompt_bufnr)
local line = action_state.get_current_line()
require("telescope.actions.generate").refine(prompt_bufnr, {
prompt_title = "LSP Workspace Symbols (" .. line .. ")",
sorter = conf.generic_sorter(opts),
})
end)
return true
end,
}):find()
end
local function check_capabilities(feature, bufnr)
local clients = vim.lsp.buf_get_clients(bufnr)
local supported_client = false
for _, client in pairs(clients) do
supported_client = client.server_capabilities[feature]
if supported_client then
break
end
end
if supported_client then
return true
else
if #clients == 0 then
utils.notify("builtin.lsp_*", {
msg = "no client attached",
level = "INFO",
})
else
utils.notify("builtin.lsp_*", {
msg = "server does not support " .. feature,
level = "INFO",
})
end
return false
end
end
local feature_map = {
["document_symbols"] = "documentSymbolProvider",
["references"] = "referencesProvider",
["definitions"] = "definitionProvider",
["type_definitions"] = "typeDefinitionProvider",
["implementations"] = "implementationProvider",
["workspace_symbols"] = "workspaceSymbolProvider",
["incoming_calls"] = "callHierarchyProvider",
["outgoing_calls"] = "callHierarchyProvider",
}
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
local feature_name = feature_map[k]
if feature_name and not check_capabilities(feature_name, opts.bufnr) then
return
end
v(opts)
end
end
return mod
end
return apply_checks(lsp)

View File

@@ -1,150 +1,17 @@
local conf = require("telescope.config").values local m = setmetatable({}, {
local finders = require "telescope.finders" __index = function(_, k)
local make_entry = require "telescope.make_entry" local utils = require "telescope.utils"
local pickers = require "telescope.pickers" utils.notify("builtin", {
local utils = require "telescope.utils" msg = string.format(
'You are using an internal interface. Do not use `require("telescope.builtin.diagnostics").%s`,'
local diagnostics = {} .. ' please use `require("telescope.builtin").diagnostics`! We will remove this endpoint soon!',
k,
local convert_diagnostic_type = function(severities, severity) k
-- convert from string to int ),
if type(severity) == "string" then
-- make sure that e.g. error is uppercased to ERROR
return severities[severity:upper()]
end
-- otherwise keep original value, incl. nil
return severity
end
local diagnostics_to_tbl = function(opts)
opts = vim.F.if_nil(opts, {})
local items = {}
local severities = vim.diagnostic.severity
local current_buf = vim.api.nvim_get_current_buf()
opts.severity = convert_diagnostic_type(severities, opts.severity)
opts.severity_limit = convert_diagnostic_type(severities, opts.severity_limit)
opts.severity_bound = convert_diagnostic_type(severities, opts.severity_bound)
local diagnosis_opts = { severity = {}, namespace = opts.namespace }
if opts.severity ~= nil then
if opts.severity_limit ~= nil or opts.severity_bound ~= nil then
utils.notify("builtin.diagnostics", {
msg = "Invalid severity parameters. Both a specific severity and a limit/bound is not allowed",
level = "ERROR", level = "ERROR",
}) })
return {} return require("telescope.builtin").diagnostics
end end,
diagnosis_opts.severity = opts.severity })
else
if opts.severity_limit ~= nil then
diagnosis_opts.severity["min"] = opts.severity_limit
end
if opts.severity_bound ~= nil then
diagnosis_opts.severity["max"] = opts.severity_bound
end
end
opts.root_dir = opts.root_dir == true and vim.loop.cwd() or opts.root_dir return m
local bufnr_name_map = {}
local filter_diag = function(diagnostic)
if bufnr_name_map[diagnostic.bufnr] == nil then
bufnr_name_map[diagnostic.bufnr] = vim.api.nvim_buf_get_name(diagnostic.bufnr)
end
local root_dir_test = not opts.root_dir
or string.sub(bufnr_name_map[diagnostic.bufnr], 1, #opts.root_dir) == opts.root_dir
local listed_test = not opts.no_unlisted or vim.api.nvim_buf_get_option(diagnostic.bufnr, "buflisted")
return root_dir_test and listed_test
end
local preprocess_diag = function(diagnostic)
return {
bufnr = diagnostic.bufnr,
filename = bufnr_name_map[diagnostic.bufnr],
lnum = diagnostic.lnum + 1,
col = diagnostic.col + 1,
text = vim.trim(diagnostic.message:gsub("[\n]", "")),
type = severities[diagnostic.severity] or severities[1],
}
end
for _, d in ipairs(vim.diagnostic.get(opts.bufnr, diagnosis_opts)) do
if filter_diag(d) then
table.insert(items, preprocess_diag(d))
end
end
-- sort results by bufnr (prioritize cur buf), severity, lnum
table.sort(items, function(a, b)
if a.bufnr == b.bufnr then
if a.type == b.type then
return a.lnum < b.lnum
else
return a.type < b.type
end
else
-- prioritize for current bufnr
if a.bufnr == current_buf then
return true
end
if b.bufnr == current_buf then
return false
end
return a.bufnr < b.bufnr
end
end)
return items
end
diagnostics.get = function(opts)
if opts.bufnr ~= 0 then
opts.bufnr = nil
end
if opts.bufnr == nil then
opts.path_display = vim.F.if_nil(opts.path_display, {})
end
if type(opts.bufnr) == "string" then
opts.bufnr = tonumber(opts.bufnr)
end
local locations = diagnostics_to_tbl(opts)
if vim.tbl_isempty(locations) then
utils.notify("builtin.diagnostics", {
msg = "No diagnostics found",
level = "INFO",
})
return
end
opts.path_display = vim.F.if_nil(opts.path_display, "hidden")
pickers.new(opts, {
prompt_title = opts.bufnr == nil and "Workspace Diagnostics" or "Document Diagnostics",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_diagnostics(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "type",
sorter = conf.generic_sorter(opts),
},
}):find()
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
v(opts)
end
end
return mod
end
return apply_checks(diagnostics)

View File

@@ -1,484 +1,17 @@
local action_state = require "telescope.actions.state" local m = setmetatable({}, {
local action_set = require "telescope.actions.set" __index = function(_, k)
local finders = require "telescope.finders" local utils = require "telescope.utils"
local make_entry = require "telescope.make_entry" utils.notify("builtin", {
local pickers = require "telescope.pickers" msg = string.format(
local previewers = require "telescope.previewers" 'You are using an internal interface. Do not use `require("telescope.builtin.files").%s`,'
local sorters = require "telescope.sorters" .. ' please use `require("telescope.builtin").%s`! We will remove this endpoint soon!',
local utils = require "telescope.utils" k,
local conf = require("telescope.config").values k
local log = require "telescope.log" ),
local Path = require "plenary.path"
local flatten = vim.tbl_flatten
local filter = vim.tbl_filter
local files = {}
local escape_chars = function(string)
return string.gsub(string, "[%(|%)|\\|%[|%]|%-|%{%}|%?|%+|%*|%^|%$|%.]", {
["\\"] = "\\\\",
["-"] = "\\-",
["("] = "\\(",
[")"] = "\\)",
["["] = "\\[",
["]"] = "\\]",
["{"] = "\\{",
["}"] = "\\}",
["?"] = "\\?",
["+"] = "\\+",
["*"] = "\\*",
["^"] = "\\^",
["$"] = "\\$",
["."] = "\\.",
})
end
-- Special keys:
-- opts.search_dirs -- list of directory to search in
-- opts.grep_open_files -- boolean to restrict search to open files
files.live_grep = function(opts)
local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
local search_dirs = opts.search_dirs
local grep_open_files = opts.grep_open_files
opts.cwd = opts.cwd and vim.fn.expand(opts.cwd) or vim.loop.cwd()
local filelist = {}
if grep_open_files then
local bufnrs = filter(function(b)
if 1 ~= vim.fn.buflisted(b) then
return false
end
return true
end, vim.api.nvim_list_bufs())
if not next(bufnrs) then
return
end
for _, bufnr in ipairs(bufnrs) do
local file = vim.api.nvim_buf_get_name(bufnr)
table.insert(filelist, Path:new(file):make_relative(opts.cwd))
end
elseif search_dirs then
for i, path in ipairs(search_dirs) do
search_dirs[i] = vim.fn.expand(path)
end
end
local additional_args = {}
if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
additional_args = opts.additional_args(opts)
end
if opts.type_filter then
additional_args[#additional_args + 1] = "--type=" .. opts.type_filter
end
if opts.glob_pattern then
additional_args[#additional_args + 1] = "--glob=" .. opts.glob_pattern
end
local live_grepper = finders.new_job(function(prompt)
-- TODO: Probably could add some options for smart case and whatever else rg offers.
if not prompt or prompt == "" then
return nil
end
local search_list = {}
if search_dirs then
table.insert(search_list, search_dirs)
end
if grep_open_files then
search_list = filelist
end
return flatten { vimgrep_arguments, additional_args, "--", prompt, search_list }
end, opts.entry_maker or make_entry.gen_from_vimgrep(opts), opts.max_results, opts.cwd)
pickers.new(opts, {
prompt_title = "Live Grep",
finder = live_grepper,
previewer = conf.grep_previewer(opts),
-- TODO: It would be cool to use `--json` output for this
-- and then we could get the highlight positions directly.
sorter = sorters.highlighter_only(opts),
}):find()
end
-- Special keys:
-- opts.search -- the string to search.
-- opts.search_dirs -- list of directory to search in
-- opts.use_regex -- special characters won't be escaped
files.grep_string = function(opts)
-- TODO: This should probably check your visual selection as well, if you've got one
local vimgrep_arguments = opts.vimgrep_arguments or conf.vimgrep_arguments
local search_dirs = opts.search_dirs
local word = opts.search or vim.fn.expand "<cword>"
local search = opts.use_regex and word or escape_chars(word)
local word_match = opts.word_match
opts.entry_maker = opts.entry_maker or make_entry.gen_from_vimgrep(opts)
local title_word = word:gsub("\n", "\\n")
local additional_args = {}
if opts.additional_args ~= nil and type(opts.additional_args) == "function" then
additional_args = opts.additional_args(opts)
end
local args = flatten {
vimgrep_arguments,
additional_args,
word_match,
"--",
search,
}
if search_dirs then
for _, path in ipairs(search_dirs) do
table.insert(args, vim.fn.expand(path))
end
end
pickers.new(opts, {
prompt_title = "Find Word (" .. title_word .. ")",
finder = finders.new_oneshot_job(args, opts),
previewer = conf.grep_previewer(opts),
sorter = conf.generic_sorter(opts),
}):find()
end
-- TODO: Maybe just change this to `find`.
-- TODO: Support `find` and maybe let people do other stuff with it as well.
files.find_files = function(opts)
local find_command = (function()
if opts.find_command then
return opts.find_command
elseif 1 == vim.fn.executable "fd" then
return { "fd", "--type", "f" }
elseif 1 == vim.fn.executable "fdfind" then
return { "fdfind", "--type", "f" }
elseif 1 == vim.fn.executable "rg" then
return { "rg", "--files" }
elseif 1 == vim.fn.executable "find" and vim.fn.has "win32" == 0 then
return { "find", ".", "-type", "f" }
elseif 1 == vim.fn.executable "where" then
return { "where", "/r", ".", "*" }
end
end)()
if not find_command then
utils.notify("builtin.find_files", {
msg = "You need to install either find, fd, or rg",
level = "ERROR", level = "ERROR",
}) })
return return require("telescope.builtin")[k]
end
local command = find_command[1]
local hidden = opts.hidden
local no_ignore = opts.no_ignore
local follow = opts.follow
local search_dirs = opts.search_dirs
if search_dirs then
for k, v in pairs(search_dirs) do
search_dirs[k] = vim.fn.expand(v)
end
end
if command == "fd" or command == "fdfind" or command == "rg" then
if hidden then
table.insert(find_command, "--hidden")
end
if no_ignore then
table.insert(find_command, "--no-ignore")
end
if follow then
table.insert(find_command, "-L")
end
if search_dirs then
if command ~= "rg" then
table.insert(find_command, ".")
end
for _, v in pairs(search_dirs) do
table.insert(find_command, v)
end
end
elseif command == "find" then
if not hidden then
table.insert(find_command, { "-not", "-path", "*/.*" })
find_command = flatten(find_command)
end
if no_ignore ~= nil then
log.warn "The `no_ignore` key is not available for the `find` command in `find_files`."
end
if follow then
table.insert(find_command, 2, "-L")
end
if search_dirs then
table.remove(find_command, 2)
for _, v in pairs(search_dirs) do
table.insert(find_command, 2, v)
end
end
elseif command == "where" then
if hidden ~= nil then
log.warn "The `hidden` key is not available for the Windows `where` command in `find_files`."
end
if no_ignore ~= nil then
log.warn "The `no_ignore` key is not available for the Windows `where` command in `find_files`."
end
if follow ~= nil then
log.warn "The `follow` key is not available for the Windows `where` command in `find_files`."
end
if search_dirs ~= nil then
log.warn "The `search_dirs` key is not available for the Windows `where` command in `find_files`."
end
end
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
end
opts.entry_maker = opts.entry_maker or make_entry.gen_from_file(opts)
pickers.new(opts, {
prompt_title = "Find Files",
finder = finders.new_oneshot_job(find_command, opts),
previewer = conf.file_previewer(opts),
sorter = conf.file_sorter(opts),
}):find()
end
local function prepare_match(entry, kind)
local entries = {}
if entry.node then
table.insert(entries, entry)
else
for name, item in pairs(entry) do
vim.list_extend(entries, prepare_match(item, name))
end
end
return entries
end
-- TODO: finish docs for opts.show_line
files.treesitter = function(opts)
opts.show_line = utils.get_default(opts.show_line, true)
local has_nvim_treesitter, _ = pcall(require, "nvim-treesitter")
if not has_nvim_treesitter then
utils.notify("builtin.treesitter", {
msg = "User need to install nvim-treesitter needs to be installed",
level = "ERROR",
})
return
end
local parsers = require "nvim-treesitter.parsers"
if not parsers.has_parser(parsers.get_buf_lang(opts.bufnr)) then
utils.notify("builtin.treesitter", {
msg = "No parser for the current buffer",
level = "ERROR",
})
return
end
local ts_locals = require "nvim-treesitter.locals"
local results = {}
for _, definition in ipairs(ts_locals.get_definitions(opts.bufnr)) do
local entries = prepare_match(ts_locals.get_local_nodes(definition))
for _, entry in ipairs(entries) do
entry.kind = vim.F.if_nil(entry.kind, "")
table.insert(results, entry)
end
end
if vim.tbl_isempty(results) then
return
end
pickers.new(opts, {
prompt_title = "Treesitter Symbols",
finder = finders.new_table {
results = results,
entry_maker = opts.entry_maker or make_entry.gen_from_treesitter(opts),
},
previewer = conf.grep_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "kind",
sorter = conf.generic_sorter(opts),
},
}):find()
end
files.current_buffer_fuzzy_find = function(opts)
-- All actions are on the current buffer
local filename = vim.fn.expand(vim.api.nvim_buf_get_name(opts.bufnr))
local filetype = vim.api.nvim_buf_get_option(opts.bufnr, "filetype")
local lines = vim.api.nvim_buf_get_lines(opts.bufnr, 0, -1, false)
local lines_with_numbers = {}
for lnum, line in ipairs(lines) do
table.insert(lines_with_numbers, {
lnum = lnum,
bufnr = opts.bufnr,
filename = filename,
text = line,
})
end
local ts_ok, ts_parsers = pcall(require, "nvim-treesitter.parsers")
if ts_ok then
filetype = ts_parsers.ft_to_lang(filetype)
end
local _, ts_configs = pcall(require, "nvim-treesitter.configs")
local parser_ok, parser = pcall(vim.treesitter.get_parser, opts.bufnr, filetype)
local query_ok, query = pcall(vim.treesitter.get_query, filetype, "highlights")
if parser_ok and query_ok and ts_ok and ts_configs.is_enabled("highlight", filetype, opts.bufnr) then
local root = parser:parse()[1]:root()
local highlighter = vim.treesitter.highlighter.new(parser)
local highlighter_query = highlighter:get_query(filetype)
local line_highlights = setmetatable({}, {
__index = function(t, k)
local obj = {}
rawset(t, k, obj)
return obj
end, end,
}) })
for id, node in query:iter_captures(root, opts.bufnr, 0, -1) do
local hl = highlighter_query:_get_hl_from_capture(id)
if hl and type(hl) ~= "number" then
local row1, col1, row2, col2 = node:range()
if row1 == row2 then return m
local row = row1 + 1
for index = col1, col2 do
line_highlights[row][index] = hl
end
else
local row = row1 + 1
for index = col1, #lines[row] do
line_highlights[row][index] = hl
end
while row < row2 + 1 do
row = row + 1
for index = 0, #(lines[row] or {}) do
line_highlights[row][index] = hl
end
end
end
end
end
opts.line_highlights = line_highlights
end
pickers.new(opts, {
prompt_title = "Current Buffer Fuzzy",
finder = finders.new_table {
results = lines_with_numbers,
entry_maker = opts.entry_maker or make_entry.gen_from_buffer_lines(opts),
},
sorter = conf.generic_sorter(opts),
previewer = conf.grep_previewer(opts),
attach_mappings = function()
action_set.select:enhance {
post = function()
local selection = action_state.get_selected_entry()
vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
end,
}
return true
end,
}):find()
end
files.tags = function(opts)
local tagfiles = opts.ctags_file and { opts.ctags_file } or vim.fn.tagfiles()
if vim.tbl_isempty(tagfiles) then
utils.notify("builtin.tags", {
msg = "No tags file found. Create one with ctags -R",
level = "ERROR",
})
return
end
local results = {}
for _, ctags_file in ipairs(tagfiles) do
for line in Path:new(vim.fn.expand(ctags_file, true)):iter() do
results[#results + 1] = line
end
end
pickers.new(opts, {
prompt_title = "Tags",
finder = finders.new_table {
results = results,
entry_maker = opts.entry_maker or make_entry.gen_from_ctags(opts),
},
previewer = previewers.ctags.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function()
action_set.select:enhance {
post = function()
local selection = action_state.get_selected_entry()
if selection.scode then
-- un-escape / then escape required
-- special chars for vim.fn.search()
-- ] ~ *
local scode = selection.scode:gsub([[\/]], "/"):gsub("[%]~*]", function(x)
return "\\" .. x
end)
vim.cmd "norm! gg"
vim.fn.search(scode)
vim.cmd "norm! zz"
else
vim.api.nvim_win_set_cursor(0, { selection.lnum, 0 })
end
end,
}
return true
end,
}):find()
end
files.current_buffer_tags = function(opts)
return files.tags(vim.tbl_extend("force", {
prompt_title = "Current Buffer Tags",
only_current_file = true,
path_display = "hidden",
}, opts))
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
v(opts)
end
end
return mod
end
return apply_checks(files)

View File

@@ -1,408 +1,17 @@
local actions = require "telescope.actions" local m = setmetatable({}, {
local action_state = require "telescope.actions.state" __index = function(_, k)
local finders = require "telescope.finders" local utils = require "telescope.utils"
local make_entry = require "telescope.make_entry" utils.notify("builtin", {
local pickers = require "telescope.pickers" msg = string.format(
local previewers = require "telescope.previewers" 'You are using an internal interface. Do not use `require("telescope.builtin.git").%s`,'
local utils = require "telescope.utils" .. ' please use `require("telescope.builtin").git_%s`! We will remove this endpoint soon!',
local entry_display = require "telescope.pickers.entry_display" k,
local strings = require "plenary.strings" k
local Path = require "plenary.path" ),
local conf = require("telescope.config").values
local git = {}
git.files = function(opts)
if opts.is_bare then
utils.notify("builtin.git_files", {
msg = "This operation must be run in a work tree",
level = "ERROR", level = "ERROR",
}) })
return return require("telescope.builtin")["git_" .. k]
end
local show_untracked = utils.get_default(opts.show_untracked, true)
local recurse_submodules = utils.get_default(opts.recurse_submodules, false)
if show_untracked and recurse_submodules then
utils.notify("builtin.git_files", {
msg = "Git does not support both --others and --recurse-submodules",
level = "ERROR",
})
return
end
-- By creating the entry maker after the cwd options,
-- we ensure the maker uses the cwd options when being created.
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_file(opts))
local git_command = vim.F.if_nil(opts.git_command, { "git", "ls-files", "--exclude-standard", "--cached" })
pickers.new(opts, {
prompt_title = "Git Files",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
git_command,
show_untracked and "--others" or nil,
recurse_submodules and "--recurse-submodules" or nil,
},
opts
),
previewer = conf.file_previewer(opts),
sorter = conf.file_sorter(opts),
}):find()
end
git.commits = function(opts)
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_commits(opts))
local git_command = vim.F.if_nil(opts.git_command, { "git", "log", "--pretty=oneline", "--abbrev-commit", "--", "." })
pickers.new(opts, {
prompt_title = "Git Commits",
finder = finders.new_oneshot_job(git_command, opts),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function(_, map)
actions.select_default:replace(actions.git_checkout)
map("i", "<c-r>m", actions.git_reset_mixed)
map("n", "<c-r>m", actions.git_reset_mixed)
map("i", "<c-r>s", actions.git_reset_soft)
map("n", "<c-r>s", actions.git_reset_soft)
map("i", "<c-r>h", actions.git_reset_hard)
map("n", "<c-r>h", actions.git_reset_hard)
return true
end, end,
}):find() })
end
git.stash = function(opts) return m
opts.show_branch = vim.F.if_nil(opts.show_branch, true)
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_stash(opts))
pickers.new(opts, {
prompt_title = "Git Stash",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
"git",
"--no-pager",
"stash",
"list",
},
opts
),
previewer = previewers.git_stash_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_apply_stash)
return true
end,
}):find()
end
local get_current_buf_line = function(winnr)
local lnum = vim.api.nvim_win_get_cursor(winnr)[1]
return vim.trim(vim.api.nvim_buf_get_lines(vim.api.nvim_win_get_buf(winnr), lnum - 1, lnum, false)[1])
end
git.bcommits = function(opts)
opts.current_line = (opts.current_file == nil) and get_current_buf_line(opts.winnr) or nil
opts.current_file = vim.F.if_nil(opts.current_file, vim.api.nvim_buf_get_name(opts.bufnr))
opts.entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_commits(opts))
local git_command = vim.F.if_nil(opts.git_command, { "git", "log", "--pretty=oneline", "--abbrev-commit" })
pickers.new(opts, {
prompt_title = "Git BCommits",
finder = finders.new_oneshot_job(
vim.tbl_flatten {
git_command,
opts.current_file,
},
opts
),
previewer = {
previewers.git_commit_diff_to_parent.new(opts),
previewers.git_commit_diff_to_head.new(opts),
previewers.git_commit_diff_as_was.new(opts),
previewers.git_commit_message.new(opts),
},
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.select_default:replace(actions.git_checkout_current_buffer)
local transfrom_file = function()
return opts.current_file and Path:new(opts.current_file):make_relative(opts.cwd) or ""
end
local get_buffer_of_orig = function(selection)
local value = selection.value .. ":" .. transfrom_file()
local content = utils.get_os_command_output({ "git", "--no-pager", "show", value }, opts.cwd)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, content)
vim.api.nvim_buf_set_name(bufnr, "Original")
return bufnr
end
local vimdiff = function(selection, command)
local ft = vim.bo.filetype
vim.cmd "diffthis"
local bufnr = get_buffer_of_orig(selection)
vim.cmd(string.format("%s %s", command, bufnr))
vim.bo.filetype = ft
vim.cmd "diffthis"
vim.api.nvim_create_autocmd("WinClosed", {
buffer = bufnr,
nested = true,
once = true,
callback = function()
vim.api.nvim_buf_delete(bufnr, { force = true })
end,
})
end
actions.select_vertical:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, "leftabove vert sbuffer")
end)
actions.select_horizontal:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vimdiff(selection, "belowright sbuffer")
end)
actions.select_tab:replace(function(prompt_bufnr)
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
vim.cmd("tabedit " .. transfrom_file())
vimdiff(selection, "leftabove vert sbuffer")
end)
return true
end,
}):find()
end
git.branches = function(opts)
local format = "%(HEAD)"
.. "%(refname)"
.. "%(authorname)"
.. "%(upstream:lstrip=2)"
.. "%(committerdate:format-local:%Y/%m/%d %H:%M:%S)"
local output = utils.get_os_command_output(
{ "git", "for-each-ref", "--perl", "--format", format, opts.pattern },
opts.cwd
)
local results = {}
local widths = {
name = 0,
authorname = 0,
upstream = 0,
committerdate = 0,
}
local unescape_single_quote = function(v)
return string.gsub(v, "\\([\\'])", "%1")
end
local parse_line = function(line)
local fields = vim.split(string.sub(line, 2, -2), "''", true)
local entry = {
head = fields[1],
refname = unescape_single_quote(fields[2]),
authorname = unescape_single_quote(fields[3]),
upstream = unescape_single_quote(fields[4]),
committerdate = fields[5],
}
local prefix
if vim.startswith(entry.refname, "refs/remotes/") then
prefix = "refs/remotes/"
elseif vim.startswith(entry.refname, "refs/heads/") then
prefix = "refs/heads/"
else
return
end
local index = 1
if entry.head ~= "*" then
index = #results + 1
end
entry.name = string.sub(entry.refname, string.len(prefix) + 1)
for key, value in pairs(widths) do
widths[key] = math.max(value, strings.strdisplaywidth(entry[key] or ""))
end
if string.len(entry.upstream) > 0 then
widths.upstream_indicator = 2
end
table.insert(results, index, entry)
end
for _, line in ipairs(output) do
parse_line(line)
end
if #results == 0 then
return
end
local displayer = entry_display.create {
separator = " ",
items = {
{ width = 1 },
{ width = widths.name },
{ width = widths.authorname },
{ width = widths.upstream_indicator },
{ width = widths.upstream },
{ width = widths.committerdate },
},
}
local make_display = function(entry)
return displayer {
{ entry.head },
{ entry.name, "TelescopeResultsIdentifier" },
{ entry.authorname },
{ string.len(entry.upstream) > 0 and "=>" or "" },
{ entry.upstream, "TelescopeResultsIdentifier" },
{ entry.committerdate },
}
end
pickers.new(opts, {
prompt_title = "Git Branches",
finder = finders.new_table {
results = results,
entry_maker = function(entry)
entry.value = entry.name
entry.ordinal = entry.name
entry.display = make_display
return entry
end,
},
previewer = previewers.git_branch_log.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function(_, map)
actions.select_default:replace(actions.git_checkout)
map("i", "<c-t>", actions.git_track_branch)
map("n", "<c-t>", actions.git_track_branch)
map("i", "<c-r>", actions.git_rebase_branch)
map("n", "<c-r>", actions.git_rebase_branch)
map("i", "<c-a>", actions.git_create_branch)
map("n", "<c-a>", actions.git_create_branch)
map("i", "<c-s>", actions.git_switch_branch)
map("n", "<c-s>", actions.git_switch_branch)
map("i", "<c-d>", actions.git_delete_branch)
map("n", "<c-d>", actions.git_delete_branch)
map("i", "<c-y>", actions.git_merge_branch)
map("n", "<c-y>", actions.git_merge_branch)
return true
end,
}):find()
end
git.status = function(opts)
if opts.is_bare then
utils.notify("builtin.git_status", {
msg = "This operation must be run in a work tree",
level = "ERROR",
})
return
end
local gen_new_finder = function()
local expand_dir = utils.if_nil(opts.expand_dir, true, opts.expand_dir)
local git_cmd = { "git", "status", "-s", "--", "." }
if expand_dir then
table.insert(git_cmd, #git_cmd - 1, "-u")
end
local output = utils.get_os_command_output(git_cmd, opts.cwd)
if #output == 0 then
print "No changes found"
utils.notify("builtin.git_status", {
msg = "No changes found",
level = "WARN",
})
return
end
return finders.new_table {
results = output,
entry_maker = vim.F.if_nil(opts.entry_maker, make_entry.gen_from_git_status(opts)),
}
end
local initial_finder = gen_new_finder()
if not initial_finder then
return
end
pickers.new(opts, {
prompt_title = "Git Status",
finder = initial_finder,
previewer = previewers.git_file_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function(prompt_bufnr, map)
actions.git_staging_toggle:enhance {
post = function()
action_state.get_current_picker(prompt_bufnr):refresh(gen_new_finder(), { reset_prompt = true })
end,
}
map("i", "<tab>", actions.git_staging_toggle)
map("n", "<tab>", actions.git_staging_toggle)
return true
end,
}):find()
end
local set_opts_cwd = function(opts)
if opts.cwd then
opts.cwd = vim.fn.expand(opts.cwd)
else
opts.cwd = vim.loop.cwd()
end
-- Find root of git directory and remove trailing newline characters
local git_root, ret = utils.get_os_command_output({ "git", "rev-parse", "--show-toplevel" }, opts.cwd)
local use_git_root = utils.get_default(opts.use_git_root, true)
if ret ~= 0 then
local in_worktree = utils.get_os_command_output({ "git", "rev-parse", "--is-inside-work-tree" }, opts.cwd)
local in_bare = utils.get_os_command_output({ "git", "rev-parse", "--is-bare-repository" }, opts.cwd)
if in_worktree[1] ~= "true" and in_bare[1] ~= "true" then
error(opts.cwd .. " is not a git directory")
elseif in_worktree[1] ~= "true" and in_bare[1] == "true" then
opts.is_bare = true
end
else
if use_git_root then
opts.cwd = git_root[1]
end
end
end
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = vim.F.if_nil(opts, {})
set_opts_cwd(opts)
v(opts)
end
end
return mod
end
return apply_checks(git)

View File

@@ -54,35 +54,37 @@ end
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer) ---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer)
---@field grep_open_files boolean: if true, restrict search to open files only, mutually exclusive with `search_dirs` ---@field grep_open_files boolean: if true, restrict search to open files only, mutually exclusive with `search_dirs`
---@field search_dirs table: directory/directories to search in, mutually exclusive with `grep_open_files` ---@field search_dirs table: directory/directories/files to search, mutually exclusive with `grep_open_files`
---@field glob_pattern string: argument to be used with `--glob`, e.g. "*.toml", can use the opposite "!*.toml" ---@field glob_pattern string|table: argument to be used with `--glob`, e.g. "*.toml", can use the opposite "!*.toml"
---@field type_filter string: argument to be used with `--type`, e.g. "rust", see `rg --type-list` ---@field type_filter string: argument to be used with `--type`, e.g. "rust", see `rg --type-list`
---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on ---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on
---@field max_results number: define a upper result value ---@field max_results number: define a upper result value
---@field disable_coordinates boolean: don't show the line & row numbers (default: false) ---@field disable_coordinates boolean: don't show the line & row numbers (default: false)
builtin.live_grep = require_on_exported_call("telescope.builtin.files").live_grep builtin.live_grep = require_on_exported_call("telescope.builtin.__files").live_grep
--- Searches for the string under your cursor in your current working directory --- Searches for the string under your cursor in your current working directory
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer) ---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer)
---@field search string: the query to search ---@field search string: the query to search
---@field search_dirs table: directory/directories to search in ---@field search_dirs table: directory/directories/files to search
---@field use_regex boolean: if true, special characters won't be escaped, allows for using regex (default: false) ---@field use_regex boolean: if true, special characters won't be escaped, allows for using regex (default: false)
---@field word_match string: can be set to `-w` to enable exact word matches ---@field word_match string: can be set to `-w` to enable exact word matches
---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on ---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on
---@field disable_coordinates boolean: don't show the line and row numbers (default: false) ---@field disable_coordinates boolean: don't show the line and row numbers (default: false)
---@field only_sort_text boolean: only sort the text, not the file, line or row (default: false) ---@field only_sort_text boolean: only sort the text, not the file, line or row (default: false)
builtin.grep_string = require_on_exported_call("telescope.builtin.files").grep_string builtin.grep_string = require_on_exported_call("telescope.builtin.__files").grep_string
--- Search for files (respecting .gitignore) --- Search for files (respecting .gitignore)
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer) ---@field cwd string: root dir to search from (default: cwd, use utils.buffer_dir() to search relative to open buffer)
---@field find_command table: command line arguments for `find_files` to use for the search, overrides default: config ---@field find_command function|table: cmd to use for the search. Can be a fn(opts) -> tbl (default: autodetect)
---@field follow boolean: if true, follows symlinks (i.e. uses `-L` flag for the `find` command) ---@field follow boolean: if true, follows symlinks (i.e. uses `-L` flag for the `find` command)
---@field hidden boolean: determines whether to show hidden files or not (default: false) ---@field hidden boolean: determines whether to show hidden files or not (default: false)
---@field no_ignore boolean: show files ignored by .gitignore, .ignore, etc. (default: false) ---@field no_ignore boolean: show files ignored by .gitignore, .ignore, etc. (default: false)
---@field search_dirs table: directory/directories to search in ---@field no_ignore_parent boolean: show files ignored by .gitignore, .ignore, etc. in parent dirs. (default: false)
builtin.find_files = require_on_exported_call("telescope.builtin.files").find_files ---@field search_dirs table: directory/directories/files to search
---@field search_file string: specify a filename to search for
builtin.find_files = require_on_exported_call("telescope.builtin.__files").find_files
--- This is an alias for the `find_files` picker --- This is an alias for the `find_files` picker
builtin.fd = builtin.find_files builtin.fd = builtin.find_files
@@ -93,12 +95,12 @@ builtin.fd = builtin.find_files
---@field show_line boolean: if true, shows the row:column that the result is found at (default: true) ---@field show_line boolean: if true, shows the row:column that the result is found at (default: true)
---@field bufnr number: specify the buffer number where treesitter should run. (default: current buffer) ---@field bufnr number: specify the buffer number where treesitter should run. (default: current buffer)
---@field symbol_highlights table: string -> string. Matches symbol with hl_group ---@field symbol_highlights table: string -> string. Matches symbol with hl_group
builtin.treesitter = require_on_exported_call("telescope.builtin.files").treesitter builtin.treesitter = require_on_exported_call("telescope.builtin.__files").treesitter
--- Live fuzzy search inside of the currently open buffer --- Live fuzzy search inside of the currently open buffer
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field skip_empty_lines boolean: if true we dont display empty lines (default: false) ---@field skip_empty_lines boolean: if true we dont display empty lines (default: false)
builtin.current_buffer_fuzzy_find = require_on_exported_call("telescope.builtin.files").current_buffer_fuzzy_find builtin.current_buffer_fuzzy_find = require_on_exported_call("telescope.builtin.__files").current_buffer_fuzzy_find
--- Lists tags in current directory with tag location file preview (users are required to run ctags -R to generate tags --- Lists tags in current directory with tag location file preview (users are required to run ctags -R to generate tags
--- or update when introducing new changes) --- or update when introducing new changes)
@@ -108,7 +110,7 @@ builtin.current_buffer_fuzzy_find = require_on_exported_call("telescope.builtin.
---@field show_line boolean: if true, shows the content of the line the tag is found on in the picker (default: true) ---@field show_line boolean: if true, shows the content of the line the tag is found on in the picker (default: true)
---@field only_sort_tags boolean: if true we will only sort tags (default: false) ---@field only_sort_tags boolean: if true we will only sort tags (default: false)
---@field fname_width number: defines the width of the filename section (default: 30) ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.tags = require_on_exported_call("telescope.builtin.files").tags builtin.tags = require_on_exported_call("telescope.builtin.__files").tags
--- Lists all of the tags for the currently open buffer, with a preview --- Lists all of the tags for the currently open buffer, with a preview
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
@@ -117,7 +119,7 @@ builtin.tags = require_on_exported_call("telescope.builtin.files").tags
---@field show_line boolean: if true, shows the content of the line the tag is found on in the picker (default: true) ---@field show_line boolean: if true, shows the content of the line the tag is found on in the picker (default: true)
---@field only_sort_tags boolean: if true we will only sort tags (default: false) ---@field only_sort_tags boolean: if true we will only sort tags (default: false)
---@field fname_width number: defines the width of the filename section (default: 30) ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.current_buffer_tags = require_on_exported_call("telescope.builtin.files").current_buffer_tags builtin.current_buffer_tags = require_on_exported_call("telescope.builtin.__files").current_buffer_tags
-- --
-- --
@@ -132,10 +134,10 @@ builtin.current_buffer_tags = require_on_exported_call("telescope.builtin.files"
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field cwd string: specify the path of the repo ---@field cwd string: specify the path of the repo
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field show_untracked boolean: if true, adds `--others` flag to command and shows untracked files (default: true) ---@field show_untracked boolean: if true, adds `--others` flag to command and shows untracked files (default: false)
---@field recurse_submodules boolean: if true, adds the `--recurse-submodules` flag to command (default: false) ---@field recurse_submodules boolean: if true, adds the `--recurse-submodules` flag to command (default: false)
---@field git_command table: command that will be exectued. {"git","ls-files","--exclude-standard","--cached"} ---@field git_command table: command that will be exectued. {"git","ls-files","--exclude-standard","--cached"}
builtin.git_files = require_on_exported_call("telescope.builtin.git").files builtin.git_files = require_on_exported_call("telescope.builtin.__git").files
--- Lists commits for current directory with diff preview --- Lists commits for current directory with diff preview
--- - Default keymaps: --- - Default keymaps:
@@ -147,7 +149,7 @@ builtin.git_files = require_on_exported_call("telescope.builtin.git").files
---@field cwd string: specify the path of the repo ---@field cwd string: specify the path of the repo
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field git_command table: command that will be exectued. {"git","log","--pretty=oneline","--abbrev-commit","--","."} ---@field git_command table: command that will be exectued. {"git","log","--pretty=oneline","--abbrev-commit","--","."}
builtin.git_commits = require_on_exported_call("telescope.builtin.git").commits builtin.git_commits = require_on_exported_call("telescope.builtin.__git").commits
--- Lists commits for current buffer with diff preview --- Lists commits for current buffer with diff preview
--- - Default keymaps or your overriden `select_` keys: --- - Default keymaps or your overriden `select_` keys:
@@ -160,7 +162,7 @@ builtin.git_commits = require_on_exported_call("telescope.builtin.git").commits
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field current_file string: specify the current file that should be used for bcommits (default: current buffer) ---@field current_file string: specify the current file that should be used for bcommits (default: current buffer)
---@field git_command table: command that will be exectued. {"git","log","--pretty=oneline","--abbrev-commit"} ---@field git_command table: command that will be exectued. {"git","log","--pretty=oneline","--abbrev-commit"}
builtin.git_bcommits = require_on_exported_call("telescope.builtin.git").bcommits builtin.git_bcommits = require_on_exported_call("telescope.builtin.__git").bcommits
--- List branches for current directory, with output from `git log --oneline` shown in the preview window --- List branches for current directory, with output from `git log --oneline` shown in the preview window
--- - Default keymaps: --- - Default keymaps:
@@ -174,7 +176,7 @@ builtin.git_bcommits = require_on_exported_call("telescope.builtin.git").bcommit
---@field cwd string: specify the path of the repo ---@field cwd string: specify the path of the repo
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field pattern string: specify the pattern to match all refs ---@field pattern string: specify the pattern to match all refs
builtin.git_branches = require_on_exported_call("telescope.builtin.git").branches builtin.git_branches = require_on_exported_call("telescope.builtin.__git").branches
--- Lists git status for current directory --- Lists git status for current directory
--- - Default keymaps: --- - Default keymaps:
@@ -184,7 +186,7 @@ builtin.git_branches = require_on_exported_call("telescope.builtin.git").branche
---@field cwd string: specify the path of the repo ---@field cwd string: specify the path of the repo
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field git_icons table: string -> string. Matches name with icon (see source code, make_entry.lua git_icon_defaults) ---@field git_icons table: string -> string. Matches name with icon (see source code, make_entry.lua git_icon_defaults)
builtin.git_status = require_on_exported_call("telescope.builtin.git").status builtin.git_status = require_on_exported_call("telescope.builtin.__git").status
--- Lists stash items in current repository --- Lists stash items in current repository
--- - Default keymaps: --- - Default keymaps:
@@ -193,7 +195,7 @@ builtin.git_status = require_on_exported_call("telescope.builtin.git").status
---@field cwd string: specify the path of the repo ---@field cwd string: specify the path of the repo
---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true) ---@field use_git_root boolean: if we should use git root as cwd or the cwd (important for submodule) (default: true)
---@field show_branch boolean: if we should display the branch name for git stash entries (default: true) ---@field show_branch boolean: if we should display the branch name for git stash entries (default: true)
builtin.git_stash = require_on_exported_call("telescope.builtin.git").stash builtin.git_stash = require_on_exported_call("telescope.builtin.__git").stash
-- --
-- --
@@ -204,14 +206,15 @@ builtin.git_stash = require_on_exported_call("telescope.builtin.git").stash
--- Lists all of the community maintained pickers built into Telescope --- Lists all of the community maintained pickers built into Telescope
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field include_extensions boolean: if true will show the pickers of the installed extensions (default: false) ---@field include_extensions boolean: if true will show the pickers of the installed extensions (default: false)
builtin.builtin = require_on_exported_call("telescope.builtin.internal").builtin ---@field use_default_opts boolean: if the selected picker should use its default options (default: false)
builtin.builtin = require_on_exported_call("telescope.builtin.__internal").builtin
--- Opens the previous picker in the identical state (incl. multi selections) --- Opens the previous picker in the identical state (incl. multi selections)
--- - Notes: --- - Notes:
--- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker| --- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker|
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field cache_index number: what picker to resume, where 1 denotes most recent (default: 1) ---@field cache_index number: what picker to resume, where 1 denotes most recent (default: 1)
builtin.resume = require_on_exported_call("telescope.builtin.internal").resume builtin.resume = require_on_exported_call("telescope.builtin.__internal").resume
--- Opens a picker over previously cached pickers in their preserved states (incl. multi selections) --- Opens a picker over previously cached pickers in their preserved states (incl. multi selections)
--- - Default keymaps: --- - Default keymaps:
@@ -219,12 +222,12 @@ builtin.resume = require_on_exported_call("telescope.builtin.internal").resume
--- - Notes: --- - Notes:
--- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker| --- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker|
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.pickers = require_on_exported_call("telescope.builtin.internal").pickers builtin.pickers = require_on_exported_call("telescope.builtin.__internal").pickers
--- Use the telescope... --- Use the telescope...
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field show_pluto boolean: we love pluto (default: false, because its a hidden feature) ---@field show_pluto boolean: we love pluto (default: false, because its a hidden feature)
builtin.planets = require_on_exported_call("telescope.builtin.internal").planets builtin.planets = require_on_exported_call("telescope.builtin.__internal").planets
--- Lists symbols inside of `data/telescope-sources/*.json` found in your runtime path --- Lists symbols inside of `data/telescope-sources/*.json` found in your runtime path
--- or found in `stdpath("data")/telescope/symbols/*.json`. The second path can be customized. --- or found in `stdpath("data")/telescope/symbols/*.json`. The second path can be customized.
@@ -234,69 +237,71 @@ builtin.planets = require_on_exported_call("telescope.builtin.internal").planets
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field symbol_path string: specify the second path. Default: `stdpath("data")/telescope/symbols/*.json` ---@field symbol_path string: specify the second path. Default: `stdpath("data")/telescope/symbols/*.json`
---@field sources table: specify a table of sources you want to load this time ---@field sources table: specify a table of sources you want to load this time
builtin.symbols = require_on_exported_call("telescope.builtin.internal").symbols builtin.symbols = require_on_exported_call("telescope.builtin.__internal").symbols
--- Lists available plugin/user commands and runs them on `<cr>` --- Lists available plugin/user commands and runs them on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field show_buf_command boolean: show buf local command (Default: true) ---@field show_buf_command boolean: show buf local command (Default: true)
builtin.commands = require_on_exported_call("telescope.builtin.internal").commands builtin.commands = require_on_exported_call("telescope.builtin.__internal").commands
--- Lists items in the quickfix list, jumps to location on `<cr>` --- Lists items in the quickfix list, jumps to location on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
---@field fname_width number: defines the width of the filename section (default: 30)
---@field nr number: specify the quickfix list number ---@field nr number: specify the quickfix list number
builtin.quickfix = require_on_exported_call("telescope.builtin.internal").quickfix builtin.quickfix = require_on_exported_call("telescope.builtin.__internal").quickfix
--- Lists all quickfix lists in your history and open them with `builtin.quickfix`. It seems that neovim --- Lists all quickfix lists in your history and open them with `builtin.quickfix`. It seems that neovim
--- only keeps the full history for 10 lists --- only keeps the full history for 10 lists
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.quickfixhistory = require_on_exported_call("telescope.builtin.internal").quickfixhistory builtin.quickfixhistory = require_on_exported_call("telescope.builtin.__internal").quickfixhistory
--- Lists items from the current window's location list, jumps to location on `<cr>` --- Lists items from the current window's location list, jumps to location on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.loclist = require_on_exported_call("telescope.builtin.internal").loclist ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.loclist = require_on_exported_call("telescope.builtin.__internal").loclist
--- Lists previously open files, opens on `<cr>` --- Lists previously open files, opens on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field only_cwd boolean: show only files in the cwd (default: false) ---@field only_cwd boolean: show only files in the cwd (default: false)
---@field cwd_only boolean: alias for only_cwd ---@field cwd_only boolean: alias for only_cwd
builtin.oldfiles = require_on_exported_call("telescope.builtin.internal").oldfiles builtin.oldfiles = require_on_exported_call("telescope.builtin.__internal").oldfiles
--- Lists commands that were executed recently, and reruns them on `<cr>` --- Lists commands that were executed recently, and reruns them on `<cr>`
--- - Default keymaps: --- - Default keymaps:
--- - `<C-e>`: open the command line with the text of the currently selected result populated in it --- - `<C-e>`: open the command line with the text of the currently selected result populated in it
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.command_history = require_on_exported_call("telescope.builtin.internal").command_history builtin.command_history = require_on_exported_call("telescope.builtin.__internal").command_history
--- Lists searches that were executed recently, and reruns them on `<cr>` --- Lists searches that were executed recently, and reruns them on `<cr>`
--- - Default keymaps: --- - Default keymaps:
--- - `<C-e>`: open a search window with the text of the currently selected search result populated in it --- - `<C-e>`: open a search window with the text of the currently selected search result populated in it
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.search_history = require_on_exported_call("telescope.builtin.internal").search_history builtin.search_history = require_on_exported_call("telescope.builtin.__internal").search_history
--- Lists vim options, allows you to edit the current value on `<cr>` --- Lists vim options, allows you to edit the current value on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.vim_options = require_on_exported_call("telescope.builtin.internal").vim_options builtin.vim_options = require_on_exported_call("telescope.builtin.__internal").vim_options
--- Lists available help tags and opens a new window with the relevant help info on `<cr>` --- Lists available help tags and opens a new window with the relevant help info on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field lang string: specify language (default: vim.o.helplang) ---@field lang string: specify language (default: vim.o.helplang)
---@field fallback boolean: fallback to en if language isn't installed (default: true) ---@field fallback boolean: fallback to en if language isn't installed (default: true)
builtin.help_tags = require_on_exported_call("telescope.builtin.internal").help_tags builtin.help_tags = require_on_exported_call("telescope.builtin.__internal").help_tags
--- Lists manpage entries, opens them in a help window on `<cr>` --- Lists manpage entries, opens them in a help window on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field sections table: a list of sections to search, use `{ "ALL" }` to search in all sections (default: { "1" }) ---@field sections table: a list of sections to search, use `{ "ALL" }` to search in all sections (default: { "1" })
---@field man_cmd function: that returns the man command. (Default: `apropos ""` on linux, `apropos " "` on macos) ---@field man_cmd function: that returns the man command. (Default: `apropos ""` on linux, `apropos " "` on macos)
builtin.man_pages = require_on_exported_call("telescope.builtin.internal").man_pages builtin.man_pages = require_on_exported_call("telescope.builtin.__internal").man_pages
--- Lists lua modules and reloads them on `<cr>` --- Lists lua modules and reloads them on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field column_len number: define the max column len for the module name (default: dynamic, longest module name) ---@field column_len number: define the max column len for the module name (default: dynamic, longest module name)
builtin.reloader = require_on_exported_call("telescope.builtin.internal").reloader builtin.reloader = require_on_exported_call("telescope.builtin.__internal").reloader
--- Lists open buffers in current neovim instance, opens selected buffer on `<cr>` --- Lists open buffers in current neovim instance, opens selected buffer on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
@@ -307,56 +312,58 @@ builtin.reloader = require_on_exported_call("telescope.builtin.internal").reload
---@field sort_lastused boolean: Sorts current and last buffer to the top and selects the lastused (default: false) ---@field sort_lastused boolean: Sorts current and last buffer to the top and selects the lastused (default: false)
---@field sort_mru boolean: Sorts all buffers after most recent used. Not just the current and last one (default: false) ---@field sort_mru boolean: Sorts all buffers after most recent used. Not just the current and last one (default: false)
---@field bufnr_width number: Defines the width of the buffer numbers in front of the filenames (default: dynamic) ---@field bufnr_width number: Defines the width of the buffer numbers in front of the filenames (default: dynamic)
builtin.buffers = require_on_exported_call("telescope.builtin.internal").buffers builtin.buffers = require_on_exported_call("telescope.builtin.__internal").buffers
--- Lists available colorschemes and applies them on `<cr>` --- Lists available colorschemes and applies them on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field enable_preview boolean: if true, will preview the selected color ---@field enable_preview boolean: if true, will preview the selected color
builtin.colorscheme = require_on_exported_call("telescope.builtin.internal").colorscheme builtin.colorscheme = require_on_exported_call("telescope.builtin.__internal").colorscheme
--- Lists vim marks and their value, jumps to the mark on `<cr>` --- Lists vim marks and their value, jumps to the mark on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.marks = require_on_exported_call("telescope.builtin.internal").marks builtin.marks = require_on_exported_call("telescope.builtin.__internal").marks
--- Lists vim registers, pastes the contents of the register on `<cr>` --- Lists vim registers, pastes the contents of the register on `<cr>`
--- - Default keymaps: --- - Default keymaps:
--- - `<C-e>`: edit the contents of the currently selected register --- - `<C-e>`: edit the contents of the currently selected register
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.registers = require_on_exported_call("telescope.builtin.internal").registers builtin.registers = require_on_exported_call("telescope.builtin.__internal").registers
--- Lists normal mode keymappings, runs the selected keymap on `<cr>` --- Lists normal mode keymappings, runs the selected keymap on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field modes table: a list of short-named keymap modes to search (default: { "n", "i", "c", "x" }) ---@field modes table: a list of short-named keymap modes to search (default: { "n", "i", "c", "x" })
---@field show_plug boolean: if true, the keymaps for which the lhs contains "<Plug>" are also shown (default: true) ---@field show_plug boolean: if true, the keymaps for which the lhs contains "<Plug>" are also shown (default: true)
builtin.keymaps = require_on_exported_call("telescope.builtin.internal").keymaps builtin.keymaps = require_on_exported_call("telescope.builtin.__internal").keymaps
--- Lists all available filetypes, sets currently open buffer's filetype to selected filetype in Telescope on `<cr>` --- Lists all available filetypes, sets currently open buffer's filetype to selected filetype in Telescope on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.filetypes = require_on_exported_call("telescope.builtin.internal").filetypes builtin.filetypes = require_on_exported_call("telescope.builtin.__internal").filetypes
--- Lists all available highlights --- Lists all available highlights
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.highlights = require_on_exported_call("telescope.builtin.internal").highlights builtin.highlights = require_on_exported_call("telescope.builtin.__internal").highlights
--- Lists vim autocommands and goes to their declaration on `<cr>` --- Lists vim autocommands and goes to their declaration on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.autocommands = require_on_exported_call("telescope.builtin.internal").autocommands builtin.autocommands = require_on_exported_call("telescope.builtin.__internal").autocommands
--- Lists spelling suggestions for the current word under the cursor, replaces word with selected suggestion on `<cr>` --- Lists spelling suggestions for the current word under the cursor, replaces word with selected suggestion on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
builtin.spell_suggest = require_on_exported_call("telescope.builtin.internal").spell_suggest builtin.spell_suggest = require_on_exported_call("telescope.builtin.__internal").spell_suggest
--- Lists the tag stack for the current window, jumps to tag on `<cr>` --- Lists the tag stack for the current window, jumps to tag on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.tagstack = require_on_exported_call("telescope.builtin.internal").tagstack ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.tagstack = require_on_exported_call("telescope.builtin.__internal").tagstack
--- Lists items from Vim's jumplist, jumps to location on `<cr>` --- Lists items from Vim's jumplist, jumps to location on `<cr>`
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.jumplist = require_on_exported_call("telescope.builtin.internal").jumplist ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.jumplist = require_on_exported_call("telescope.builtin.__internal").jumplist
-- --
-- --
@@ -369,63 +376,76 @@ builtin.jumplist = require_on_exported_call("telescope.builtin.internal").jumpli
---@field include_declaration boolean: include symbol declaration in the lsp references (default: true) ---@field include_declaration boolean: include symbol declaration in the lsp references (default: true)
---@field include_current_line boolean: include current line (default: false) ---@field include_current_line boolean: include current line (default: false)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.lsp_references = require_on_exported_call("telescope.builtin.lsp").references ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.lsp_references = require_on_exported_call("telescope.builtin.__lsp").references
--- Lists LSP incoming calls for word under the cursor, jumps to reference on `<cr>`
---@param opts table: options to pass to the picker
---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false)
builtin.lsp_incoming_calls = require_on_exported_call("telescope.builtin.__lsp").incoming_calls
--- Lists LSP outgoing calls for word under the cursor, jumps to reference on `<cr>`
---@param opts table: options to pass to the picker
---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false)
builtin.lsp_outgoing_calls = require_on_exported_call("telescope.builtin.__lsp").outgoing_calls
--- Goto the definition of the word under the cursor, if there's only one, otherwise show all options in Telescope --- Goto the definition of the word under the cursor, if there's only one, otherwise show all options in Telescope
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never" ---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never"
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.lsp_definitions = require_on_exported_call("telescope.builtin.lsp").definitions ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.lsp_definitions = require_on_exported_call("telescope.builtin.__lsp").definitions
--- Goto the definition of the type of the word under the cursor, if there's only one, --- Goto the definition of the type of the word under the cursor, if there's only one,
--- otherwise show all options in Telescope --- otherwise show all options in Telescope
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never" ---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never"
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.lsp_type_definitions = require("telescope.builtin.lsp").type_definitions ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.lsp_type_definitions = require("telescope.builtin.__lsp").type_definitions
--- Goto the implementation of the word under the cursor if there's only one, otherwise show all options in Telescope --- Goto the implementation of the word under the cursor if there's only one, otherwise show all options in Telescope
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field jump_type string: how to goto implementation if there is only one, values: "tab", "split", "vsplit", "never" ---@field jump_type string: how to goto implementation if there is only one, values: "tab", "split", "vsplit", "never"
---@field ignore_filename boolean: dont show filenames (default: true) ---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false) ---@field trim_text boolean: trim results text (default: false)
builtin.lsp_implementations = require_on_exported_call("telescope.builtin.lsp").implementations ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.lsp_implementations = require_on_exported_call("telescope.builtin.__lsp").implementations
--- Lists LSP document symbols in the current buffer --- Lists LSP document symbols in the current buffer
--- - Default keymaps: --- - Default keymaps:
--- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`) --- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`)
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: true)
---@field show_line boolean: if true, shows the content of the line the tag is found on (default: false) ---@field show_line boolean: if true, shows the content of the line the tag is found on (default: false)
---@field symbols string|table: filter results by symbol kind(s) ---@field symbols string|table: filter results by symbol kind(s)
---@field ignore_symbols string|table: list of symbols to ignore ---@field ignore_symbols string|table: list of symbols to ignore
---@field symbol_highlights table: string -> string. Matches symbol with hl_group ---@field symbol_highlights table: string -> string. Matches symbol with hl_group
builtin.lsp_document_symbols = require_on_exported_call("telescope.builtin.lsp").document_symbols builtin.lsp_document_symbols = require_on_exported_call("telescope.builtin.__lsp").document_symbols
--- Lists LSP document symbols in the current workspace --- Lists LSP document symbols in the current workspace
--- - Default keymaps: --- - Default keymaps:
--- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`) --- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`)
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field query string: for what to query the workspace (default: "") ---@field query string: for what to query the workspace (default: "")
---@field ignore_filename boolean: dont show filenames (default: false)
---@field show_line boolean: if true, shows the content of the line the tag is found on (default: false) ---@field show_line boolean: if true, shows the content of the line the tag is found on (default: false)
---@field symbols string|table: filter results by symbol kind(s) ---@field symbols string|table: filter results by symbol kind(s)
---@field ignore_symbols string|table: list of symbols to ignore ---@field ignore_symbols string|table: list of symbols to ignore
---@field symbol_highlights table: string -> string. Matches symbol with hl_group ---@field symbol_highlights table: string -> string. Matches symbol with hl_group
builtin.lsp_workspace_symbols = require_on_exported_call("telescope.builtin.lsp").workspace_symbols builtin.lsp_workspace_symbols = require_on_exported_call("telescope.builtin.__lsp").workspace_symbols
--- Dynamically lists LSP for all workspace symbols --- Dynamically lists LSP for all workspace symbols
--- - Default keymaps: --- - Default keymaps:
--- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`) --- - `<C-l>`: show autocompletion menu to prefilter your query by type of symbol you want to see (i.e. `:variable:`)
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field ignore_filename boolean: dont show filenames (default: false)
---@field show_line boolean: if true, shows the content of the line the symbol is found on (default: false) ---@field show_line boolean: if true, shows the content of the line the symbol is found on (default: false)
---@field symbols string|table: filter results by symbol kind(s) ---@field symbols string|table: filter results by symbol kind(s)
---@field ignore_symbols string|table: list of symbols to ignore ---@field ignore_symbols string|table: list of symbols to ignore
---@field symbol_highlights table: string -> string. Matches symbol with hl_group ---@field symbol_highlights table: string -> string. Matches symbol with hl_group
builtin.lsp_dynamic_workspace_symbols = require_on_exported_call("telescope.builtin.lsp").dynamic_workspace_symbols builtin.lsp_dynamic_workspace_symbols = require_on_exported_call("telescope.builtin.__lsp").dynamic_workspace_symbols
-- --
-- --
@@ -448,7 +468,7 @@ builtin.lsp_dynamic_workspace_symbols = require_on_exported_call("telescope.buil
---@field no_sign boolean: hide DiagnosticSigns from Results (default: false) ---@field no_sign boolean: hide DiagnosticSigns from Results (default: false)
---@field line_width number: set length of diagnostic entry text in Results ---@field line_width number: set length of diagnostic entry text in Results
---@field namespace number: limit your diagnostics to a specific namespace ---@field namespace number: limit your diagnostics to a specific namespace
builtin.diagnostics = require_on_exported_call("telescope.builtin.diagnostics").get builtin.diagnostics = require_on_exported_call("telescope.builtin.__diagnostics").get
local apply_config = function(mod) local apply_config = function(mod)
local pickers_conf = require("telescope.config").pickers local pickers_conf = require("telescope.config").pickers

File diff suppressed because it is too large Load Diff

View File

@@ -1,292 +1,17 @@
local channel = require("plenary.async.control").channel local m = setmetatable({}, {
__index = function(_, k)
local conf = require("telescope.config").values local utils = require "telescope.utils"
local finders = require "telescope.finders" utils.notify("builtin", {
local make_entry = require "telescope.make_entry" msg = string.format(
local pickers = require "telescope.pickers" 'You are using an internal interface. Do not use `require("telescope.builtin.lsp").%s`,'
local utils = require "telescope.utils" .. ' please use `require("telescope.builtin").lsp_%s`! We will remove this endpoint soon!',
k,
local lsp = {} k
),
lsp.references = function(opts) level = "ERROR",
local filepath = vim.api.nvim_buf_get_name(opts.bufnr)
local lnum = vim.api.nvim_win_get_cursor(opts.winnr)[1]
local params = vim.lsp.util.make_position_params(opts.winnr)
local include_current_line = vim.F.if_nil(opts.include_current_line, false)
params.context = { includeDeclaration = vim.F.if_nil(opts.include_declaration, true) }
vim.lsp.buf_request(opts.bufnr, "textDocument/references", params, function(err, result, ctx, _)
if err then
vim.api.nvim_err_writeln("Error when finding references: " .. err.message)
return
end
local locations = {}
if result then
local results = vim.lsp.util.locations_to_items(result, vim.lsp.get_client_by_id(ctx.client_id).offset_encoding)
if include_current_line then
locations = vim.tbl_filter(function(v)
-- Remove current line from result
return not (v.filename == filepath and v.lnum == lnum)
end, vim.F.if_nil(results, {}))
else
locations = vim.F.if_nil(results, {})
end
end
if vim.tbl_isempty(locations) then
return
end
pickers.new(opts, {
prompt_title = "LSP References",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
local function list_or_jump(action, title, opts)
opts = opts or {}
local params = vim.lsp.util.make_position_params(opts.winnr)
vim.lsp.buf_request(opts.bufnr, action, params, function(err, result, ctx, _)
if err then
vim.api.nvim_err_writeln("Error when executing " .. action .. " : " .. err.message)
return
end
local flattened_results = {}
if result then
-- textDocument/definition can return Location or Location[]
if not vim.tbl_islist(result) then
flattened_results = { result }
end
vim.list_extend(flattened_results, result)
end
local offset_encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding
if #flattened_results == 0 then
return
elseif #flattened_results == 1 and opts.jump_type ~= "never" then
if opts.jump_type == "tab" then
vim.cmd "tabedit"
elseif opts.jump_type == "split" then
vim.cmd "new"
elseif opts.jump_type == "vsplit" then
vim.cmd "vnew"
end
vim.lsp.util.jump_to_location(flattened_results[1], offset_encoding)
else
local locations = vim.lsp.util.locations_to_items(flattened_results, offset_encoding)
pickers.new(opts, {
prompt_title = title,
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end
end)
end
lsp.definitions = function(opts)
return list_or_jump("textDocument/definition", "LSP Definitions", opts)
end
lsp.type_definitions = function(opts)
return list_or_jump("textDocument/typeDefinition", "LSP Type Definitions", opts)
end
lsp.implementations = function(opts)
return list_or_jump("textDocument/implementation", "LSP Implementations", opts)
end
lsp.document_symbols = function(opts)
local params = vim.lsp.util.make_position_params(opts.winnr)
vim.lsp.buf_request(opts.bufnr, "textDocument/documentSymbol", params, function(err, result, _, _)
if err then
vim.api.nvim_err_writeln("Error when finding document symbols: " .. err.message)
return
end
if not result or vim.tbl_isempty(result) then
utils.notify("builtin.lsp_document_symbols", {
msg = "No results from textDocument/documentSymbol",
level = "INFO",
}) })
return return require("telescope.builtin")["lsp_" .. k]
end end,
})
local locations = vim.lsp.util.symbols_to_items(result or {}, opts.bufnr) or {} return m
locations = utils.filter_symbols(locations, opts)
if locations == nil then
-- error message already printed in `utils.filter_symbols`
return
end
if vim.tbl_isempty(locations) then
utils.notify("builtin.lsp_document_symbols", {
msg = "No document_symbol locations found",
level = "INFO",
})
return
end
opts.ignore_filename = opts.ignore_filename or true
pickers.new(opts, {
prompt_title = "LSP Document Symbols",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "symbol_type",
sorter = conf.generic_sorter(opts),
},
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
lsp.workspace_symbols = function(opts)
local params = { query = opts.query or "" }
vim.lsp.buf_request(opts.bufnr, "workspace/symbol", params, function(err, server_result, _, _)
if err then
vim.api.nvim_err_writeln("Error when finding workspace symbols: " .. err.message)
return
end
local locations = vim.lsp.util.symbols_to_items(server_result or {}, opts.bufnr) or {}
locations = utils.filter_symbols(locations, opts)
if locations == nil then
-- error message already printed in `utils.filter_symbols`
return
end
if vim.tbl_isempty(locations) then
utils.notify("builtin.lsp_workspace_symbols", {
msg = "No results from workspace/symbol. Maybe try a different query: "
.. "'Telescope lsp_workspace_symbols query=example'",
level = "INFO",
})
return
end
opts.ignore_filename = utils.get_default(opts.ignore_filename, false)
pickers.new(opts, {
prompt_title = "LSP Workspace Symbols",
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.prefilter_sorter {
tag = "symbol_type",
sorter = conf.generic_sorter(opts),
},
}):find()
end)
end
local function get_workspace_symbols_requester(bufnr, opts)
local cancel = function() end
return function(prompt)
local tx, rx = channel.oneshot()
cancel()
_, cancel = vim.lsp.buf_request(bufnr, "workspace/symbol", { query = prompt }, tx)
-- Handle 0.5 / 0.5.1 handler situation
local err, res = rx()
assert(not err, err)
local locations = vim.lsp.util.symbols_to_items(res or {}, bufnr) or {}
if not vim.tbl_isempty(locations) then
locations = utils.filter_symbols(locations, opts) or {}
end
return locations
end
end
lsp.dynamic_workspace_symbols = function(opts)
pickers.new(opts, {
prompt_title = "LSP Dynamic Workspace Symbols",
finder = finders.new_dynamic {
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts),
fn = get_workspace_symbols_requester(opts.bufnr, opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
}):find()
end
local function check_capabilities(feature, bufnr)
local clients = vim.lsp.buf_get_clients(bufnr)
local supported_client = false
for _, client in pairs(clients) do
supported_client = client.server_capabilities[feature]
if supported_client then
break
end
end
if supported_client then
return true
else
if #clients == 0 then
utils.notify("builtin.lsp_*", {
msg = "no client attached",
level = "INFO",
})
else
utils.notify("builtin.lsp_*", {
msg = "server does not support " .. feature,
level = "INFO",
})
end
return false
end
end
local feature_map = {
["document_symbols"] = "documentSymbolProvider",
["references"] = "referencesProvider",
["definitions"] = "definitionProvider",
["type_definitions"] = "typeDefinitionProvider",
["implementations"] = "implementationProvider",
["workspace_symbols"] = "workspaceSymbolProvider",
}
local function apply_checks(mod)
for k, v in pairs(mod) do
mod[k] = function(opts)
opts = opts or {}
local feature_name = feature_map[k]
if feature_name and not check_capabilities(feature_name, opts.bufnr) then
return
end
v(opts)
end
end
return mod
end
return apply_checks(lsp)

View File

@@ -1,7 +1,6 @@
local strings = require "plenary.strings" local strings = require "plenary.strings"
local deprecated = require "telescope.deprecated" local deprecated = require "telescope.deprecated"
local sorters = require "telescope.sorters" local sorters = require "telescope.sorters"
local if_nil = vim.F.if_nil
local os_sep = require("plenary.path").path.sep local os_sep = require("plenary.path").path.sep
local has_win = vim.fn.has "win32" == 1 local has_win = vim.fn.has "win32" == 1
@@ -69,7 +68,7 @@ config.descriptions = {}
config.pickers = _TelescopeConfigurationPickers config.pickers = _TelescopeConfigurationPickers
function config.set_pickers(pickers) function config.set_pickers(pickers)
pickers = if_nil(pickers, {}) pickers = vim.F.if_nil(pickers, {})
for k, v in pairs(pickers) do for k, v in pairs(pickers) do
config.pickers[k] = v config.pickers[k] = v
@@ -182,7 +181,8 @@ append(
- "reset" (default) - "reset" (default)
- "follow" - "follow"
- "row" - "row"
- "closest"]] - "closest"
- "none"]]
) )
append( append(
@@ -593,8 +593,17 @@ append(
highlighting, which falls back to regex-based highlighting. highlighting, which falls back to regex-based highlighting.
`true`: treesitter highlighting for all available filetypes `true`: treesitter highlighting for all available filetypes
`false`: regex-based highlighting for all filetypes `false`: regex-based highlighting for all filetypes
`table`: table of filetypes for which to attach treesitter `table`: following nvim-treesitters highlighting options:
highlighting It contains two keys:
- enable boolean|table: if boolean, enable all ts
highlighing with that flag,
disable still considered.
Containing a list of filetypes,
that are enabled, disabled
ignored because it doesnt make
any sense in this case.
- disable table: containing a list of filetypes
that are disabled
Default: true Default: true
- msg_bg_fillchar: Character to fill background of unpreviewable buffers with - msg_bg_fillchar: Character to fill background of unpreviewable buffers with
Default: "" Default: ""
@@ -783,6 +792,17 @@ append(
Example: { "%.npz" } -- ignore all npz files Example: { "%.npz" } -- ignore all npz files
See: https://www.lua.org/manual/5.1/manual.html#5.4.1 for more See: https://www.lua.org/manual/5.1/manual.html#5.4.1 for more
information about lua regex information about lua regex
Note: `file_ignore_patterns` will be used in all pickers that have a
file associated. This might lead to the problem that lsp_ pickers
aren't displaying results because they might be ignored by
`file_ignore_patterns`. For example, setting up node_modules as ignored
will never show node_modules in any results, even if you are
interested in lsp_ results.
If you only want `file_ignore_patterns` for `find_files` and
`grep_string`/`live_grep` it is suggested that you setup `gitignore`
and have fd and or ripgrep installed because both tools will not show
`gitignore`d files on default.
Default: nil]] Default: nil]]
) )
@@ -865,8 +885,8 @@ append(
-- @param tele_defaults table: (optional) a table containing all of the defaults -- @param tele_defaults table: (optional) a table containing all of the defaults
-- for telescope [defaults to `telescope_defaults`] -- for telescope [defaults to `telescope_defaults`]
function config.set_defaults(user_defaults, tele_defaults) function config.set_defaults(user_defaults, tele_defaults)
user_defaults = if_nil(user_defaults, {}) user_defaults = vim.F.if_nil(user_defaults, {})
tele_defaults = if_nil(tele_defaults, telescope_defaults) tele_defaults = vim.F.if_nil(tele_defaults, telescope_defaults)
-- Check if using layout keywords outside of `layout_config` -- Check if using layout keywords outside of `layout_config`
deprecated.options(user_defaults) deprecated.options(user_defaults)
@@ -874,8 +894,8 @@ function config.set_defaults(user_defaults, tele_defaults)
local function get(name, default_val) local function get(name, default_val)
if name == "layout_config" then if name == "layout_config" then
return smarter_depth_2_extend( return smarter_depth_2_extend(
if_nil(user_defaults[name], {}), vim.F.if_nil(user_defaults[name], {}),
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {})) vim.tbl_deep_extend("keep", vim.F.if_nil(config.values[name], {}), vim.F.if_nil(default_val, {}))
) )
end end
if name == "history" or name == "cache_picker" or name == "preview" then if name == "history" or name == "cache_picker" or name == "preview" then
@@ -884,8 +904,8 @@ function config.set_defaults(user_defaults, tele_defaults)
end end
return smarter_depth_2_extend( return smarter_depth_2_extend(
if_nil(user_defaults[name], {}), vim.F.if_nil(user_defaults[name], {}),
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {})) vim.tbl_deep_extend("keep", vim.F.if_nil(config.values[name], {}), vim.F.if_nil(default_val, {}))
) )
end end
return first_non_null(user_defaults[name], config.values[name], default_val) return first_non_null(user_defaults[name], config.values[name], default_val)

View File

@@ -91,8 +91,6 @@ That's the next step to scrolling.
--]] --]]
local get_default = require("telescope.utils").get_default
local resolver = {} local resolver = {}
local _resolve_map = {} local _resolve_map = {}
@@ -129,9 +127,6 @@ end] = function(selector, val)
end end
end end
-- Tables TODO:
-- ... {70, max}
-- function: -- function:
-- Function must have same signature as get_window_layout -- Function must have same signature as get_window_layout
-- function(self, max_columns, max_lines): number -- function(self, max_columns, max_lines): number
@@ -143,6 +138,26 @@ end] = function(_, val)
return val return val
end end
_resolve_map[function(val)
return type(val) == "table" and val[1] >= 0 and val[1] < 1 and val["max"] ~= nil
end] =
function(selector, val)
return function(...)
local selected = select(selector, ...)
return math.min(math.floor(val[1] * selected), val["max"])
end
end
_resolve_map[function(val)
return type(val) == "table" and val[1] >= 0 and val[1] < 1 and val["min"] ~= nil
end] =
function(selector, val)
return function(...)
local selected = select(selector, ...)
return math.max(math.floor(val[1] * selected), val["min"])
end
end
-- Add padding option -- Add padding option
_resolve_map[function(val) _resolve_map[function(val)
return type(val) == "table" and val["padding"] ~= nil return type(val) == "table" and val["padding"] ~= nil
@@ -164,7 +179,7 @@ end] = function(selector, val)
end end
--- Converts input to a function that returns the height. --- Converts input to a function that returns the height.
--- The input must take one of four forms: --- The input must take one of five forms:
--- 1. 0 <= number < 1 <br> --- 1. 0 <= number < 1 <br>
--- This means total height as a percentage. --- This means total height as a percentage.
--- 2. 1 <= number <br> --- 2. 1 <= number <br>
@@ -172,7 +187,10 @@ end
--- 3. function <br> --- 3. function <br>
--- Must have signature: --- Must have signature:
--- function(self, max_columns, max_lines): number --- function(self, max_columns, max_lines): number
--- 4. table of the form: {padding = `foo`} <br> --- 4. table of the form: { val, max = ..., min = ... } <br>
--- val has to be in the first form 0 <= val < 1 and only one is given,
--- `min` or `max` as fixed number
--- 5. table of the form: {padding = `foo`} <br>
--- where `foo` has one of the previous three forms. <br> --- where `foo` has one of the previous three forms. <br>
--- The height is then set to be the remaining space after padding. --- The height is then set to be the remaining space after padding.
--- For example, if the window has height 50, and the input is {padding = 5}, --- For example, if the window has height 50, and the input is {padding = 5},
@@ -190,7 +208,7 @@ resolver.resolve_height = function(val)
end end
--- Converts input to a function that returns the width. --- Converts input to a function that returns the width.
--- The input must take one of four forms: --- The input must take one of five forms:
--- 1. 0 <= number < 1 <br> --- 1. 0 <= number < 1 <br>
--- This means total width as a percentage. --- This means total width as a percentage.
--- 2. 1 <= number <br> --- 2. 1 <= number <br>
@@ -198,7 +216,10 @@ end
--- 3. function <br> --- 3. function <br>
--- Must have signature: --- Must have signature:
--- function(self, max_columns, max_lines): number --- function(self, max_columns, max_lines): number
--- 4. table of the form: {padding = `foo`} <br> --- 4. table of the form: { val, max = ..., min = ... } <br>
--- val has to be in the first form 0 <= val < 1 and only one is given,
--- `min` or `max` as fixed number
--- 5. table of the form: {padding = `foo`} <br>
--- where `foo` has one of the previous three forms. <br> --- where `foo` has one of the previous three forms. <br>
--- The width is then set to be the remaining space after padding. --- The width is then set to be the remaining space after padding.
--- For example, if the window has width 100, and the input is {padding = 5}, --- For example, if the window has width 100, and the input is {padding = 5},
@@ -286,9 +307,9 @@ resolver.win_option = function(val, default)
end end
return { return {
preview = get_default(val.preview, val_to_set), preview = vim.F.if_nil(val.preview, val_to_set),
results = get_default(val.results, val_to_set), results = vim.F.if_nil(val.results, val_to_set),
prompt = get_default(val.prompt, val_to_set), prompt = vim.F.if_nil(val.prompt, val_to_set),
} }
end end
end end

View File

@@ -30,6 +30,7 @@ return function(opts)
end end
end, end,
results = results, results = results,
entry_maker = entry_maker,
}, { }, {
__call = function(_, prompt, process_result, process_complete) __call = function(_, prompt, process_result, process_complete)
if not job_started then if not job_started then

View File

@@ -24,6 +24,7 @@ return function(opts)
return setmetatable({ return setmetatable({
results = results, results = results,
entry_maker = entry_maker,
close = function() end, close = function() end,
}, { }, {
__call = function(_, _, process_result, process_complete) __call = function(_, _, process_result, process_complete)

View File

@@ -1,3 +1,40 @@
---@tag telescope.make_entry
---@brief [[
---
--- Each picker has a finder made up of two parts, the results which are the
--- data to be displayed, and the entry_maker. These entry_makers are functions
--- returned from make_entry functions. These will be referrd to as
--- entry_makers in the following documentation.
---
--- Every entry maker returns a function which accepts the data to be used for
--- an entry. This function will return an entry table (or nil, meaning skip
--- this entry) which contains of the - following important keys:
--- - value any: value key can be anything but still required
--- - valid bool: is an optional key because it defaults to true but if the key
--- is set to false it will not be displayed by the picker. (optional)
--- - ordinal string: is the text that is used for filtering (required)
--- - display string|function: is either a string of the text that is being
--- displayed or a function receiving the entry at a later stage, when the entry
--- is actually being displayed. A function can be useful here if complex
--- calculation have to be done. `make_entry` can also return a second value
--- a highlight array which will then apply to the line. Highlight entry in
--- this array has the following signature `{ { start_col, end_col }, hl_group }`
--- (required).
--- - filename string: will be interpreted by the default `<cr>` action as
--- open this file (optional)
--- - bufnr number: will be interpreted by the default `<cr>` action as open
--- this buffer (optional)
--- - lnum number: lnum value which will be interpreted by the default `<cr>`
--- action as a jump to this line (optional)
--- - col number: col value which will be interpreted by the default `<cr>`
--- action as a jump to this column (optional)
---
--- More information on easier displaying, see |telescope.pickers.entry_display|
---
--- TODO: Document something we call `entry_index`
---@brief ]]
local entry_display = require "telescope.pickers.entry_display" local entry_display = require "telescope.pickers.entry_display"
local utils = require "telescope.utils" local utils = require "telescope.utils"
local strings = require "plenary.strings" local strings = require "plenary.strings"
@@ -26,8 +63,55 @@ local lsp_type_highlight = {
["Variable"] = "TelescopeResultsVariable", ["Variable"] = "TelescopeResultsVariable",
} }
local get_filename_fn = function()
local bufnr_name_cache = {}
return function(bufnr)
bufnr = vim.F.if_nil(bufnr, 0)
local c = bufnr_name_cache[bufnr]
if c then
return c
end
local n = vim.api.nvim_buf_get_name(bufnr)
bufnr_name_cache[bufnr] = n
return n
end
end
local handle_entry_index = function(opts, t, k)
local override = ((opts or {}).entry_index or {})[k]
if not override then
return
end
local val, save = override(t, opts)
if save then
rawset(t, k, val)
end
return val
end
local make_entry = {} local make_entry = {}
make_entry.set_default_entry_mt = function(tbl, opts)
return setmetatable({}, {
__index = function(t, k)
local override = handle_entry_index(opts, t, k)
if override then
return override
end
-- Only hit tbl once
local val = tbl[k]
if val then
rawset(t, k, val)
end
return val
end,
})
end
do do
local lookup_keys = { local lookup_keys = {
display = 1, display = 1,
@@ -35,13 +119,18 @@ do
value = 1, value = 1,
} }
function make_entry.gen_from_string(opts)
local mt_string_entry = { local mt_string_entry = {
__index = function(t, k) __index = function(t, k)
local override = handle_entry_index(opts, t, k)
if override then
return override
end
return rawget(t, rawget(lookup_keys, k)) return rawget(t, rawget(lookup_keys, k))
end, end,
} }
function make_entry.gen_from_string()
return function(line) return function(line)
return setmetatable({ return setmetatable({
line, line,
@@ -82,6 +171,11 @@ do
end end
mt_file_entry.__index = function(t, k) mt_file_entry.__index = function(t, k)
local override = handle_entry_index(opts, t, k)
if override then
return override
end
local raw = rawget(mt_file_entry, k) local raw = rawget(mt_file_entry, k)
if raw then if raw then
return raw return raw
@@ -133,9 +227,6 @@ do
return { filename, lnum, col, text } return { filename, lnum, col, text }
end end
--- Special options:
--- - disable_coordinates: Don't show the line & row numbers
--- - only_sort_text: Only sort via the text. Ignore filename and other items
function make_entry.gen_from_vimgrep(opts) function make_entry.gen_from_vimgrep(opts)
local mt_vimgrep_entry local mt_vimgrep_entry
@@ -205,6 +296,11 @@ do
end, end,
__index = function(t, k) __index = function(t, k)
local override = handle_entry_index(opts, t, k)
if override then
return override
end
local raw = rawget(mt_vimgrep_entry, k) local raw = rawget(mt_vimgrep_entry, k)
if raw then if raw then
return raw return raw
@@ -257,13 +353,13 @@ function make_entry.gen_from_git_stash(opts)
local _, branch_name = string.match(splitted[2], "^([WIP on|On]+) (.+)") local _, branch_name = string.match(splitted[2], "^([WIP on|On]+) (.+)")
local commit_info = splitted[3] local commit_info = splitted[3]
return { return make_entry.set_default_entry_mt({
value = stash_idx, value = stash_idx,
ordinal = commit_info, ordinal = commit_info,
branch_name = branch_name, branch_name = branch_name,
commit_info = commit_info, commit_info = commit_info,
display = make_display, display = make_display,
} }, opts)
end end
end end
@@ -297,52 +393,61 @@ function make_entry.gen_from_git_commits(opts)
msg = "<empty commit message>" msg = "<empty commit message>"
end end
return { return make_entry.set_default_entry_mt({
value = sha, value = sha,
ordinal = sha .. " " .. msg, ordinal = sha .. " " .. msg,
msg = msg, msg = msg,
display = make_display, display = make_display,
current_file = opts.current_file, current_file = opts.current_file,
} }, opts)
end end
end end
function make_entry.gen_from_quickfix(opts) function make_entry.gen_from_quickfix(opts)
opts = opts or {} opts = opts or {}
local show_line = vim.F.if_nil(opts.show_line, true)
local displayer = entry_display.create { local hidden = utils.is_path_hidden(opts)
separator = "", local items = {
items = { { width = vim.F.if_nil(opts.fname_width, 30) },
{ width = 8 },
{ width = 0.45 },
{ remaining = true }, { remaining = true },
},
} }
if hidden then
items[1] = 8
end
if not show_line then
table.remove(items, 1)
end
local displayer = entry_display.create { separator = "", items = items }
local make_display = function(entry) local make_display = function(entry)
local filename = utils.transform_path(opts, entry.filename) local input = {}
if not hidden then
local line_info = { table.concat({ entry.lnum, entry.col }, ":"), "TelescopeResultsLineNr" } table.insert(input, string.format("%s:%d:%d", utils.transform_path(opts, entry.filename), entry.lnum, entry.col))
else
table.insert(input, string.format("%4d:%2d", entry.lnum, entry.col))
end
if show_line then
local text = entry.text
if opts.trim_text then if opts.trim_text then
entry.text = entry.text:gsub("^%s*(.-)%s*$", "%1") text = text:gsub("^%s*(.-)%s*$", "%1")
end
text = text:gsub(".* | ", "")
table.insert(input, text)
end end
return displayer { return displayer(input)
line_info,
entry.text:gsub(".* | ", ""),
filename,
}
end end
local get_filename = get_filename_fn()
return function(entry) return function(entry)
local filename = entry.filename or vim.api.nvim_buf_get_name(entry.bufnr) local filename = vim.F.if_nil(entry.filename, get_filename(entry.bufnr))
return {
valid = true,
return make_entry.set_default_entry_mt({
value = entry, value = entry,
ordinal = (not opts.ignore_filename and filename or "") .. " " .. entry.text, ordinal = (not hidden and filename or "") .. " " .. entry.text,
display = make_display, display = make_display,
bufnr = entry.bufnr, bufnr = entry.bufnr,
@@ -352,7 +457,7 @@ function make_entry.gen_from_quickfix(opts)
text = entry.text, text = entry.text,
start = entry.start, start = entry.start,
finish = entry.finish, finish = entry.finish,
} }, opts)
end end
end end
@@ -361,14 +466,22 @@ function make_entry.gen_from_lsp_symbols(opts)
local bufnr = opts.bufnr or vim.api.nvim_get_current_buf() local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
-- Default we have two columns, symbol and type(unbound)
-- If path is not hidden then its, filepath, symbol and type(still unbound)
-- If show_line is also set, type is bound to len 8
local display_items = { local display_items = {
{ width = opts.symbol_width or 25 }, -- symbol { width = opts.symbol_width or 25 },
{ width = opts.symbol_type_width or 8 }, -- symbol type { remaining = true },
{ remaining = true }, -- filename{:optional_lnum+col} OR content preview
} }
if opts.ignore_filename and opts.show_line then local hidden = utils.is_path_hidden(opts)
table.insert(display_items, 2, { width = 6 }) if not hidden then
table.insert(display_items, 1, { width = vim.F.if_nil(opts.fname_width, 30) })
end
if opts.show_line then
-- bound type to len 8 or custom
table.insert(display_items, #display_items, { width = opts.symbol_type_width or 8 })
end end
local displayer = entry_display.create { local displayer = entry_display.create {
@@ -376,51 +489,42 @@ function make_entry.gen_from_lsp_symbols(opts)
hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" }, hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" },
items = display_items, items = display_items,
} }
local type_highlight = vim.F.if_nil(opts.symbol_highlights or lsp_type_highlight)
local make_display = function(entry) local make_display = function(entry)
local msg local msg
-- what to show in the last column: filename or symbol information if opts.show_line then
if opts.ignore_filename then -- ignore the filename and show line preview instead msg = vim.trim(vim.F.if_nil(vim.api.nvim_buf_get_lines(bufnr, entry.lnum - 1, entry.lnum, false)[1], ""))
-- TODO: fixme - if ignore_filename is set for workspace, bufnr will be incorrect
msg = vim.api.nvim_buf_get_lines(bufnr, entry.lnum - 1, entry.lnum, false)[1] or ""
msg = vim.trim(msg)
else
local filename = utils.transform_path(opts, entry.filename)
if opts.show_line then -- show inline line info
filename = filename .. " [" .. entry.lnum .. ":" .. entry.col .. "]"
end
msg = filename
end end
local type_highlight = opts.symbol_highlights or lsp_type_highlight if hidden then
local display_columns = { return displayer {
entry.symbol_name, entry.symbol_name,
{ entry.symbol_type:lower(), type_highlight[entry.symbol_type], type_highlight[entry.symbol_type] }, { entry.symbol_type:lower(), type_highlight[entry.symbol_type] },
msg, msg,
} }
else
if opts.ignore_filename and opts.show_line then return displayer {
table.insert(display_columns, 2, { entry.lnum .. ":" .. entry.col, "TelescopeResultsLineNr" }) utils.transform_path(opts, entry.filename),
end entry.symbol_name,
{ entry.symbol_type:lower(), type_highlight[entry.symbol_type] },
return displayer(display_columns) msg,
}
end
end end
local get_filename = get_filename_fn()
return function(entry) return function(entry)
local filename = entry.filename or vim.api.nvim_buf_get_name(entry.bufnr) local filename = vim.F.if_nil(entry.filename, get_filename(entry.bufnr))
local symbol_msg = entry.text local symbol_msg = entry.text
local symbol_type, symbol_name = symbol_msg:match "%[(.+)%]%s+(.*)" local symbol_type, symbol_name = symbol_msg:match "%[(.+)%]%s+(.*)"
local ordinal = "" local ordinal = ""
if not opts.ignore_filename and filename then if not hidden and filename then
ordinal = filename .. " " ordinal = filename .. " "
end end
ordinal = ordinal .. symbol_name .. " " .. (symbol_type or "unknown") ordinal = ordinal .. symbol_name .. " " .. (symbol_type or "unknown")
return { return make_entry.set_default_entry_mt({
valid = true,
value = entry, value = entry,
ordinal = ordinal, ordinal = ordinal,
display = make_display, display = make_display,
@@ -432,7 +536,7 @@ function make_entry.gen_from_lsp_symbols(opts)
symbol_type = symbol_type, symbol_type = symbol_type,
start = entry.start, start = entry.start,
finish = entry.finish, finish = entry.finish,
} }, opts)
end end
end end
@@ -460,8 +564,9 @@ function make_entry.gen_from_buffer(opts)
local cwd = vim.fn.expand(opts.cwd or vim.loop.cwd()) local cwd = vim.fn.expand(opts.cwd or vim.loop.cwd())
local make_display = function(entry) local make_display = function(entry)
-- bufnr_width + modes + icon + 3 spaces + : + lnum
opts.__prefix = opts.bufnr_width + 4 + icon_width + 3 + 1 + #tostring(entry.lnum)
local display_bufname = utils.transform_path(opts, entry.filename) local display_bufname = utils.transform_path(opts, entry.filename)
local icon, hl_group = utils.get_devicons(entry.filename, disable_devicons) local icon, hl_group = utils.get_devicons(entry.filename, disable_devicons)
return displayer { return displayer {
@@ -483,9 +588,7 @@ function make_entry.gen_from_buffer(opts)
local indicator = entry.flag .. hidden .. readonly .. changed local indicator = entry.flag .. hidden .. readonly .. changed
local line_count = vim.api.nvim_buf_line_count(entry.bufnr) local line_count = vim.api.nvim_buf_line_count(entry.bufnr)
return { return make_entry.set_default_entry_mt({
valid = true,
value = bufname, value = bufname,
ordinal = entry.bufnr .. " : " .. bufname, ordinal = entry.bufnr .. " : " .. bufname,
display = make_display, display = make_display,
@@ -495,7 +598,7 @@ function make_entry.gen_from_buffer(opts)
-- account for potentially stale lnum as getbufinfo might not be updated or from resuming buffers picker -- account for potentially stale lnum as getbufinfo might not be updated or from resuming buffers picker
lnum = entry.info.lnum ~= 0 and math.max(math.min(entry.info.lnum, line_count), 1) or 1, lnum = entry.info.lnum ~= 0 and math.max(math.min(entry.info.lnum, line_count), 1) or 1,
indicator = indicator, indicator = indicator,
} }, opts)
end end
end end
@@ -537,13 +640,12 @@ function make_entry.gen_from_treesitter(opts)
return displayer(display_columns) return displayer(display_columns)
end end
local get_filename = get_filename_fn()
return function(entry) return function(entry)
local ts_utils = require "nvim-treesitter.ts_utils" local ts_utils = require "nvim-treesitter.ts_utils"
local start_row, start_col, end_row, _ = ts_utils.get_node_range(entry.node) local start_row, start_col, end_row, _ = ts_utils.get_node_range(entry.node)
local node_text = vim.treesitter.get_node_text(entry.node, bufnr) local node_text = vim.treesitter.get_node_text(entry.node, bufnr)
return { return make_entry.set_default_entry_mt({
valid = true,
value = entry.node, value = entry.node,
kind = entry.kind, kind = entry.kind,
ordinal = node_text .. " " .. (entry.kind or "unknown"), ordinal = node_text .. " " .. (entry.kind or "unknown"),
@@ -551,14 +653,14 @@ function make_entry.gen_from_treesitter(opts)
node_text = node_text, node_text = node_text,
filename = vim.api.nvim_buf_get_name(bufnr), filename = get_filename(bufnr),
-- need to add one since the previewer substacts one -- need to add one since the previewer substacts one
lnum = start_row + 1, lnum = start_row + 1,
col = start_col, col = start_col,
text = node_text, text = node_text,
start = start_row, start = start_row,
finish = end_row, finish = end_row,
} }, opts)
end end
end end
@@ -573,14 +675,12 @@ function make_entry.gen_from_packages(opts)
end end
return function(module_name) return function(module_name)
local entry = { return make_entry.set_default_entry_mt({
valid = module_name ~= "", valid = module_name ~= "",
value = module_name, value = module_name,
ordinal = module_name, ordinal = module_name,
} display = make_display(module_name),
entry.display = make_display(module_name) }, opts)
return entry
end end
end end
@@ -622,21 +722,21 @@ function make_entry.gen_from_apropos(opts)
cmd = vim.split(cmd, ",")[1] cmd = vim.split(cmd, ",")[1]
return keyword return keyword
and sections[section] and sections[section]
and { and make_entry.set_default_entry_mt({
value = cmd, value = cmd,
description = desc, description = desc,
ordinal = cmd, ordinal = cmd,
display = make_display, display = make_display,
section = section, section = section,
keyword = keyword, keyword = keyword,
} }, opts)
or nil or nil
end end
end end
function make_entry.gen_from_marks(_) function make_entry.gen_from_marks(opts)
return function(item) return function(item)
return { return make_entry.set_default_entry_mt({
value = item.line, value = item.line,
ordinal = item.line, ordinal = item.line,
display = item.line, display = item.line,
@@ -644,11 +744,11 @@ function make_entry.gen_from_marks(_)
col = item.col, col = item.col,
start = item.lnum, start = item.lnum,
filename = item.filename, filename = item.filename,
} }, opts)
end end
end end
function make_entry.gen_from_registers(_) function make_entry.gen_from_registers(opts)
local displayer = entry_display.create { local displayer = entry_display.create {
separator = " ", separator = " ",
hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" }, hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" },
@@ -667,13 +767,12 @@ function make_entry.gen_from_registers(_)
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
valid = true,
value = entry, value = entry,
ordinal = entry, ordinal = entry,
content = vim.fn.getreg(entry), content = vim.fn.getreg(entry),
display = make_display, display = make_display,
} }, opts)
end end
end end
@@ -706,7 +805,7 @@ function make_entry.gen_from_keymaps(opts)
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
mode = entry.mode, mode = entry.mode,
lhs = get_lhs(entry), lhs = get_lhs(entry),
desc = get_desc(entry), desc = get_desc(entry),
@@ -715,22 +814,22 @@ function make_entry.gen_from_keymaps(opts)
value = entry, value = entry,
ordinal = entry.mode .. " " .. get_lhs(entry) .. " " .. get_desc(entry), ordinal = entry.mode .. " " .. get_lhs(entry) .. " " .. get_desc(entry),
display = make_display, display = make_display,
} }, opts)
end end
end end
function make_entry.gen_from_highlights() function make_entry.gen_from_highlights(opts)
local make_display = function(entry) local make_display = function(entry)
local display = entry.value local display = entry.value
return display, { { { 0, #display }, display } } return display, { { { 0, #display }, display } }
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
value = entry, value = entry,
display = make_display, display = make_display,
ordinal = entry, ordinal = entry,
} }, opts)
end end
end end
@@ -751,12 +850,12 @@ function make_entry.gen_from_picker(opts)
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
value = entry, value = entry,
text = entry.prompt_title, text = entry.prompt_title,
ordinal = string.format("%s %s", entry.prompt_title, utils.get_default(entry.default_text, "")), ordinal = string.format("%s %s", entry.prompt_title, vim.F.if_nil(entry.default_text, "")),
display = make_display, display = make_display,
} }, opts)
end end
end end
@@ -799,117 +898,61 @@ function make_entry.gen_from_buffer_lines(opts)
return return
end end
return { return make_entry.set_default_entry_mt({
valid = true,
ordinal = entry.text, ordinal = entry.text,
display = make_display, display = make_display,
filename = entry.filename, filename = entry.filename,
lnum = entry.lnum, lnum = entry.lnum,
text = entry.text, text = entry.text,
} }, opts)
end end
end end
function make_entry.gen_from_vimoptions() function make_entry.gen_from_vimoptions(opts)
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(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
local displayer = entry_display.create { local displayer = entry_display.create {
separator = "", separator = "",
hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" }, hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" },
items = { items = {
{ width = 25 }, { width = 25 },
{ width = 12 }, { width = 12 },
{ width = 11 },
{ remaining = true }, { remaining = true },
}, },
} }
local make_display = function(entry) local make_display = function(entry)
return displayer { return displayer {
{ entry.name, "Keyword" }, { entry.value.name, "Keyword" },
{ "[" .. entry.value_type .. "]", "Type" }, { "[" .. entry.value.type .. "]", "Type" },
utils.display_termcodes(tostring(entry.current_value)), { "[" .. entry.value.scope .. "]", "Identifier" },
entry.description, utils.display_termcodes(tostring(entry.value.value)),
} }
end end
return function(line) return function(o)
local entry = process_one_opt(line) local entry = {
if not entry then display = make_display,
return value = {
name = o.name,
value = o.default,
type = o.type,
scope = o.scope,
},
ordinal = string.format("%s %s %s", o.name, o.type, o.scope),
}
local ok, value = pcall(vim.api.nvim_get_option, o.name)
if ok then
entry.value.value = value
entry.ordinal = entry.ordinal .. " " .. utils.display_termcodes(tostring(value))
else
entry.ordinal = entry.ordinal .. " " .. utils.display_termcodes(tostring(o.default))
end end
entry.valid = true return make_entry.set_default_entry_mt(entry, opts)
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
end end
--- Special options:
--- - only_sort_tags: Only sort via tag name. Ignore filename and other items
function make_entry.gen_from_ctags(opts) function make_entry.gen_from_ctags(opts)
opts = opts or {} opts = opts or {}
@@ -960,6 +1003,11 @@ function make_entry.gen_from_ctags(opts)
local mt = {} local mt = {}
mt.__index = function(t, k) mt.__index = function(t, k)
local override = handle_entry_index(opts, t, k)
if override then
return override
end
if k == "path" then if k == "path" then
local retpath = Path:new({ t.filename }):absolute() local retpath = Path:new({ t.filename }):absolute()
if not vim.loop.fs_access(retpath, "R", nil) then if not vim.loop.fs_access(retpath, "R", nil) then
@@ -969,6 +1017,7 @@ function make_entry.gen_from_ctags(opts)
end end
end end
local current_file_cache = {}
return function(line) return function(line)
if line == "" or line:sub(1, 1) == "!" then if line == "" or line:sub(1, 1) == "!" then
return nil return nil
@@ -986,9 +1035,15 @@ function make_entry.gen_from_ctags(opts)
file = string.gsub(file, "/", "\\") file = string.gsub(file, "/", "\\")
end end
if opts.only_current_file and file ~= current_file then if opts.only_current_file then
if current_file_cache[file] == nil then
current_file_cache[file] = Path:new(file):normalize(cwd) == current_file
end
if current_file_cache[file] == false then
return nil return nil
end end
end
local tag_entry = {} local tag_entry = {}
if opts.only_sort_tags then if opts.only_sort_tags then
@@ -1031,11 +1086,12 @@ function make_entry.gen_from_diagnostics(opts)
end)() end)()
local display_items = { local display_items = {
{ width = utils.if_nil(signs, 8, 10) }, { width = signs ~= nil and 10 or 8 },
{ remaining = true }, { remaining = true },
} }
local line_width = vim.F.if_nil(opts.line_width, 0.5) local line_width = vim.F.if_nil(opts.line_width, 0.5)
if not utils.is_path_hidden(opts) then local hidden = utils.is_path_hidden(opts)
if not hidden then
table.insert(display_items, 2, { width = line_width }) table.insert(display_items, 2, { width = line_width })
end end
local displayer = entry_display.create { local displayer = entry_display.create {
@@ -1053,10 +1109,6 @@ function make_entry.gen_from_diagnostics(opts)
"Diagnostic" .. entry.type, "Diagnostic" .. entry.type,
} }
--TODO(conni2461): I dont like that this is symbol lnum:col | msg | filename
-- i want: symbol filename:lnum:col | msg
-- or : symbol lnum:col | msg
-- I think this is more natural
return displayer { return displayer {
line_info, line_info,
entry.text, entry.text,
@@ -1065,20 +1117,20 @@ function make_entry.gen_from_diagnostics(opts)
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
value = entry, value = entry,
ordinal = ("%s %s"):format(not opts.ignore_filename and entry.filename or "", entry.text), ordinal = ("%s %s"):format(not hidden and entry.filename or "", entry.text),
display = make_display, display = make_display,
filename = entry.filename, filename = entry.filename,
type = entry.type, type = entry.type,
lnum = entry.lnum, lnum = entry.lnum,
col = entry.col, col = entry.col,
text = entry.text, text = entry.text,
} }, opts)
end end
end end
function make_entry.gen_from_autocommands(_) function make_entry.gen_from_autocommands(opts)
local displayer = entry_display.create { local displayer = entry_display.create {
separator = "", separator = "",
items = { items = {
@@ -1091,32 +1143,30 @@ function make_entry.gen_from_autocommands(_)
local make_display = function(entry) local make_display = function(entry)
return displayer { return displayer {
{ entry.event, "vimAutoEvent" }, { entry.value.event, "vimAutoEvent" },
{ entry.group, "vimAugroup" }, { entry.value.group_name, "vimAugroup" },
{ entry.ft_pattern, "vimAutoCmdSfxList" }, { entry.value.pattern, "vimAutoCmdSfxList" },
entry.command, entry.value.command,
} }
end end
-- TODO: <action> dump current filtered items to buffer
return function(entry) return function(entry)
return { local group_name = vim.F.if_nil(entry.group_name, "<anonymous>")
return make_entry.set_default_entry_mt({
value = {
event = entry.event, event = entry.event,
group = entry.group, group_name = group_name,
ft_pattern = entry.ft_pattern, pattern = entry.pattern,
command = entry.command, command = entry.command,
value = string.format("+%d %s", entry.source_lnum, entry.source_file), },
source_file = entry.source_file,
source_lnum = entry.source_lnum,
-- --
valid = true, ordinal = entry.event .. " " .. group_name .. " " .. entry.pattern .. " " .. entry.command,
ordinal = entry.event .. " " .. entry.group .. " " .. entry.ft_pattern .. " " .. entry.command,
display = make_display, display = make_display,
} }, opts)
end end
end end
function make_entry.gen_from_commands(_) function make_entry.gen_from_commands(opts)
local displayer = entry_display.create { local displayer = entry_display.create {
separator = "", separator = "",
items = { items = {
@@ -1149,7 +1199,7 @@ function make_entry.gen_from_commands(_)
end end
return function(entry) return function(entry)
return { return make_entry.set_default_entry_mt({
name = entry.name, name = entry.name,
bang = entry.bang, bang = entry.bang,
nargs = entry.nargs, nargs = entry.nargs,
@@ -1157,10 +1207,9 @@ function make_entry.gen_from_commands(_)
definition = entry.definition, definition = entry.definition,
-- --
value = entry, value = entry,
valid = true,
ordinal = entry.name, ordinal = entry.name,
display = make_display, display = make_display,
} }, opts)
end end
end end
@@ -1219,13 +1268,13 @@ function make_entry.gen_from_git_status(opts)
end end
local mod, file = string.match(entry, "(..).*%s[->%s]?(.+)") local mod, file = string.match(entry, "(..).*%s[->%s]?(.+)")
return { return setmetatable({
value = file, value = file,
status = mod, status = mod,
ordinal = entry, ordinal = entry,
display = make_display, display = make_display,
path = Path:new({ opts.cwd, file }):absolute(), path = Path:new({ opts.cwd, file }):absolute(),
} }, opts)
end end
end end

View File

@@ -24,8 +24,6 @@ local p_window = require "telescope.pickers.window"
local EntryManager = require "telescope.entry_manager" local EntryManager = require "telescope.entry_manager"
local MultiSelect = require "telescope.pickers.multi" local MultiSelect = require "telescope.pickers.multi"
local get_default = utils.get_default
local truncate = require("plenary.strings").truncate local truncate = require("plenary.strings").truncate
local strdisplaywidth = require("plenary.strings").strdisplaywidth local strdisplaywidth = require("plenary.strings").strdisplaywidth
@@ -65,26 +63,27 @@ function Picker:new(opts)
-- pcall(v.clear) -- pcall(v.clear)
-- end -- end
local layout_strategy = get_default(opts.layout_strategy, config.values.layout_strategy) local layout_strategy = vim.F.if_nil(opts.layout_strategy, config.values.layout_strategy)
local obj = setmetatable({ local obj = setmetatable({
prompt_title = get_default(opts.prompt_title, config.values.prompt_title), prompt_title = vim.F.if_nil(opts.prompt_title, config.values.prompt_title),
results_title = get_default(opts.results_title, config.values.results_title), results_title = vim.F.if_nil(opts.results_title, config.values.results_title),
-- either whats passed in by the user or whats defined by the previewer -- either whats passed in by the user or whats defined by the previewer
preview_title = opts.preview_title, preview_title = opts.preview_title,
prompt_prefix = get_default(opts.prompt_prefix, config.values.prompt_prefix), prompt_prefix = vim.F.if_nil(opts.prompt_prefix, config.values.prompt_prefix),
wrap_results = get_default(opts.wrap_results, config.values.wrap_results), wrap_results = vim.F.if_nil(opts.wrap_results, config.values.wrap_results),
selection_caret = get_default(opts.selection_caret, config.values.selection_caret), selection_caret = vim.F.if_nil(opts.selection_caret, config.values.selection_caret),
entry_prefix = get_default(opts.entry_prefix, config.values.entry_prefix), entry_prefix = vim.F.if_nil(opts.entry_prefix, config.values.entry_prefix),
multi_icon = get_default(opts.multi_icon, config.values.multi_icon), multi_icon = vim.F.if_nil(opts.multi_icon, config.values.multi_icon),
initial_mode = get_default(opts.initial_mode, config.values.initial_mode), initial_mode = vim.F.if_nil(opts.initial_mode, config.values.initial_mode),
_original_mode = vim.api.nvim_get_mode().mode, _original_mode = vim.api.nvim_get_mode().mode,
debounce = get_default(tonumber(opts.debounce), nil), debounce = vim.F.if_nil(tonumber(opts.debounce), nil),
_finder_attached = true,
default_text = opts.default_text, default_text = opts.default_text,
get_status_text = get_default(opts.get_status_text, config.values.get_status_text), get_status_text = vim.F.if_nil(opts.get_status_text, config.values.get_status_text),
_on_input_filter_cb = opts.on_input_filter_cb or function() end, _on_input_filter_cb = opts.on_input_filter_cb or function() end,
finder = assert(opts.finder, "Finder is required."), finder = assert(opts.finder, "Finder is required."),
@@ -95,7 +94,7 @@ function Picker:new(opts)
default_selection_index = opts.default_selection_index, default_selection_index = opts.default_selection_index,
get_selection_window = get_default(opts.get_selection_window, config.values.get_selection_window), get_selection_window = vim.F.if_nil(opts.get_selection_window, config.values.get_selection_window),
cwd = opts.cwd, cwd = opts.cwd,
@@ -106,32 +105,32 @@ function Picker:new(opts)
and opts._multi and opts._multi
or MultiSelect:new(), or MultiSelect:new(),
track = get_default(opts.track, false), track = vim.F.if_nil(opts.track, false),
stats = {}, stats = {},
attach_mappings = opts.attach_mappings, attach_mappings = opts.attach_mappings,
file_ignore_patterns = get_default(opts.file_ignore_patterns, config.values.file_ignore_patterns), file_ignore_patterns = vim.F.if_nil(opts.file_ignore_patterns, config.values.file_ignore_patterns),
scroll_strategy = get_default(opts.scroll_strategy, config.values.scroll_strategy), scroll_strategy = vim.F.if_nil(opts.scroll_strategy, config.values.scroll_strategy),
sorting_strategy = get_default(opts.sorting_strategy, config.values.sorting_strategy), sorting_strategy = vim.F.if_nil(opts.sorting_strategy, config.values.sorting_strategy),
tiebreak = get_default(opts.tiebreak, config.values.tiebreak), tiebreak = vim.F.if_nil(opts.tiebreak, config.values.tiebreak),
selection_strategy = get_default(opts.selection_strategy, config.values.selection_strategy), selection_strategy = vim.F.if_nil(opts.selection_strategy, config.values.selection_strategy),
push_cursor_on_edit = get_default(opts.push_cursor_on_edit, false), push_cursor_on_edit = vim.F.if_nil(opts.push_cursor_on_edit, false),
push_tagstack_on_edit = get_default(opts.push_tagstack_on_edit, false), push_tagstack_on_edit = vim.F.if_nil(opts.push_tagstack_on_edit, false),
layout_strategy = layout_strategy, layout_strategy = layout_strategy,
layout_config = config.smarter_depth_2_extend(opts.layout_config or {}, config.values.layout_config or {}), layout_config = config.smarter_depth_2_extend(opts.layout_config or {}, config.values.layout_config or {}),
__cycle_layout_list = get_default(opts.cycle_layout_list, config.values.cycle_layout_list), __cycle_layout_list = vim.F.if_nil(opts.cycle_layout_list, config.values.cycle_layout_list),
window = { window = {
winblend = get_default( winblend = vim.F.if_nil(
opts.winblend, opts.winblend,
type(opts.window) == "table" and opts.window.winblend or config.values.winblend type(opts.window) == "table" and opts.window.winblend or config.values.winblend
), ),
border = get_default(opts.border, type(opts.window) == "table" and opts.window.border or config.values.border), border = vim.F.if_nil(opts.border, type(opts.window) == "table" and opts.window.border or config.values.border),
borderchars = get_default( borderchars = vim.F.if_nil(
opts.borderchars, opts.borderchars,
type(opts.window) == "table" and opts.window.borderchars or config.values.borderchars type(opts.window) == "table" and opts.window.borderchars or config.values.borderchars
), ),
@@ -505,10 +504,12 @@ function Picker:find()
-- Register attach -- Register attach
vim.api.nvim_buf_attach(prompt_bufnr, false, { vim.api.nvim_buf_attach(prompt_bufnr, false, {
on_lines = function(...) on_lines = function(...)
if self._finder_attached then
find_id = self:_next_find_id() find_id = self:_next_find_id()
status_updater { completed = false } status_updater { completed = false }
self._on_lines(...) self._on_lines(...)
end
end, end,
on_detach = function() on_detach = function()
@@ -692,7 +693,7 @@ end
--- ---
--- Example usage in telescope: --- Example usage in telescope:
--- - `actions.delete_buffer()` --- - `actions.delete_buffer()`
---@param delete_cb function: called with each deleted selection ---@param delete_cb function: called for each selection fn(s) -> bool|nil (true|nil removes the entry from the results)
function Picker:delete_selection(delete_cb) function Picker:delete_selection(delete_cb)
vim.validate { delete_cb = { delete_cb, "f" } } vim.validate { delete_cb = { delete_cb, "f" } }
local original_selection_strategy = self.selection_strategy local original_selection_strategy = self.selection_strategy
@@ -718,8 +719,10 @@ function Picker:delete_selection(delete_cb)
return x > y return x > y
end) end)
for _, index in ipairs(selection_index) do for _, index in ipairs(selection_index) do
local selection = table.remove(self.finder.results, index) local delete_cb_return = delete_cb(self.finder.results[index])
delete_cb(selection) if delete_cb_return == nil or delete_cb_return == true then
table.remove(self.finder.results, index)
end
end end
if used_multi_select then if used_multi_select then
@@ -908,7 +911,7 @@ function Picker:refresh(finder, opts)
local handle = type(opts.new_prefix) == "table" and unpack or function(x) local handle = type(opts.new_prefix) == "table" and unpack or function(x)
return x return x
end end
self:change_prompt_prefix(handle(opts.new_prefix)) self:change_prompt_prefix(handle(opts.new_prefix), opts.prefix_hl_group)
end end
if finder then if finder then
@@ -962,6 +965,9 @@ function Picker:set_selection(row)
state.set_global_key("selected_entry", entry) state.set_global_key("selected_entry", entry)
if not entry then if not entry then
-- also refresh previewer when there is no entry selected, so the preview window is cleared
self._selection_entry = entry
self:refresh_previewer()
return return
end end
@@ -1065,10 +1071,6 @@ end
--- Refresh the previewer based on the current `status` of the picker --- Refresh the previewer based on the current `status` of the picker
function Picker:refresh_previewer() function Picker:refresh_previewer()
local status = state.get_status(self.prompt_bufnr) local status = state.get_status(self.prompt_bufnr)
if not self._selection_entry then
-- if selection_entry is nil there is nothing to be previewed
return
end
if self.previewer and status.preview_win and a.nvim_win_is_valid(status.preview_win) then if self.previewer and status.preview_win and a.nvim_win_is_valid(status.preview_win) then
self:_increment "previewed" self:_increment "previewed"
@@ -1365,6 +1367,16 @@ function Picker:_do_selection(prompt)
else else
self:set_selection(self:get_reset_row()) self:set_selection(self:get_reset_row())
end end
elseif selection_strategy == "none" then
if self._selection_entry then
local old_entry, old_row = self._selection_entry, self._selection_row
self:reset_selection() -- required to reset selection before updating prefix
if old_row >= 0 then
self:update_prefix(old_entry, old_row)
self.highlighter:hi_multiselect(old_row, self:is_multi_selected(old_entry))
end
end
return
else else
error("Unknown selection strategy: " .. selection_strategy) error("Unknown selection strategy: " .. selection_strategy)
end end
@@ -1495,6 +1507,11 @@ function Picker:_reset_highlights()
vim.api.nvim_buf_clear_namespace(self.results_bufnr, ns_telescope_matching, 0, -1) vim.api.nvim_buf_clear_namespace(self.results_bufnr, ns_telescope_matching, 0, -1)
end end
-- Toggles whether finder is attached to prompt buffer input
function Picker:_toggle_finder_attach()
self._finder_attached = not self._finder_attached
end
function Picker:_detach() function Picker:_detach()
self.finder:close() self.finder:close()

View File

@@ -1,3 +1,63 @@
---@tag telescope.pickers.entry_display
---@brief [[
--- Entry Display is used to format each entry shown in the result panel.
---
--- Entry Display create() will give us a function based on the configuration
--- of column widths we pass into it. We then can use this function n times to
--- return a string based on structured input.
---
--- Note that if you call `create()` inside `make_display` it will be called for
--- every single entry. So it is suggested to do this outside of `make_display`
--- for the best performance.
---
--- The create function will use the column widths passed to it in
--- configaration.items. Each item in that table is the number of characters in
--- the column. It's also possible for the final column to not have a fixed
--- width, this will be shown in the configuartion as 'remaining = true'.
---
--- An example of this configuration is shown for the buffers picker
--- <code>
--- local displayer = entry_display.create {
--- separator = " ",
--- items = {
--- { width = opts.bufnr_width },
--- { width = 4 },
--- { width = icon_width },
--- { remaining = true },
--- },
--- }
--- </code>
---
--- This shows 4 columns, the first is defined in the opts as the width we'll
--- use when display_string the number of the buffer. The second has a fixed
--- width of 4 and the 3rd column's widht will be decided by the width of the
--- icons we use. The fourth column will use the remaining space. Finally we
--- have also defined the seperator between each column will be the space " ".
---
--- An example of how the display reference will be used is shown, again for
--- the buffers picker:
--- <code>
--- return displayer {
--- { entry.bufnr, "TelescopeResultsNumber" },
--- { entry.indicator, "TelescopeResultsComment" },
--- { icon, hl_group },
--- display_bufname .. ":" .. entry.lnum,
--- }
--- </code>
---
--- There are two types of values each column can have. Either a simple String
--- or a table containing the String as well as the hl_group.
---
--- The displayer can return values, string and an optional highlights.
--- String is all the text to be displayed for this entry as a single string. If
--- parts of the string are to be highlighted they will be described in the
--- highlights table.
---
--- For better understanding of how create() and displayer are used it's best to look
--- at the code in make_entry.lua.
---@brief ]]
local strings = require "plenary.strings" local strings = require "plenary.strings"
local state = require "telescope.state" local state = require "telescope.state"
local resolve = require "telescope.config.resolve" local resolve = require "telescope.config.resolve"

View File

@@ -53,7 +53,6 @@
local resolve = require "telescope.config.resolve" local resolve = require "telescope.config.resolve"
local p_window = require "telescope.pickers.window" local p_window = require "telescope.pickers.window"
local if_nil = vim.F.if_nil
local get_border_size = function(opts) local get_border_size = function(opts)
if opts.window.border == false then if opts.window.border == false then
@@ -125,7 +124,7 @@ local function validate_layout_config(strategy_name, configuration, values, defa
local valid_configuration_keys = get_valid_configuration_keys(configuration) local valid_configuration_keys = get_valid_configuration_keys(configuration)
-- If no default_layout_config provided, check Telescope's config values -- If no default_layout_config provided, check Telescope's config values
default_layout_config = if_nil(default_layout_config, require("telescope.config").values.layout_config) default_layout_config = vim.F.if_nil(default_layout_config, require("telescope.config").values.layout_config)
local result = {} local result = {}
local get_value = function(k) local get_value = function(k)
@@ -263,7 +262,7 @@ local function make_documented_layout(name, layout_config, layout)
validate_layout_config( validate_layout_config(
name, name,
layout_config, layout_config,
vim.tbl_deep_extend("keep", if_nil(override_layout, {}), if_nil(self.layout_config, {})) vim.tbl_deep_extend("keep", vim.F.if_nil(override_layout, {}), vim.F.if_nil(self.layout_config, {}))
) )
) )
end end
@@ -320,7 +319,7 @@ layout_strategies.horizontal = make_documented_layout(
-- Cap over/undersized width (with previewer) -- Cap over/undersized width (with previewer)
width, w_space = calc_size_and_spacing(width, max_columns, bs, 2, 4, 1) width, w_space = calc_size_and_spacing(width, max_columns, bs, 2, 4, 1)
preview.width = resolve.resolve_width(if_nil(layout_config.preview_width, function(_, cols) preview.width = resolve.resolve_width(vim.F.if_nil(layout_config.preview_width, function(_, cols)
if cols < 150 then if cols < 150 then
return math.floor(cols * 0.4) return math.floor(cols * 0.4)
elseif cols < 200 then elseif cols < 200 then
@@ -588,7 +587,7 @@ layout_strategies.cursor = make_documented_layout(
-- Cap over/undersized width (with preview) -- Cap over/undersized width (with preview)
width, w_space = calc_size_and_spacing(width, max_columns, bs, 2, 4, 0) width, w_space = calc_size_and_spacing(width, max_columns, bs, 2, 4, 0)
preview.width = resolve.resolve_width(if_nil(layout_config.preview_width, 2 / 3))(self, width, max_lines) preview.width = resolve.resolve_width(vim.F.if_nil(layout_config.preview_width, 2 / 3))(self, width, max_lines)
prompt.width = width - preview.width - w_space prompt.width = width - preview.width - w_space
results.width = prompt.width results.width = prompt.width
else else
@@ -694,7 +693,11 @@ layout_strategies.vertical = make_documented_layout(
-- Cap over/undersized height (with previewer) -- Cap over/undersized height (with previewer)
height, h_space = calc_size_and_spacing(height, max_lines, bs, 3, 6, 2) height, h_space = calc_size_and_spacing(height, max_lines, bs, 3, 6, 2)
preview.height = resolve.resolve_height(if_nil(layout_config.preview_height, 0.5))(self, max_columns, height) preview.height = resolve.resolve_height(vim.F.if_nil(layout_config.preview_height, 0.5))(
self,
max_columns,
height
)
else else
-- Cap over/undersized height (without previewer) -- Cap over/undersized height (without previewer)
height, h_space = calc_size_and_spacing(height, max_lines, bs, 2, 4, 1) height, h_space = calc_size_and_spacing(height, max_lines, bs, 2, 4, 1)
@@ -764,8 +767,8 @@ layout_strategies.flex = make_documented_layout(
horizontal = "Options to pass when switching to horizontal layout", horizontal = "Options to pass when switching to horizontal layout",
}), }),
function(self, max_columns, max_lines, layout_config) function(self, max_columns, max_lines, layout_config)
local flip_columns = if_nil(layout_config.flip_columns, 100) local flip_columns = vim.F.if_nil(layout_config.flip_columns, 100)
local flip_lines = if_nil(layout_config.flip_lines, 20) local flip_lines = vim.F.if_nil(layout_config.flip_lines, 20)
if max_columns < flip_columns and max_lines > flip_lines then if max_columns < flip_columns and max_lines > flip_lines then
self.__flex_strategy = "vertical" self.__flex_strategy = "vertical"
@@ -851,7 +854,7 @@ layout_strategies.bottom_pane = make_documented_layout(
local tbln local tbln
max_lines, tbln = calc_tabline(max_lines) max_lines, tbln = calc_tabline(max_lines)
local height = if_nil(resolve.resolve_height(layout_config.height)(self, max_columns, max_lines), 25) local height = vim.F.if_nil(resolve.resolve_height(layout_config.height)(self, max_columns, max_lines), 25)
if type(layout_config.height) == "table" and type(layout_config.height.padding) == "number" then if type(layout_config.height) == "table" and type(layout_config.height.padding) == "number" then
-- Since bottom_pane only has padding at the top, we only need half as much padding in total -- Since bottom_pane only has padding at the top, we only need half as much padding in total
-- This doesn't match the vim help for `resolve.resolve_height`, but it matches expectations -- This doesn't match the vim help for `resolve.resolve_height`, but it matches expectations
@@ -874,7 +877,7 @@ layout_strategies.bottom_pane = make_documented_layout(
-- Cap over/undersized width (with preview) -- Cap over/undersized width (with preview)
local width, w_space = calc_size_and_spacing(max_columns, max_columns, bs, 2, 4, 0) local width, w_space = calc_size_and_spacing(max_columns, max_columns, bs, 2, 4, 0)
preview.width = resolve.resolve_width(if_nil(layout_config.preview_width, 0.5))(self, width, max_lines) preview.width = resolve.resolve_width(vim.F.if_nil(layout_config.preview_width, 0.5))(self, width, max_lines)
results.width = width - preview.width - w_space results.width = width - preview.width - w_space
else else
results.width = prompt.width results.width = prompt.width

View File

@@ -386,6 +386,10 @@ previewers.new_buffer_previewer = function(opts)
opts.define_preview(self, entry, status) opts.define_preview(self, entry, status)
vim.schedule(function() vim.schedule(function()
if not self or not self.state or not self.state.bufnr then
return
end
if vim.api.nvim_buf_is_valid(self.state.bufnr) then if vim.api.nvim_buf_is_valid(self.state.bufnr) then
vim.api.nvim_buf_call(self.state.bufnr, function() vim.api.nvim_buf_call(self.state.bufnr, function()
vim.cmd "do User TelescopePreviewerLoaded" vim.cmd "do User TelescopePreviewerLoaded"
@@ -715,8 +719,12 @@ previewers.git_stash_diff = defaulter(function(opts)
value = entry.value, value = entry.value,
bufname = self.state.bufname, bufname = self.state.bufname,
cwd = opts.cwd, cwd = opts.cwd,
callback = function(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
putils.regex_highlighter(bufnr, "diff")
end
end,
}) })
putils.regex_highlighter(self.state.bufnr, "diff")
end, end,
} }
end, {}) end, {})
@@ -741,10 +749,12 @@ previewers.git_commit_diff_to_parent = defaulter(function(opts)
bufname = self.state.bufname, bufname = self.state.bufname,
cwd = opts.cwd, cwd = opts.cwd,
callback = function(bufnr) callback = function(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
search_cb_jump(self, bufnr, opts.current_line) search_cb_jump(self, bufnr, opts.current_line)
putils.regex_highlighter(bufnr, "diff")
end
end, end,
}) })
putils.regex_highlighter(self.state.bufnr, "diff")
end, end,
} }
end, {}) end, {})
@@ -770,10 +780,12 @@ previewers.git_commit_diff_to_head = defaulter(function(opts)
bufname = self.state.bufname, bufname = self.state.bufname,
cwd = opts.cwd, cwd = opts.cwd,
callback = function(bufnr) callback = function(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
search_cb_jump(self, bufnr, opts.current_line) search_cb_jump(self, bufnr, opts.current_line)
putils.regex_highlighter(bufnr, "diff")
end
end, end,
}) })
putils.regex_highlighter(self.state.bufnr, "diff")
end, end,
} }
end, {}) end, {})
@@ -799,10 +811,12 @@ previewers.git_commit_diff_as_was = defaulter(function(opts)
bufname = self.state.bufname, bufname = self.state.bufname,
cwd = opts.cwd, cwd = opts.cwd,
callback = function(bufnr) callback = function(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
search_cb_jump(self, bufnr, opts.current_line) search_cb_jump(self, bufnr, opts.current_line)
putils.regex_highlighter(bufnr, ft)
end
end, end,
}) })
putils.highlighter(self.state.bufnr, ft)
end, end,
} }
end, {}) end, {})
@@ -864,8 +878,12 @@ previewers.git_file_diff = defaulter(function(opts)
value = entry.value, value = entry.value,
bufname = self.state.bufname, bufname = self.state.bufname,
cwd = opts.cwd, cwd = opts.cwd,
callback = function(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
putils.regex_highlighter(bufnr, "diff")
end
end,
}) })
putils.regex_highlighter(self.state.bufnr, "diff")
end end
end, end,
} }
@@ -881,12 +899,12 @@ previewers.autocommands = defaulter(function(_)
end, end,
get_buffer_by_name = function(_, entry) get_buffer_by_name = function(_, entry)
return entry.group return entry.value.group_name
end, end,
define_preview = function(self, entry, status) define_preview = function(self, entry, status)
local results = vim.tbl_filter(function(x) local results = vim.tbl_filter(function(x)
return x.group == entry.group return x.value.group_name == entry.value.group_name
end, status.picker.finder.results) end, status.picker.finder.results)
if self.state.last_set_bufnr then if self.state.last_set_bufnr then
@@ -894,9 +912,9 @@ previewers.autocommands = defaulter(function(_)
end end
local selected_row = 0 local selected_row = 0
if self.state.bufname ~= entry.group then if self.state.bufname ~= entry.value.group_name then
local display = {} local display = {}
table.insert(display, string.format(" augroup: %s - [ %d entries ]", entry.group, #results)) table.insert(display, string.format(" augroup: %s - [ %d entries ]", entry.value.group_name, #results))
-- TODO: calculate banner width/string in setup() -- TODO: calculate banner width/string in setup()
-- TODO: get column characters to be the same HL group as border -- TODO: get column characters to be the same HL group as border
table.insert(display, string.rep("", vim.fn.getwininfo(status.preview_win)[1].width)) table.insert(display, string.rep("", vim.fn.getwininfo(status.preview_win)[1].width))
@@ -905,7 +923,10 @@ previewers.autocommands = defaulter(function(_)
if item == entry then if item == entry then
selected_row = idx selected_row = idx
end end
table.insert(display, string.format(" %-14s▏%-08s %s", item.event, item.ft_pattern, item.command)) table.insert(
display,
string.format(" %-14s▏%-08s %s", item.value.event, item.value.ft_pattern, item.value.command)
)
end end
vim.api.nvim_buf_set_option(self.state.bufnr, "filetype", "vim") vim.api.nvim_buf_set_option(self.state.bufnr, "filetype", "vim")

View File

@@ -1,3 +1,5 @@
local utils = require "telescope.utils"
local Previewer = {} local Previewer = {}
Previewer.__index = Previewer Previewer.__index = Previewer
@@ -25,11 +27,19 @@ function Previewer:new(opts)
_send_input = opts.send_input, _send_input = opts.send_input,
_scroll_fn = opts.scroll_fn, _scroll_fn = opts.scroll_fn,
preview_fn = opts.preview_fn, preview_fn = opts.preview_fn,
_empty_bufnr = nil,
}, Previewer) }, Previewer)
end end
function Previewer:preview(entry, status) function Previewer:preview(entry, status)
if not entry then if not entry then
if not self._empty_bufnr then
self._empty_bufnr = vim.api.nvim_create_buf(false, true)
end
if vim.api.nvim_buf_is_valid(self._empty_bufnr) then
vim.api.nvim_win_set_buf(status.preview_win, self._empty_bufnr)
end
return return
end end
@@ -47,7 +57,11 @@ end
function Previewer:title(entry, dynamic) function Previewer:title(entry, dynamic)
if dynamic == true and self._dyn_title_fn ~= nil then if dynamic == true and self._dyn_title_fn ~= nil then
if entry == nil then if entry == nil then
return nil if self._title_fn ~= nil then
return self:_title_fn()
else
return ""
end
end end
return self:_dyn_title_fn(entry) return self:_dyn_title_fn(entry)
end end
@@ -57,6 +71,9 @@ function Previewer:title(entry, dynamic)
end end
function Previewer:teardown() function Previewer:teardown()
if self._empty_bufnr then
utils.buf_delete(self._empty_bufnr)
end
if self._teardown_func then if self._teardown_func then
self:_teardown_func() self:_teardown_func()
end end

View File

@@ -82,12 +82,26 @@ end
utils.highlighter = function(bufnr, ft, opts) utils.highlighter = function(bufnr, ft, opts)
opts = opts or {} opts = opts or {}
opts.preview = opts.preview or {} opts.preview = opts.preview or {}
opts.preview.treesitter = vim.F.if_nil( opts.preview.treesitter = vim.F.if_nil(opts.preview.treesitter, conf.preview.treesitter)
opts.preview.treesitter, if type(opts.preview.treesitter) == "boolean" then
type(conf.preview) == "table" and conf.preview.treesitter local temp = { enable = opts.preview.treesitter }
) opts.preview.treesitter = temp
local ts_highlighting = opts.preview.treesitter == true end
or type(opts.preview.treesitter) == "table" and vim.tbl_contains(opts.preview.treesitter, ft)
local ts_highlighting = (function()
if type(opts.preview.treesitter.enable) == "table" then
if vim.tbl_contains(opts.preview.treesitter.enable, ft) then
return true
end
return false
end
if vim.tbl_contains(vim.F.if_nil(opts.preview.treesitter.disable, {}), ft) then
return false
end
return opts.preview.treesitter.enable == nil or opts.preview.treesitter.enable == true
end)()
local ts_success local ts_success
if ts_highlighting then if ts_highlighting then

View File

@@ -602,7 +602,7 @@ end
sorters.prefilter = function(opts) sorters.prefilter = function(opts)
local sorter = opts.sorter local sorter = opts.sorter
opts.delimiter = util.get_default(opts.delimiter, ":") opts.delimiter = vim.F.if_nil(opts.delimiter, ":")
sorter._delimiter = opts.delimiter sorter._delimiter = opts.delimiter
sorter.tags = create_tag_set(opts.tag) sorter.tags = create_tag_set(opts.tag)
sorter.filter_function = filter_function(opts) sorter.filter_function = filter_function(opts)

View File

@@ -1,3 +1,10 @@
---@tag telescope.utils
---@config { ["module"] = "telescope.utils" }
---@brief [[
--- Utilities for writing telescope pickers
---@brief ]]
local Path = require "plenary.path" local Path = require "plenary.path"
local Job = require "plenary.job" local Job = require "plenary.job"
@@ -13,6 +20,7 @@ utils.get_separator = function()
end end
utils.if_nil = function(x, was_nil, was_not_nil) utils.if_nil = function(x, was_nil, was_not_nil)
log.error "telescope.utils.if_nil is deprecated and will be removed. Please use vim.F.if_nil"
if x == nil then if x == nil then
return was_nil return was_nil
else else
@@ -21,6 +29,7 @@ utils.if_nil = function(x, was_nil, was_not_nil)
end end
utils.get_default = function(x, default) utils.get_default = function(x, default)
log.error "telescope.utils.get_default is deprecated and will be removed. Please use vim.F.if_nil"
return utils.if_nil(x, default, x) return utils.if_nil(x, default, x)
end end
@@ -191,7 +200,7 @@ utils.path_tail = (function()
end)() end)()
utils.is_path_hidden = function(opts, path_display) utils.is_path_hidden = function(opts, path_display)
path_display = path_display or utils.get_default(opts.path_display, require("telescope.config").values.path_display) path_display = path_display or vim.F.if_nil(opts.path_display, require("telescope.config").values.path_display)
return path_display == nil return path_display == nil
or path_display == "hidden" or path_display == "hidden"
@@ -210,6 +219,16 @@ local calc_result_length = function(truncate_len)
return type(truncate_len) == "number" and len - truncate_len or len return type(truncate_len) == "number" and len - truncate_len or len
end end
--- Transform path is a util function that formats a path based on path_display
--- found in `opts` or the default value from config.
--- It is meant to be used in make_entry to have a uniform interface for
--- builtins as well as extensions utilizing the same user configuration
--- Note: It is only supported inside `make_entry`/`make_display` the use of
--- this function outside of telescope might yield to undefined behavior and will
--- not be addressed by us
---@param opts table: The opts the users passed into the picker. Might contains a path_display key
---@param path string: The path that should be formated
---@return string: The transformed path ready to be displayed
utils.transform_path = function(opts, path) utils.transform_path = function(opts, path)
if path == nil then if path == nil then
return return
@@ -218,7 +237,7 @@ utils.transform_path = function(opts, path)
return path return path
end end
local path_display = utils.get_default(opts.path_display, require("telescope.config").values.path_display) local path_display = vim.F.if_nil(opts.path_display, require("telescope.config").values.path_display)
local transformed_path = path local transformed_path = path
@@ -257,7 +276,10 @@ utils.transform_path = function(opts, path)
if opts.__length == nil then if opts.__length == nil then
opts.__length = calc_result_length(path_display.truncate) opts.__length = calc_result_length(path_display.truncate)
end end
transformed_path = truncate(transformed_path, opts.__length, nil, -1) if opts.__prefix == nil then
opts.__prefix = 0
end
transformed_path = truncate(transformed_path, opts.__length - opts.__prefix, nil, -1)
end end
end end

View File

@@ -75,6 +75,14 @@ describe("telescope.config.resolve", function()
end end
end) end)
it("should handle percentages with min/max boundary", function()
eq(20, resolve.resolve_width { 0.1, min = 20 }(nil, 40, 120))
eq(30, resolve.resolve_height { 0.1, min = 20 }(nil, 40, 300))
eq(24, resolve.resolve_width { 0.4, max = 80 }(nil, 60, 60))
eq(80, resolve.resolve_height { 0.4, max = 80 }(nil, 60, 300))
end)
it("should handle fixed size", function() it("should handle fixed size", function()
local fixed = { 5, 8, 13, 21, 34 } local fixed = { 5, 8, 13, 21, 34 }
for _, s in ipairs(test_sizes) do for _, s in ipairs(test_sizes) do

View File

@@ -1,47 +0,0 @@
local finders = require('telescope.finders')
local previewers = require('telescope.previewers')
local pickers = require('telescope.pickers')
local sorters = require('telescope.sorters')
-- Get all the items from v:oldfiles that are valid files
local valid_oldfiles = vim.tbl_filter(function(val)
return 0 ~= vim.fn.filereadable(val)
end, vim.v.oldfiles)
-- print(vim.inspect(valid_oldfiles))
-- => {
-- "/home/tj/blah.txt",
-- "/home/tj/another_dir/file.py",
-- ...
-- }
-- Create a finder from a Lua list.
local oldfiles_finder = finders.new_table(valid_oldfiles)
-- Get a pre-defined sorter.
-- Sorters return a "score" for each "Entry" found by a finder.
--
-- This sorter is optimized to best find files in a fuzzy manner.
local oldfiles_sorter = sorters.get_fuzzy_file()
-- Get a pre-defined previewer.
-- Previewers take the currently selected entry,
-- and put a preview of it in a floating window
local oldfiles_previewer = previewers.cat
-- Create and run a Picker.
-- Pickers are the main entry point to telescope.
-- They manage the interactions between:
-- Finder,
-- Sorter,
-- Previewer
--
-- And provide the UI for the user.
pickers.new {
prompt = 'Oldfiles',
finder = oldfiles_finder,
sorter = oldfiles_sorter,
previewer = oldfiles_previewer,
}:find()

View File

@@ -1,30 +0,0 @@
local finders = require('telescope.finders')
local previewers = require('telescope.previewers')
local pickers = require('telescope.pickers')
-- Create a new finder.
-- This finder, rather than taking a Lua list,
-- generates a shell command that should be run.
--
-- Each line of the shell command is converted to an entry,
-- and is possible to preview with builtin previews.
--
-- In this example, we use ripgrep to search over your entire directory
-- live as you type.
local live_grepper = finders.new_job(function(prompt)
if not prompt or prompt == "" then
return nil
end
return { 'rg', "--vimgrep", prompt}
end)
-- Create and run the Picker.
--
-- NOTE: No sorter is needed to be passed.
-- Results will be returned in the order they are received.
pickers.new({
prompt = 'Live Grep',
finder = live_grepper,
previewer = previewers.vimgrep,
}):find()

View File

@@ -1,34 +0,0 @@
### 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>

View File

@@ -1,26 +0,0 @@
+-------------------------------------------------------------------+
| Picker:find()--------------------+ +------>Picker |
| | ^ | | |
| | | v | |
| | +----------------+ +----------------+ |
| +->| Finder + | Sorter | |
| +----------------+ +----------------+ |
| [1] |
| |
| |
| |
| |
| |
| |
+-------------------------------------------------------------------+
Picker starts a `finder`.
Finder returns a list of `entries` to Picker.
Picker can optionally sort w/ `Sorter`.
Picker can optionally preview selected with `Previewer`
Then you can map stuff in the picker to decide what to do next.

View File

@@ -1,55 +0,0 @@
local actions = require('telescope.actions')
local finders = require('telescope.finders')
local previewers = require('telescope.previewers')
local pickers = require('telescope.pickers')
local sorters = require('telescope.sorters')
local utils = require('telescope.utils')
local Job = require('plenary.job')
-- local live_grepper = finders.new {
-- fn_command = function(_, prompt)
-- -- TODO: Make it so that we can start searching on the first character.
-- if not prompt or prompt == "" then
-- return nil
-- end
-- return {
-- command = 'rg',
-- args = {"--vimgrep", prompt},
-- }
-- end
-- }
local f = function(prompt, process_result, process_complete)
local fzf = Job:new {
command = 'fzf';
writer = Job:new {
command = "fdfind",
args = nil,
cwd = "/home/tj/build/neovim",
enable_handlers = false,
},
-- Still doesn't work if you don't pass these args and just run `fzf`
args = {'--no-sort', '--filter', prompt};
}
local start = vim.fn.reltime()
print(vim.inspect(fzf:sync()), vim.fn.reltimestr(vim.fn.reltime(start)))
end
-- Process all the files
-- f("", nil, nil)
-- Filter on nvimexec
f("nvim/executor", nil, nil)
-- pickers.new({}, {
-- prompt = 'Live Grep',
-- finder = f,
-- previewer = previewers.vimgrep,
-- }):find()

View File

@@ -1,33 +0,0 @@
RELOAD('telescope')
RELOAD('plenary')
local finders = require('telescope.finders')
local make_entry = require('telescope.make_entry')
local pickers = require('telescope.pickers')
local sorters = require('telescope.sorters')
local Job = require('plenary.job')
pickers.new {
prompt = "Piped FZF",
finder = finders._new {
fn_command = function(_, prompt)
return {
command = 'fzf',
args = {'--no-sort', '--filter', prompt or ''},
writer = Job:new {
command = 'rg',
args = {'--files'},
cwd = '/home/tj/',
enable_handlers = false,
},
}
end,
entry_maker = make_entry.gen_from_file(),
sorter = sorters.get_fuzzy_file(),
},
}:find()

View File

@@ -1,11 +0,0 @@
echo "hello"
sleep 1
echo "help"
sleep 1
echo "hi"
sleep 1
echo "husband"
sleep 1
echo "helper"

View File

@@ -17,6 +17,9 @@ docs.test = function()
"./lua/telescope/themes.lua", "./lua/telescope/themes.lua",
"./lua/telescope/pickers/layout_strategies.lua", "./lua/telescope/pickers/layout_strategies.lua",
"./lua/telescope/config/resolve.lua", "./lua/telescope/config/resolve.lua",
"./lua/telescope/make_entry.lua",
"./lua/telescope/pickers/entry_display.lua",
"./lua/telescope/utils.lua",
"./lua/telescope/actions/init.lua", "./lua/telescope/actions/init.lua",
"./lua/telescope/actions/state.lua", "./lua/telescope/actions/state.lua",
"./lua/telescope/actions/set.lua", "./lua/telescope/actions/set.lua",