Skip to content

Commit 567f12f

Browse files
committed
ColumnSort 2.0
Version 2.0 adds settings and with this the possibility to either specify a column-separation character or let ColumnSort auto-detect the separation character. The user can also specify to skip the column header and the sorting order.
1 parent f02f0e6 commit 567f12f

5 files changed

Lines changed: 135 additions & 13 deletions

File tree

ColumnSort.py

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
# Plugin: ColumnSort
22
# Author: Matthias M. Schneider
3-
# Verison: 1.0
4-
# Copyright: None - Published under the GPL
3+
# Verison: 2.0
4+
# Copyright: IDC (I Don't Care) - Published under the GPL
55
# Purpose: Sort lines by detecting columns separated by a tab character.
66
# The user can then choose the column to be used as sort key from a quick panel.
77
# The plugin uses two commands as the handler of the pick panel has no access to the edit token,
88
# so a second command is called with parameters to sort and replace the text.
99
import sublime, sublime_plugin
1010

11+
AUTO_FIELD_SEPARATORS = "\t,;:|/#"
1112

1213
class ColumnSortCommand(sublime_plugin.TextCommand):
1314
"""
1415
Command: column_sort
1516
"""
16-
def run(self, edit, rows_cols, col_num):
17+
def run(self, edit, rows_cols, col_num, field_separator, skip_header, ascending):
18+
# Check if the first line of the selection should be skipped
19+
starting_row = 1 if skip_header is True else 0
1720
# Sort the array of arrays with columns using a lambda function (see the Python Sort How-to)
18-
rows_cols.sort(key=lambda col:col[col_num])
19-
# Produce the text for replacement by using a generator and according join function calls. Mind the trailing new-line character
20-
sorded = "\n".join(["\t".join(row) for row in rows_cols]) + "\n"
21+
rows_cols_head = rows_cols[0:starting_row]
22+
rows_cols_tail = rows_cols[starting_row:]
23+
rows_cols_tail.sort(key=lambda col:col[col_num], reverse=ascending)
24+
rows_cols = rows_cols_head + rows_cols_tail
25+
# Produce the text for replacement by using a generator and according join function calls. Mind the trailling new-line character.
26+
sorded = "\n".join([field_separator.join(row) for row in rows_cols]) + "\n"
2127
# Now replace the selected text
2228
self.view.replace(edit, self.view.sel()[0], sorded)
2329

@@ -26,19 +32,48 @@ class ColumnPickCommand(sublime_plugin.TextCommand):
2632
"""
2733
Command: column_pick
2834
"""
29-
3035
rows_cols = None
36+
field_separator = None
37+
skip_header = None
38+
ascending = None
3139

3240
def run(self, edit):
3341
# Get the selected text and split it in lines using a Sublime function
3442
text_lines = self.view.substr(self.view.sel()[0]).splitlines()
35-
# Use a generator with the split function to get an array of arrays containing lines with its columns
36-
self.rows_cols = [line.split('\t') for line in text_lines]
43+
# Return early if there is no selection
44+
if text_lines is None or len(text_lines) == 0: return
45+
46+
# Load the settings afresh for each run
47+
settings = sublime.load_settings("ColumnSort.sublime-settings")
3748

49+
# Set up the instance variables
50+
self.field_separator = settings.get('columnsort_field_separator')
51+
self.skip_header = settings.get('columnsort_skip_header')
52+
self.ascending = {'ascending': False, 'descending': True}[settings.get('columnsort_sort_direction')]
53+
54+
# Check the field separator setting and try to find one if the setting is "auto"
55+
if self.field_separator == "auto":
56+
self.field_separator = None
57+
for fs in AUTO_FIELD_SEPARATORS:
58+
if len(text_lines[0].split(fs)) > 1:
59+
self.field_separator = fs
60+
break
61+
62+
# Return if no field separator could be detected, so sorting will not be promoted
63+
if self.field_separator is None: return
64+
65+
# Use a generator with the split function to get an array of arrays containing lines with its columns
66+
self.rows_cols = [line.split(self.field_separator) for line in text_lines]
3867
# Show a quick panel containing the values of the columns of the first line
3968
self.view.window().show_quick_panel(self.rows_cols[0], self.column_selected)
4069

4170
def column_selected(self, col_num):
4271
# If the user didn't abort the action actually run the column_sort command
4372
if col_num >= 0:
44-
self.view.run_command('column_sort', {'rows_cols':self.rows_cols, 'col_num':col_num})
73+
self.view.run_command('column_sort', {
74+
'rows_cols':self.rows_cols,
75+
'col_num':col_num,
76+
'field_separator': self.field_separator,
77+
'skip_header': self.skip_header,
78+
'ascending': self.ascending
79+
})

ColumnSort.sublime-settings

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
/*
3+
Field separation character, or "auto" if ColumnSort should try to detect columns separated by
4+
one of the following characters:
5+
● Tabulator (\t)
6+
● Comma (,)
7+
● Semicolon (;)
8+
● Colon (:)
9+
● Vertical Bar (|)
10+
● Forward Slash (/)
11+
● Hash (#)
12+
13+
NOTE 1: The order of the field separation characters listed here is also defining their priority in
14+
which they will be detected and processed. As a consequence, a file which contains more than
15+
one field separation character will be split into columns by the first occurrence of those
16+
characters in top to bottom order.
17+
NOTE 2: Currently "string escaping" using single or double quotes is not supported by the splitting
18+
method used. It is therefore highly recommended to stick with tab-separation for a hasslefree
19+
and reliable operation.
20+
*/
21+
"columnsort_field_separator": "auto",
22+
23+
/*
24+
ColumnSort cannot predict if the selected text contains a header line or not. Set this property to
25+
either true or false to indicate if you want to force a default.
26+
If the property is set to true the first row of the selection will be only used for column heading
27+
display purposes and left alone during sorting which will then begin with the second line of the
28+
selection.
29+
*/
30+
"columnsort_skip_header": true,
31+
32+
/*
33+
The sorting can be defined to be "ascending" or "descending" by default.
34+
*/
35+
"columnsort_sort_direction": "ascending"
36+
}

Default.sublime-commands

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
[
2+
{
3+
"caption": "Preferences: ColumnSort – Default",
4+
"command": "open_file",
5+
"args": {
6+
"file": "${packages}/ColumnSort/ColumnSort.sublime-settings",
7+
}
8+
},
29
{
310
"caption": "Preferences: ColumnSort Key Bindings – Default",
411
"command": "open_file",
@@ -23,6 +30,13 @@
2330
"platform": "Linux"
2431
}
2532
},
33+
{
34+
"caption": "Preferences: ColumnSort – User",
35+
"command": "open_file",
36+
"args": {
37+
"file": "${packages}/User/ColumnSort.sublime-settings",
38+
}
39+
},
2640
{
2741
"caption": "Preferences: ColumnSort Key Bindings – User",
2842
"command": "open_file",

Main.sublime-menu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"caption": "ColumnSort",
2222
"children":
2323
[
24+
{ "command": "open_file", "args": { "file": "${packages}/ColumnSort/ColumnSort.sublime-settings", }, "caption": "Settings – Default" },
25+
{ "command": "open_file", "args": { "file": "${packages}/User/ColumnSort.sublime-settings", }, "caption": "Settings – User" },
2426
{ "command": "open_file", "args": { "file": "${packages}/ColumnSort/Default (Windows).sublime-keymap", "platform": "Windows" }, "caption": "Key Bindings – Default" },
2527
{ "command": "open_file", "args": { "file": "${packages}/ColumnSort/Default (OSX).sublime-keymap", "platform": "OSX" }, "caption": "Key Bindings – Default" },
2628
{ "command": "open_file", "args": { "file": "${packages}/ColumnSort/Default (Linux).sublime-keymap", "platform": "Linux" }, "caption": "Key Bindings – Default" },

README.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,50 @@
11
# ColumnSort
22
ColumnSort is a plugin package for Sublime Text version 3 which provides a simple means of sorting tab-separated text by column.
33
## Limitations
4-
* ColumnSort currently only works with tabular text which has its columns separated with a tab character ('\t' or '\x09').
5-
* Currently only ascending sorting is available.
4+
* ColumnSort allows to either specify the column (field) separation character, or let ColumnSort try to auto-detect the separator via the settings.
5+
* Either ascending or descending sorting is available via the settings.
66

77
## Usage
88
1. Install the package either
99
* by copyping the package to Sublime's package folder using the menu entry <kbd>Browse Packages…</kbd>, or
1010
* by using the very convenient [Package Control](https://packagecontrol.io) plugin and choosing the <kbd>Install Package</kbd> command from the command palette.
11-
2. Open a file with tab-separated content, or produce or paste suchlike text in a buffer.
11+
2. Open a file with column-separated content, or produce or paste suchlike text in a buffer.
1212
3. Select the lines you want to include to be sorted.
1313
4. Press <kbd>Cmd Ctrl X</kbd> on the Mac, <kbd>Ctrl Meta X</kbd> on Linux or <kbd>Ctrl Alt X</kbd> on Windows. This will produce a popup window which displays the content of the first row as separate entries to choose from. The idea behind this is that often the first row contains header descriptions which makes identifying the data in the columns much easier.
1414
5. Select an entry in the popup window with the up and down arrow keys and press <kbd>Return</kbd> or <kbd>Enter</kbd>, or click on an entry with the mouse.
1515
6. The selected text will be **replaced** with the sorted text.
16+
17+
## Settings
18+
The settings file currently has the following options to tinkle with:
19+
20+
### <kbd>columnsort\_field\_separator</kbd> (default: <kbd>"auto"</kbd>)
21+
22+
Field separation character, or "auto" if ColumnSort should try to detect columns separated by
23+
one of the following characters:
24+
* Tabulator (\t)
25+
* Comma (,)
26+
* Semicolon (;)
27+
* Colon (:)
28+
* Vertical Bar (|)
29+
* Forward Slash (/)
30+
* Hash (#)
31+
32+
NOTE 1: The order of the field separation characters listed here is also defining their priority in
33+
which they will be detected and processed. As a consequence, a file which contains more than
34+
one field separation character will be split into columns by the first occurrence of those
35+
characters in top to bottom order.
36+
37+
NOTE 2: Currently "string escaping" using single or double quotes is not supported by the splitting
38+
method used. It is therefore highly recommended to stick with tab-separation for a hasslefree
39+
and reliable operation.
40+
41+
### <kbd>columnsort\_skip\_header</kbd> (default: <kbd>true</kbd>)
42+
ColumnSort cannot predict if the selected text contains a header line or not. Set this property to
43+
either true or false to indicate if you want to force a default.
44+
45+
If the property is set to true the first row of the selection will be only used for column heading
46+
display purposes and left alone during sorting which will then begin with the second line of the
47+
selection.
48+
49+
### <kbd>columnsort\_sort\_direction</kbd> (default: <kbd>"ascending"</kbd>)
50+
The sorting can be defined to be <kbd>"ascending"</kbd> or <kbd>"descending"</kbd> by default.

0 commit comments

Comments
 (0)