Alternate between common files using pre-defined regexp. Just map the patterns and start navigating between files that are related.
Telescope alternate can create files when they are missing (including files with regexp at destination).
Now supports both Telescope and fzf-lua!
Packer:
use { "otavioschwanck/telescope-alternate" }
Lazy.nvim:
{
"otavioschwanck/telescope-alternate",
dependencies = { "nvim-telescope/telescope.nvim" }, -- or { "ibhagwan/fzf-lua" }
}
vim-plug:
Plug 'otavioschwanck/telescope-alternate'
-- Configuration using vim.g (recommended approach)
vim.g.telescope_alternate = {
mappings = {
{ 'app/services/(.*)_services/(.*).rb', { -- alternate from services to contracts / models
{ 'app/contracts/[1]_contracts/[2].rb', 'Contract' }, -- Adding label to switch
{ 'app/models/**/*[1].rb', 'Model', true }, -- Ignore create entry (with true)
} },
{ 'app/contracts/(.*)_contracts/(.*).rb', { { 'app/services/[1]_services/[2].rb', 'Service' } } }, -- from contracts to services
-- Search anything on helper folder that contains pluralize version of model.
--Example: app/models/user.rb -> app/helpers/foo/bar/my_users_helper.rb
{ 'app/models/(.*).rb', { { 'db/helpers/**/*[1:pluralize]*.rb', 'Helper' } } },
{ 'app/**/*.rb', { { 'spec/[1].rb', 'Test' } } }, -- Alternate between file and test
},
presets = { 'rails', 'rspec', 'nestjs', 'angular' }, -- Pre-defined mapping presets
picker = 'telescope', -- or 'fzf-lua'
open_only_one_with = 'current_pane', -- when just have only possible file, open it with. Can also be horizontal_split and vertical_split
transformers = { -- custom transformers
change_to_uppercase = function(w) return my_uppercase_method(w) end
},
telescope_mappings = { -- Change the telescope mappings
i = {
open_current = '<CR>',
open_horizontal = '<C-s>',
open_vertical = '<C-v>',
open_tab = '<C-t>',
},
n = {
open_current = '<CR>',
open_horizontal = '<C-s>',
open_vertical = '<C-v>',
open_tab = '<C-t>',
}
}
}
-- Alternative setup method (legacy, still supported)
require('telescope-alternate').setup({
mappings = {
{ 'app/services/(.*)_services/(.*).rb', { -- alternate from services to contracts / models
{ 'app/contracts/[1]_contracts/[2].rb', 'Contract' }, -- Adding label to switch
{ 'app/models/**/*[1].rb', 'Model', true }, -- Ignore create entry (with true)
} },
{ 'app/contracts/(.*)_contracts/(.*).rb', { { 'app/services/[1]_services/[2].rb', 'Service' } } }, -- from contracts to services
-- Search anything on helper folder that contains pluralize version of model.
--Example: app/models/user.rb -> app/helpers/foo/bar/my_users_helper.rb
{ 'app/models/(.*).rb', { { 'db/helpers/**/*[1:pluralize]*.rb', 'Helper' } } },
{ 'app/**/*.rb', { { 'spec/[1].rb', 'Test' } } }, -- Alternate between file and test
},
presets = { 'rails', 'rspec', 'nestjs', 'angular' }, -- Pre-defined mapping presets
picker = 'telescope', -- or 'fzf-lua'
open_only_one_with = 'current_pane', -- when just have only possible file, open it with. Can also be horizontal_split and vertical_split
transformers = { -- custom transformers
change_to_uppercase = function(w) return my_uppercase_method(w) end
},
telescope_mappings = { -- Change the telescope mappings
i = {
open_current = '<CR>',
open_horizontal = '<C-s>',
open_vertical = '<C-v>',
open_tab = '<C-t>',
},
n = {
open_current = '<CR>',
open_horizontal = '<C-s>',
open_vertical = '<C-v>',
open_tab = '<C-t>',
}
}
})
## Alternative Configuration Methods
### Using Telescope Setup (Legacy)
```lua
require('telescope').setup{
extensions = {
["telescope-alternate"] = {
mappings = {
-- your mappings here
},
presets = { 'rails', 'nestjs' },
picker = 'telescope' -- or 'fzf-lua'
},
},
}
mappings = {
{ pattern = 'app/services/(.*)_services/(.*).rb', targets = {
{ template = 'app/contracts/[1]_contracts/[2].rb', label = 'Contract', enable_new = true } -- enable_new can be a function too.
}
},
{ pattern = 'app/contracts/(.*)_contracts/(.*).rb', targets = {
{ template = 'app/services/[1]_services/[2].rb', label = 'Service', enable_new = true }
}
},
}
The plugin automatically loads the telescope extension when available. You can use:
:Telescope telescope-alternate alternate_file
Or use the provided command:
:TelescopeAlternate
Configure with fzf-lua picker:
vim.g.telescope_alternate = {
picker = 'fzf-lua',
mappings = {
-- your mappings here
}
}
Then run:
:lua require('telescope-alternate').alternate_file()
You can create convenient key mappings:
-- Using the provided command (recommended)
vim.keymap.set('n', '<leader>ta', ':TelescopeAlternate<CR>', { desc = 'Alternate file' })
-- Or using telescope directly
vim.keymap.set('n', '<leader>ta', ':Telescope telescope-alternate alternate_file<CR>', { desc = 'Alternate file' })
-- Or using lua function directly
vim.keymap.set('n', '<leader>ta', function() require('telescope-alternate').alternate_file() end, { desc = 'Alternate file' })
{ 'current-file-pattern', { { 'destination-pattern', 'label', ignoreCreate (true or false) } } }
current-file-pattern
can have multiple destinations(.*)
in the current file pattern is a capture group[1]
, [2]
, [3]
in the destination pattern refers to the corresponding capture groupWhen you're editing a file, the plugin will:
You can apply transformers to captured groups using the syntax: [1:function_name]
or [1:function1,function2]
Function Name | Description | Example |
---|---|---|
camel_to_kebap | userName -> user-name | [1:camel_to_kebap] |
kebap_to_camel | user-name -> userName | [1:kebap_to_camel] |
pluralize | userName -> userNames | [1:pluralize] |
singularize | userNames -> userName | [1:singularize] |
You can define custom transformers:
require('telescope-alternate').setup({
transformers = {
my_custom_transformer = function(text)
return text:upper()
end
}
})
{
'app/models/(.*).rb', {
{ 'db/helpers/**/*[1]*.rb', 'Helper' },
{ 'app/controllers/**/*[1:pluralize]_controller.rb', 'Controller' },
{ 'spec/models/[1]_spec.rb', 'Test' }
}
}
This mapping will:
app/models/user.rb
db/helpers/**/user*.rb
filesapp/controllers/**/users_controller.rb
spec/models/user_spec.rb
Option | Type | Default | Description |
---|---|---|---|
picker |
string | 'telescope' |
Choose between 'telescope' or 'fzf-lua' |
mappings |
table | {} |
File pattern mappings |
presets |
table | {} |
Pre-defined mapping presets |
open_only_one_with |
string | 'current_pane' |
How to open file when only one match. Options: 'current_pane' , 'horizontal_split' , 'vertical_split' , 'tab' |
transformers |
table | {} |
Custom transformer functions |
telescope_mappings |
table | {} |
Custom telescope key mappings |
The plugin comes with several presets for common project structures:
'rails'
- Ruby on Rails project mappings'rspec'
- RSpec test mappings 'nestjs'
- NestJS project mappings'angular'
- Angular project mappingsExample:
require('telescope-alternate').setup({
presets = { 'rails', 'rspec' }
})