Sort is a sorting plugin for Neovim that provides intelligent sorting capabilities with support for both line-wise and delimiter-based sorting. This plugin automatically selects the most appropriate sorting strategy using a configurable priority system, making sorting efficient and intuitive.
:Sort
command covers most sorting scenarios without additional configuration.:sort
command functionality where applicable.{
'sQVe/sort.nvim',
config = function()
require('sort').setup({
-- Optional configuration overrides.
})
end,
}
Sort comes with the following defaults:
{
-- List of delimiters, in descending order of priority, to automatically
-- sort on.
delimiters = {
',',
'|',
';',
':',
's', -- Space.
't' -- Tab.
},
-- Enable natural sorting for motion operations by default.
-- When true, sorts "item1,item10,item2" as "item1,item2,item10".
-- When false, uses lexicographic sorting: "item1,item10,item2".
natural_sort = true,
-- Whitespace handling configuration.
whitespace = {
-- When whitespace before items is >= this many characters, it's considered
-- alignment and is preserved. Otherwise, whitespace is normalized to be
-- consistent when sorting changes item order.
alignment_threshold = 3,
},
-- Default keymappings (set to false to disable).
mappings = {
operator = 'go',
textobject = {
inner = 'io',
around = 'ao',
},
motion = {
next_delimiter = ']o',
prev_delimiter = '[o',
},
},
}
The :Sort
command adapts its behavior based on your selection:
When selecting multiple lines, all arguments are passed to Neovim's built-in :sort
command:
:[range]Sort[!] [flags]
See :help :sort
for complete documentation of flags and options.
When selecting within a single line, the plugin performs delimiter-based sorting:
:[range]Sort[!] [delimiter][flags]
Available flags:
!
- Reverse the sort order[delimiter]
- Manually specify delimiter (any punctuation, s
for space, t
for tab)b
- Sort by binary numbersi
- Ignore casen
- Sort by decimal numberso
- Sort by octal numbersu
- Keep only unique itemsx
- Sort by hexadecimal numbersz
- Natural sorting (handles numbers in strings properly)Sort provides Vim-style operators and text objects for efficient sorting:
Mapping | Mode | Description |
---|---|---|
go |
Normal | Sort operator (use with any motion) |
go |
Visual | Sort visual selection |
gogo |
Normal | Sort current line |
io |
Operator/Visual | Inner sortable region text object |
ao |
Operator/Visual | Around sortable region text object |
]o |
Normal/Visual/Operator | Jump to next delimiter |
[o |
Normal/Visual/Operator | Jump to previous delimiter |
All sorting operations support Vim's dot-repeat (.
) functionality, allowing you to easily repeat the last sort operation.
" Sort a word.
gow
" Sort inside parentheses.
go(
" Sort 3 lines down.
go3j
" Sort inside quotes using text object.
goio
" Sort around delimiters using text object.
goao
" Sort a paragraph.
gop
" Quick line sort.
gogo
By default, Sort uses natural sorting for motion operations, which handles numbers in strings more intuitively:
" With natural_sort = true (default):
" 'item1,item10,item2' becomes 'item1,item2,item10'
go$
" With natural_sort = false:
" 'item1,item10,item2' becomes 'item1,item10,item2' (lexicographic)
go$
To disable natural sorting for motions:
require('sort').setup({
natural_sort = false,
})
Note: The :Sort z
command still works independently of this setting for explicit natural sorting.
You can customize the default mappings:
require('sort').setup({
mappings = {
operator = 'gs',
textobject = {
inner = 'ii',
around = 'ai',
},
motion = {
next_delimiter = ']d',
prev_delimiter = '[d',
},
},
})
To disable mappings entirely:
require('sort').setup({
mappings = {
operator = false,
textobject = false,
motion = false,
},
})
Use the z
flag to enable natural sorting, which handles numbers in strings properly:
" Before: item1, item10, item2
" After: item1, item2, item10
:Sort z
Natural sorting also prioritizes punctuation over numeric continuations, making it ideal for programming content:
" Shell aliases
" Before: A1='{ print $1 }', A2='{ print $2 }', A='| awk'
" After: A='| awk', A1='{ print $1 }', A2='{ print $2 }'
" Function definitions
" Before: func1(), func10(), func()
" After: func(), func1(), func10()
" CSS selectors
" Before: .btn1, .btn:hover, .btn=active
" After: .btn:hover, .btn=active, .btn1
This enhancement ensures that identifiers with punctuation (like A=
, func()
) sort before identifiers with numeric suffixes (like A1
, func2
).
The plugin automatically normalizes whitespace in sorted content while preserving alignment when appropriate. The alignment_threshold
setting controls when whitespace is considered significant for alignment purposes.
When multiple delimiters are present, the plugin uses the configured priority order to determine which delimiter to sort by. This ensures consistent behavior across different text patterns.
All contributions are welcome! Whether it's bug reports, feature requests, or pull requests, your help makes Sort better for everyone.
Before contributing:
This project uses git hooks to ensure code quality and consistent formatting. To install the pre-commit hook:
./scripts/install-hooks
The pre-commit hook will automatically format:
stylua (for Lua files):
cargo install stylua
(recommended)brew install stylua
(macOS)shfmt (for shell scripts):
go install mvdan.cc/sh/v3/cmd/shfmt@latest
(recommended)brew install shfmt
(macOS)To run the test suite:
./scripts/test
Use the -v
or --verbose
flag for detailed output:
./scripts/test --verbose