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.
- Delimiter-aware sorting: Automatically detects and sorts by delimiters like commas, pipes, colons, and more.
- Intelligent strategy selection: Uses a configurable priority list to choose the best sorting approach.
- Natural sorting support: Handles strings with numbers naturally (e.g., "item1", "item2", "item10").
- Minimal user input: The
:Sort
command covers most sorting scenarios without additional configuration. - Vim-compatible: Mirrors Neovim's built-in
:sort
command functionality where applicable. - Motion-based operations: Provides text objects and motions for efficient sorting workflows.
- Whitespace preservation: Intelligently handles and normalizes whitespace in sorted content.
{
'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:
- Follow the existing code style and formatting conventions
- Install the formatters (stylua and shfmt) for consistent formatting
- Write clear commit messages describing your changes
- Add tests for new functionality when applicable
- Run tests before submitting pull requests
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)- Download from stylua releases
shfmt (for shell scripts):
go install mvdan.cc/sh/v3/cmd/shfmt@latest
(recommended)brew install shfmt
(macOS)- Download from shfmt releases
To run the test suite:
./scripts/test
Use the -v
or --verbose
flag for detailed output:
./scripts/test --verbose
- Delimiter sorting: Support for multiple delimiter types with priority-based selection
- Numerical sorting: Support for binary, decimal, octal, and hexadecimal number sorting
- Motion mappings: Vim-style operators and text objects for efficient sorting
- Natural sorting: Intuitive sorting of strings containing numbers
- Whitespace handling: Intelligent whitespace preservation and normalization
- Comprehensive testing: Full test coverage for stability and reliability