Last active
February 27, 2018 04:25
-
-
Save symmetriq/a3b1965405d413878516782c3aac8983 to your computer and use it in GitHub Desktop.
BBEdit: Tidy Values
This file contains 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
#!/usr/bin/env ruby | |
#------------------------------------------------------------------------------- | |
# Tidy Values | |
#------------------------------------------------------------------------------- | |
# Jason Sims <[email protected]> | |
#------------------------------------------------------------------------------- | |
# | |
# Aligns a series of `key: value` or `var = value` lines | |
# | |
# - Language agnostic | |
# - Supports quoted keys (' or ") if lines are key: value pairs | |
# - Supports `||=` | |
# - Supports mixed `||=` and `=`; the `=` will be aligned | |
# - Supports leading commas | |
# - Preserves indentation | |
# - Unlike many BBEdit filters, this doesn't strip the trailing newline, so you | |
# can quickly select entire lines by clicking and dragging in the line number | |
# column on the left. | |
# | |
#------------------------------------------------------------------------------- | |
# | |
# Usage: | |
# Select multiple lines of text that contain `key: value` or `var = value`, then | |
# apply this via keyboard shortcut or Text → Apply Text Filter → Tidy Values. | |
# | |
# CAUTION: | |
# This removes lines that don't contain either of the above expressions. | |
# | |
#------------------------------------------------------------------------------- | |
# | |
# Installation in BBEdit: | |
# | |
# 1. Place this file in your "Text Filters" directory: | |
# ~/Library/Application Support/BBEdit/Text Filters/ | |
# or | |
# ~/Dropbox/Application Support/BBEdit/Text Filters/ | |
# | |
# 2. Optionally assign a keyboard shortcut to "Tidy Values" in: | |
# BBEdit → Preferences → Menus & Shortcuts → Text → Apply Text Filter | |
# | |
#------------------------------------------------------------------------------- | |
# More scripts & snippets here: | |
# https://gist.github.com/symmetriq | |
#------------------------------------------------------------------------------- | |
input = ARGF.set_encoding('UTF-8').read | |
# here's an example of what this script does: | |
indent = '' | |
leading_comma = '' | |
operators = {} | |
longest_operator = 0 | |
keys = [] | |
values = [] | |
input.split("\n").each_with_index do |line, i| | |
matches = /^( *)(, *)?(?:('[^']+'|"[^"]+"|[^ :]+) *(:)|([^ =]+) *((?:\|\|)?=)) *(.*)$/.match line | |
next if matches.nil? | |
# capture indent for each line in case the selection uses leading commas and | |
# the first line has no comma (this could be more efficient by only capturing | |
# the indent of the last line, but then we'd also need to make sure the last | |
# line isn't empty) | |
indent = matches[1] if matches[1] | |
leading_comma = matches[2] if matches[2] && leading_comma.empty? | |
key = matches[3] || matches[5] | |
keys.push key | |
operator = matches[4] || matches[6] | |
operators[key] = operator | |
longest_operator = [operator.length, longest_operator].max | |
values.push matches[7] | |
end | |
longest_key = keys.max_by(&:length).length | |
output = [] | |
keys.zip(values).each do |key, value| | |
operator = operators[key] | |
prefix = output.length == 0 ? ' ' * leading_comma.length : leading_comma | |
output.push "#{indent}#{prefix}#{key.ljust(longest_key)} #{operator.rjust(longest_operator)} #{value}" | |
end | |
print output.join("\n") | |
print "\n" if input[-1] == "\n" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment