Skip to content

Commit 6976209

Browse files
committed
refactor: simplify opener logic
1 parent 074bbd6 commit 6976209

File tree

2 files changed

+12
-12
lines changed

2 files changed

+12
-12
lines changed

ARCHITECTURE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ These finders are hard-coded in the Command-T source code as functions.
1818

1919
In the following discussion, note that there are a few sets of confusing, overlapping, or overloading terms that would make a good target for refactoring:
2020

21-
- "open", "on_open", "opener": used at various layers of abstraction for configuration key names, callbacks, parameters, and so on.
21+
- "open", "on_open": used at various layers of abstraction for configuration key names, callbacks, parameters, and so on.
2222
- "config" vs "options": used to describe user-supplied settings, defaults, and also function-level parameters.
2323

2424
## List-based finder life-cycle
@@ -39,7 +39,7 @@ In the following discussion, note that there are a few sets of confusing, overla
3939
1. It looks up the finder config under the `name` key (`'buffer'`, for example) of the user's settings (obtained via a call to `commandt.options()`, which returns a _copy_ of the user's settings, or falls back to the defaults if there are no explicit user settings).
4040
2. If the config defines an `options` callback, it calls the callback with the existing options so that it has an opportunity to transform those options, and then sanitizes them. This is used by several finders to force the display of dotfiles (ie. by unconditionally setting `always_show_dot_files` to `true`, and `never_show_dot_files` to `false`); specifically, the `'buffer'`, `'help'`, `'history'`, `'jump'`, `'line'`, `'search'`, and `'tag'` finders.
4141
3. If the config defines an `on_directory` callback, it calls the callback with the directory to give it the opportunity to transform the directory. This is used by finders which change their root directory based on the `commandt.traverse` setting; if no directory is provided, and the user settings require it, the callback will attempt to infer an appropriate directory, using the current working directory as a fallback. Finders which use `on_directory` include `'fd'`, `'find'`, `'git'`, and `'rg'`.
42-
4. It prepares an `open` callback with signature `open(item, ex_command)` and assigns it back to the `options` object that will be passed into the `finders.list` or `finders.command` implementation, and also into `ui.show()`. This `open` callback will in turn forward to the `open` implementation specified in the config, if provided, otherwise falling back to `commandt.open(item, ex_command)` which is otherwise known as `sbuffer(buffer, command)` (it's called "smart" because it tries to intelligently pick the right place to open the requested buffer). Finders which specify a custom `'open'` in their config include `'fd'`, `'find'`, `'git'`, and `'rg'`; which all pass in an `on_open(item, ex_command, directory, _options, opener, _context)` implementation which uses the `opener` to open a relativized path (ie. `opener(relativize(directory, item), ex_command)`); note that the `opener` here is actually `commandt.open` (ie. `sbuffer()`). In contrast, the `'help'`, `'history'`, `'line'`, `'search'`, and `'tag'` finders define totally custom open callbacks. Finally, the `'buffer'` and `'jump'` finders define nothing, which means they use the fallback.
42+
4. It prepares an `open` callback with signature `open(item, ex_command)` and assigns it back to the `options` object that will be passed into the `finders.list` or `finders.command` implementation, and also into `ui.show()`. This `open` callback will in turn forward to the `open` implementation specified in the config, if provided, otherwise falling back to `commandt.open(item, ex_command)` which is otherwise known as `sbuffer(buffer, command)` (it's called "smart" because it tries to intelligently pick the right place to open the requested buffer). Finders which specify a custom `'open'` in their config include `'fd'`, `'find'`, `'git'`, and `'rg'`; which all pass in an `on_open(item, ex_command, directory, _options, _context)` implementation which uses `sbuffer()` to open a relativized path (ie. `sbuffer(relativize(directory, item), ex_command)`). In contrast, the `'help'`, `'history'`, `'line'`, `'search'`, and `'tag'` finders define totally custom open callbacks. Finally, the `'buffer'` and `'jump'` finders define nothing, which means they use the fallback.
4343
5. If the finder config provides a `candidates` field, it obtains the actual list finder and context by passing in the `directory`, `config.candidates`, and `options`. Otherwise, it must contain a `command` field and it obtains a command finder passing in `directory`, `config.command`, `options`, and `name` (the `name` is used to look up finder-specific settings in the `options`).
4444
6. If the finder config provides a `fallback` field set to `true`, it adds the fallback finder to the `finder` object, passing in the original `finder`, `directory`, and `options` (this fallback finder is a lazy wrapper around the built-in file finder, which gets invoked if the primary finder fails.
4545
7. It invokes `ui.show()`, passing in the `finder` and `options`, merging in three additional settings: `name`, `mode` (`mode` is `'virtual'`, `'file'` or `nil`), and an `on_close` callback set to `config.on_close`. Finders which actually specify an `on_close` are `'fd'`, `'find'`, `'rg'`, and the built-in file finders; they all use `popd` for this purpose, to reset to the original working directory in case the user specified a temporary directory as an argument to those finders (the watchman finder doesn't need this as it does not change into a temporary directory even when the user specifies a directory argument).
@@ -49,7 +49,7 @@ In the following discussion, note that there are a few sets of confusing, overla
4949
1. `Prompt.new()` captures various settings, including `on_open` and `mappings`. It creates a window with `Window.new()` and `self._window:show()`, and sets up mappings inside that window with `self._window:map()`. When the user chooses to open a selection via a mapping, the prompt will call the `on_open` callback with either `'edit'`, `'split'`, `'tabedit'`, or `'vsplit'` as an argument.
5050
8. The `on_open` callback, which is actually `ui.open(ex_command)` (`ex_command` is `'edit'`, `'split'` etc), calls `close()`, which closes the windows and invokes any `on_close` callback.
5151
9. If the UI has an `on_open` callback, it calls it so that it can transform the result. Only the built-in file finder and the watchman finder use this, and they both use it to relativize the result in relation to the `directory`.
52-
10. The thing that actually opens the result is called with `vim.defer_fn()`, to give autocommands a chance to run. The called function is `current_finder.open(result, ex_command)`. Recall from the above that finders like `'fd'` pass in an `options.open` that relativizes the path and uses the `opener` (`commandt.open()`) to do a "smart open". Finders like the `'help'` finder define a custom callback. Finders like `'buffer'` and `'jump'` define no `on_open`, so use the default.
52+
10. The thing that actually opens the result is called with `vim.defer_fn()`, to give autocommands a chance to run. The called function is `current_finder.open(result, ex_command)`. Recall from the above that finders like `'fd'` pass in an `options.open` that relativizes the path and uses `sbuffer()` to do a "smart open". Finders like the `'help'` finder define a custom callback. Finders like `'buffer'` and `'jump'` define no `on_open`, so use the default.
5353

5454
## Command-based finder life-cycle
5555

lua/wincent/commandt/init.lua

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ end
7878
-- Common `on_open` implementation used by several "command" finders that equips
7979
-- them to deal with automatic directory changes caused by the `traverse`
8080
-- setting.
81-
local function on_open(item, ex_command, directory, _options, opener, _context)
82-
opener(relativize(directory, item), ex_command)
81+
local function on_open(item, ex_command, directory, _options, _context)
82+
sbuffer(relativize(directory, item), ex_command)
8383
end
8484

8585
local help_opened = false
@@ -432,7 +432,7 @@ local default_options = {
432432
return commands
433433
end,
434434
mode = 'virtual',
435-
open = function(item, _ex_command, _directory, _options, _opener, _context)
435+
open = function(item, _ex_command, _directory, _options, _context)
436436
vim.api.nvim_feedkeys(':' .. item, 'nt', true)
437437
end,
438438
options = force_dot_files,
@@ -517,7 +517,7 @@ local default_options = {
517517
return helptags
518518
end,
519519
mode = 'virtual',
520-
open = function(item, ex_command, _directory, _options, _opener, _context)
520+
open = function(item, ex_command, _directory, _options, _context)
521521
local command = 'help'
522522
if ex_command == 'split' then
523523
-- Split is the default, so for this finder, we abuse "split" mode to do
@@ -557,7 +557,7 @@ local default_options = {
557557
return commands
558558
end,
559559
mode = 'virtual',
560-
open = function(item, _ex_command, _directory, _options, _opener, _context)
560+
open = function(item, _ex_command, _directory, _options, _context)
561561
vim.api.nvim_feedkeys(':' .. item, 'nt', true)
562562
end,
563563
options = force_dot_files,
@@ -625,7 +625,7 @@ local default_options = {
625625
return result
626626
end,
627627
mode = 'virtual',
628-
open = function(item, _ex_command, _directory, _options, _opener, _context)
628+
open = function(item, _ex_command, _directory, _options, _context)
629629
-- Extract line number from (eg) "some line contents:100".
630630
local suffix = string.find(item, '%d+$')
631631
local index = tonumber(item:sub(suffix))
@@ -659,7 +659,7 @@ local default_options = {
659659
return commands
660660
end,
661661
mode = 'virtual',
662-
open = function(item, _ex_command, _directory, _options, _opener, _context)
662+
open = function(item, _ex_command, _directory, _options, _context)
663663
vim.api.nvim_feedkeys('/' .. item, 'nt', true)
664664
end,
665665
options = force_dot_files,
@@ -685,9 +685,9 @@ local default_options = {
685685
return result, candidates
686686
end,
687687
mode = 'virtual',
688-
open = function(item, ex_command, _directory, options, opener, context)
688+
open = function(item, ex_command, _directory, options, context)
689689
local tag = context[item]
690-
opener(tag.filename, ex_command)
690+
sbuffer(tag.filename, ex_command)
691691

692692
-- Strip leading and trailing slashes, and use \M ('nomagic'):
693693
-- ie. "/^int main()$/" → "\M^int main()$"

0 commit comments

Comments
 (0)