├── .gitignore
├── License.md
├── README.md
├── autoload
└── sort_motion.vim
├── doc
└── sort_motion.txt
└── plugin
└── sort_motion.vim
/.gitignore:
--------------------------------------------------------------------------------
1 | tags
2 |
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Chris Toomey
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Sort Motion.vim
2 | ===============
3 |
4 | This plugin provides the ability to sort in Vim using text objects and
5 | motions. Sorting lines and argument lists manually can be a hassle, and thus
6 | most write it off as a waste of effort, but when its as easy as anything else
7 | in Vim, it becomes a viable option.
8 |
9 | `sort-motion` has three different sorting modes:
10 |
11 | - Linewise: sort a sequence of lines (require statements, gem lists, etc)
12 | - Character: sort a comma separated list (argument lists, attribute lists, etc)
13 | - Visual (linewise or normal): provided for continuity, similar to linewise
14 | - Block Visual: By default behaves the same as the other visual modes.
15 | Optionally, you can provide a specific sort command which you might use to
16 | sort by a column (example: `Vissort`)
17 |
18 | Installation
19 | ------------
20 |
21 | Using [Vundle][]:
22 |
23 | ``` vim
24 | " add this line to your ~/.vimrc
25 | Bundle 'christoomey/vim-sort-motion'
26 | ```
27 |
28 | then run `:BundleInstall` from within Vim.
29 |
30 | [Vundle]: https://github.com/gmarik/Vundle.vim
31 |
32 | Usage
33 | -----
34 |
35 | ### Linewise
36 |
37 | The primary interface to this plugin is via the `gs` mapping, for sorting
38 | based on a text object or motion. To use the mapping, type `gs` followed by a
39 | motion, ie `2j` to sort down two lines.
40 |
41 | Examples:
42 |
43 | - `gs2j` => Sort down two lines (current + 2 below)
44 | - `gsip` => Sort the current paragraph
45 | - `gsii` => Sort the current indentation level (requires [text-obj-indent plugin][])
46 |
47 | [text-obj-indent plugin]: https://github.com/kana/vim-textobj-indent
48 |
49 | ### Character
50 |
51 | In addition, if the text object is within a line then `sort-motion` will
52 | attempt to sort the text as a comma separated list.
53 |
54 | Examples:
55 |
56 | `gsi(` => Sort within parenthesis. `(b, c, a)` would become `(a, b, c)`
57 |
58 | ### Visual
59 |
60 | For continuity, `sort-motion` also defines a visual mode mapping for `gs`.
61 | This behaves as a linewise sort over the lines defined by the visual selection.
62 |
63 | You can also (optionally) specify a blockwise command to use for block
64 | selections (example: `Vissort`).
65 |
66 | Configuration
67 | -------------
68 |
69 | ### sort_motion_flags
70 |
71 | If you'd like to pass any options to `sort`
72 | you can set `g:sort_motion_flags`. For example you could use:
73 |
74 | ```vim
75 | let g:sort_motion_flags = 'ui'
76 | ```
77 |
78 | To make all sorts case insensitive and remove duplicates.
79 |
80 | *Note*: this only applies to linewise sorting (including visual), but does
81 | not apply to the character based sorting of comma separated lists.
82 |
83 | ### sort_motion_visual_block_command
84 |
85 | If you'd like to specify a specific command to use for blockwise selections you
86 | can set it here. This is useful if for example you want to use `Vissort` so that
87 | you can sort by a column.
88 |
89 | ```vim
90 | let g:sort_motion_visual_block_command = 'Vissort'
91 | ```
92 |
93 | By default the command used is `sort`.
94 |
95 | NOTE: To use `Vissort` you will need to install this plugin.
96 |
--------------------------------------------------------------------------------
/autoload/sort_motion.vim:
--------------------------------------------------------------------------------
1 | " autoload/sort_motion.vim
2 |
3 | if exists('g:autoloaded_sort_motion')
4 | finish
5 | endif
6 | let g:autoloaded_sort_motion = 1
7 |
8 | let s:sort_motion_flags = get(g:, 'sort_motion_flags', '')
9 |
10 | function! sort_motion#sort_motion(mode) abort
11 | let l:sort_motion_visual_block_command =
12 | \ get(g:,'sort_motion_visual_block_command', 'sort')
13 |
14 | if a:mode == 'line'
15 | execute "'[,']sort " . s:sort_motion_flags
16 | elseif a:mode == 'char'
17 | execute "normal! `[v`]y"
18 | let startpos = match(@@, '\v\i')
19 | let parts = split(@@, '\v\i+')
20 | if startpos > 0
21 | let prefix = parts[0]
22 | let delimiter = parts[1]
23 | let suffix = parts[-1]
24 | else
25 | let prefix = ''
26 | let delimiter = parts[0]
27 | let suffix = ''
28 | endif
29 | if prefix == delimiter
30 | let prefix = ''
31 | endif
32 | if suffix == delimiter
33 | let suffix = ''
34 | endif
35 | let sortstart = strlen(prefix)
36 | let sortend = strlen(@@) - sortstart - strlen(suffix)
37 | let sortables = strpart(@@, sortstart, sortend)
38 | let sorted = join(sort(split(sortables, '\V' . escape(delimiter, '\'))), delimiter)
39 | execute "normal! v`]c" . prefix . sorted . suffix
40 | execute "normal! `["
41 | elseif a:mode == 'V'
42 | execute "'<,'>sort " . s:sort_motion_flags
43 | elseif a:mode ==# ''
44 | execute "'<,'>".l:sort_motion_visual_block_command.' '.s:sort_motion_flags
45 | endif
46 | endfunction
47 |
48 | function! sort_motion#sort_lines() abort
49 | let beginning = line('.')
50 | let end = v:count1 + beginning - 1
51 | execute beginning . ',' . end . 'sort ' . s:sort_motion_flags
52 | endfunction
53 |
--------------------------------------------------------------------------------
/doc/sort_motion.txt:
--------------------------------------------------------------------------------
1 | *sort_motion.txt* Sort using text objects and motions.
2 |
3 | ==============================================================================
4 | Descriptions and default values:~
5 |
6 | *'g:sort_motion'*
7 | Mapping for text object sorting: >
8 | let g:sort_motion = 'gs'
9 | <
10 |
11 | *'g:sort_motion_lines'*
12 | Mapping for linewise sorting: >
13 | let g:sort_motion_lines = 'gss'
14 | <
15 |
16 | *'g:sort_motion_visual'*
17 | Mapping for sorting in |Visual| mode: >
18 | let g:sort_motion_visual = 'gs'
19 | <
20 | ==============================================================================
21 |
--------------------------------------------------------------------------------
/plugin/sort_motion.vim:
--------------------------------------------------------------------------------
1 | " sort-motion.vim - Sort based on linewise motions
2 | " Maintainer: Chris Toomey
3 | " Version: 0.1
4 | " Source: http://github.com/christoomey/vim-sort-motion
5 |
6 | if exists('g:loaded_sort_motion') || &cp || v:version < 700
7 | finish
8 | endif
9 | let g:loaded_sort_motion = 1
10 |
11 | nnoremap SortMotion
12 | \ :set opfunc=sort_motion#sort_motiong@
13 | xnoremap SortMotionVisual
14 | \ :call sort_motion#sort_motion(visualmode())
15 | nnoremap SortLines
16 | \ :call sort_motion#sort_lines()
17 |
18 | if !hasmapto('SortMotion', 'n') && maparg('gs', 'n') ==# ''
19 | nmap gs SortMotion
20 | endif
21 | if !hasmapto('SortMotionVisual', 'x') && maparg('gs', 'x') ==# ''
22 | xmap gs SortMotionVisual
23 | endif
24 | if !hasmapto('SortLines', 'n') && maparg('gss', 'n') ==# ''
25 | nmap gss SortLines
26 | endif
27 |
--------------------------------------------------------------------------------