Skip to content

Instantly share code, notes, and snippets.

@sorbits
Forked from mads-hartmann/align.rb
Created May 24, 2011 21:02
Show Gist options
  • Save sorbits/989679 to your computer and use it in GitHub Desktop.
Save sorbits/989679 to your computer and use it in GitHub Desktop.
align.rb
# Alignes the source
def align(text, regexp, width)
text.to_a.map do |line|
if offset = offsetOfRegexpInLine(line, regexp)
if shouldInsertBefore(line, regexp)
before = line[0..offset-1]
before + ' ' * (width - (before.length)) + line[offset..line.length-1]
else
before = line[0..offset]
before + ' ' * (width - (before.length-1)) + line[offset+1..line.length-1]
end
else
line
end
end.join
end
# Figures out if the spacing should be added before or after the match
def shouldInsertBefore(line, regexp)
offset = offsetOfRegexpInLine(line,regexp)
if line.chars.to_a[offset-1] =~ /\s/ then true else false end
end
# Finds the width of the line with the most text before the regexp.
def width(text, regexp)
text.split("\n").collect { |line| offsetOfRegexpInLine(line,regexp) }.max
end
# The offset of a regexp in a line of text. -1 if it doesn't match
def offsetOfRegexpInLine(line, regexp)
if match = regexp.match(line)
match.offset(match.size > 1 ? 1 : 0)[0]
else
-1
end
end
# Checks that the regexp matches every line
def hasMatchForAll(text, regexp)
text.to_a.select { |x| not x =~ /^\s*$/}.all? { |line| line =~ regexp }
end
# Checks if the first occurance of the regexp is at the same column in each line
def notAlignedIn(text,regexp)
not text.to_a.collect { |line| offsetOfRegexpInLine(line, regexp) }.reduce { |acc, x| x == acc }
end
# sorts and filters the regular expressions so the ones with the captures with the
# lowest offset comes first. The ones that aren't matched at all are filtered.
def prioritizeRegexps(text, regexps)
regexps.select{ |regexp|
hasMatchForAll(text, regexp) && notAlignedIn(text, regexp)
}.collect { |regexp| {
"min_offset" => text.split("\n").collect { |line| offsetOfRegexpInLine(line,regexp) }.min,
"regexp" => regexp
}}.sort { |dict1,dict2|
dict1['min_offset'] <=> dict2['min_offset']
}.select { |dict|
dict['min_offset'] > 0
}.collect { |dict|
dict['regexp']
}
end
=begin
Lets give it a try
=end
regexps = [ /(,)(?!$)/, /\}/, /<-/, /\s[-+\/*|]?(=)\s/, /\s(=>)\s/,/:/,/\/\// ]
text = DATA.read
prioritizeRegexps(text, regexps).each { |regexp|
text = align(text, regexp, width(text, regexp))
}
puts text
__END__
{ capitalizeWord, flag::insert },
{ changeCaseOfLetter, flag::insert },
{ changeCaseOfWord, flag::insert },
{ complete, flag::insert|flag::unselect },
{ deleteBackward, flag::erase },
{ deleteBackwardByDecomposingPreviousCharacter, flag::insert },
{ deleteForward, flag::erase },
{ deleteSubWordBackward, flag::erase },
{ deleteSubWordForward, flag::erase },
{ deleteToBeginningOfLine, flag::erase },
{ deleteToBeginningOfParagraph, flag::erase },
{ deleteToEndOfLine, flag::erase },
{ deleteToEndOfParagraph, flag::erase },
{ deleteToMark, flag::mark },
{ deleteWordBackward, flag::erase },
{ deleteWordForward, flag::erase },
{ indent, flag::insert },
{ insertBacktab, flag::insert|flag::unselect },
{ insertNewline, flag::insert|flag::unselect },
{ insertNewlineIgnoringFieldEditor, flag::insert|flag::unselect },
{ insertTab, flag::insert|flag::unselect },
{ insertTabIgnoringFieldEditor, flag::insert|flag::unselect },
{ moveBackward, flag::simple_movement },
{ moveDown, flag::require_continuous_selection|flag::simple_movement },
{ moveDownAndModifySelection, flag::require_continuous_selection },
{ moveForward, flag::simple_movement },
{ moveParagraphBackwardAndModifySelection, flag::require_continuous_selection },
{ moveParagraphForwardAndModifySelection, flag::require_continuous_selection },
{ moveToBeginningOfColumn, flag::require_continuous_selection },
{ moveToBeginningOfColumnAndModifySelection, flag::require_continuous_selection },
{ moveToBeginningOfDocument, flag::require_continuous_selection },
{ moveToBeginningOfDocumentAndModifySelection, flag::require_continuous_selection },
{ moveToBeginningOfParagraph, flag::require_continuous_selection },
{ moveToEndOfColumn, flag::require_continuous_selection },
{ moveToEndOfColumnAndModifySelection, flag::require_continuous_selection },
{ moveToEndOfDocument, flag::require_continuous_selection },
{ moveToEndOfDocumentAndModifySelection, flag::require_continuous_selection },
{ moveToEndOfParagraph, flag::require_continuous_selection },
{ moveUp, flag::require_continuous_selection|flag::simple_movement },
{ moveUpAndModifySelection, flag::require_continuous_selection },
{ moveWordBackward, flag::simple_movement },
{ moveWordForward, flag::simple_movement },
{ nextCompletion, flag::insert|flag::unselect },
{ pageDown, flag::require_continuous_selection },
{ pageDownAndModifySelection, flag::require_continuous_selection },
{ pageUp, flag::require_continuous_selection },
{ pageUpAndModifySelection, flag::require_continuous_selection },
{ previousCompletion, flag::insert|flag::unselect },
{ reformatText, flag::insert },
{ reformatTextAndJustify, flag::insert },
{ selectToMark, flag::mark },
{ shiftLeft, flag::insert },
{ shiftRight, flag::insert },
{ swapWithMark, flag::mark },
{ transpose, flag::insert },
{ unwrapText, flag::insert },
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment