Created
February 6, 2025 15:20
-
-
Save dmlogv/10a4ba185aeac50ad52963072c3fe120 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sublime, sublime_plugin | |
""" Format text as table | |
""" | |
class AlignerCommand(sublime_plugin.TextCommand): | |
""" Split text by delimeter and format as table with limited width | |
@param 'limit': int - Max width of table, default is 80 | |
@param 'splitter': str - Custom delimeter, default is ', ' | |
@param 'after': bool - Delimeter position, default is False (before) | |
@param 'expand': int - Additional space between text and delimeter, default 1 | |
@param 'align': str - Text align in cell, default is left | |
Example: view.run_command('aligner', {'limit':10, 'splitter':','}) | |
""" | |
def run(self, edit, **kwargs): | |
# Default argument values | |
limit = kwargs.get('limit') or 80 # Table width limit | |
splitter = kwargs.get('splitter') or ', ' # Column delimeter | |
after = kwargs.get('after') or False # Delimeter position | |
expand = kwargs.get('expand') or 1 # Additional space in cell | |
align = kwargs.get('align') or 'left' # Text alignment | |
# Parameters value check | |
if limit < 0: | |
raise ValueError('Limit value must be greater or equal 0') | |
if not (type(splitter) == str or type(splitter) == unicode): | |
raise TypeError('Splitter must be a string') | |
if not type(after) == bool: | |
raise TypeError('After must be a boolean') | |
if expand < 0: | |
raise ValueError('Expand value must be greater or equal 0') | |
if align not in ['left', 'right']: | |
raise ValueError("Align value must be 'left' or 'right'") | |
# Get selected text or select all | |
region = self.view.sel()[0] or sublime.Region(0, self.view.size()) | |
selection = self.view.substr(region) | |
# Split text by delimeter, exclude empty strings, trim spaces | |
parts = [ | |
item.strip() for item | |
in filter(None, selection.split(splitter.strip() or ' ')) | |
] | |
# Max cell length plus additional space | |
max_len = max([len(item) for item in parts]) + expand | |
# Number of cell in row or 1 if limit too short | |
per_line = max(limit // (max_len + len(splitter)), 1) | |
rows = [] | |
# Loop cells by number of cells in row | |
for current_item in range(0, len(parts), per_line): | |
rows.append( | |
# Join cells in to row | |
(splitter).join( | |
[ | |
# Align text in cell with spaces | |
{ | |
'left': item.ljust(max_len), | |
'right': item.rjust(max_len) | |
}[align] for item | |
in parts[current_item : current_item + per_line] | |
] | |
) | |
) | |
# Replace region with output rows | |
row_splitter = { | |
True: splitter + '\r\n', | |
False: '\r\n' + splitter | |
}.get(after) | |
first_shift = { | |
True: '', | |
False: ' ' * len(splitter) | |
}.get(after) | |
self.view.replace(edit, region, first_shift + (row_splitter).join(rows)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment