-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add basic line length based formatting support #66
Merged
gingermusketeer
merged 45 commits into
new-formatter
from
add-basic-line-length-based-formatting-support
Jan 26, 2018
Merged
Changes from 30 commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
6470ebf
Add line length restrained printing utilities
gingermusketeer a794fbb
Fix tests for older versions of ruby
gingermusketeer d4558e1
Add more complex example and fix indent printing
gingermusketeer ca3a59a
Add initial prettier printing integration
gingermusketeer fbe2c42
Add doc mode helpers
gingermusketeer 94ddb11
Return token from consume_token
gingermusketeer 6b2895b
Allow print_width to be configured
gingermusketeer 656636f
Fix more tests
gingermusketeer 85e6165
Fix test for comment on first element
gingermusketeer 8867e8b
Fix remaining trailing comma tests
gingermusketeer fdd6242
Fix simple method call spec
gingermusketeer a93cd49
Fix percent array literal test
gingermusketeer 903e72a
Fix simple array specs
gingermusketeer df24550
Add support for star args
gingermusketeer 6c90829
Fix more complex tests
gingermusketeer 46cc5fd
Fix hash test
gingermusketeer 8b015d6
Only use new args_add_star logic in doc mode
gingermusketeer 130bc96
Fix comment on a newline after an array item
gingermusketeer 4e52126
Handle strings in doc mode
gingermusketeer befd18d
Change specs to match new formatting
gingermusketeer 5d50eb6
Fix nested array issue
gingermusketeer 2d7b873
Add printer example for heredoc
gingermusketeer 68113ea
Remove unneeded code
gingermusketeer de073df
Cleanup
gingermusketeer 53e5eee
Address PR feedback
gingermusketeer d5bed76
Add example of nested array with brackets
gingermusketeer 8fbe3ba
Merge branch 'master' into add-basic-line-length-based-formatting-sup…
gingermusketeer b57d338
Fix parens spec
gingermusketeer c607c78
Switch from CODE to RUBY for heredocs
gingermusketeer 7944964
Cleanup unused code
gingermusketeer 84f5f0a
Fix printing heredocs in printer
gingermusketeer 5f97fdd
Fix heredoc handling for doc printer
gingermusketeer e71def6
Add new test cases and fix them
gingermusketeer 711bfd5
Refactor to handle non doc handled nodes generically
gingermusketeer 7fed281
Fix print_width config calculation
gingermusketeer e25138d
Format codebase
gingermusketeer 8cc334d
Remove usage of squiggly heredocs
gingermusketeer ba42b5c
Add test for indentation issue
gingermusketeer c8ce87f
Merge branch 'master' into add-basic-line-length-based-formatting-sup…
gingermusketeer 46ea2f4
Refactor literal elements method
gingermusketeer 99901fd
Remove unneeded code
gingermusketeer 660e797
Refactor comment handling
gingermusketeer 7ff6caf
Code style tweaks
gingermusketeer c7028c2
Fix array literal bug
gingermusketeer 4835c73
Handle percent array nested inside normal array
gingermusketeer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
module Rufo | ||
class DocBuilder | ||
class InvalidDocError < StandardError; end | ||
|
||
class << self | ||
|
||
# Combine an array of items into a single string. | ||
def concat(parts) | ||
assert_docs(parts) | ||
{ | ||
type: :concat, parts: parts, | ||
} | ||
end | ||
|
||
# Increase level of indentation. | ||
def indent(contents) | ||
assert_doc(contents) | ||
{ | ||
type: :indent, contents: contents, | ||
} | ||
end | ||
|
||
# Increase indentation by a fixed number. | ||
def align(n, contents) | ||
assert_doc(contents) | ||
{type: :align, contents: contents, n: n} | ||
end | ||
|
||
# Groups are items that the printer should try and fit onto a single line. | ||
# If the group does not fit then it breaks instead. | ||
def group(contents, opts = {}) | ||
assert_doc(contents) | ||
{ | ||
type: :group, | ||
contents: contents, | ||
break: !!opts[:should_break], | ||
expanded_states: opts[:expanded_states], | ||
} | ||
end | ||
|
||
# Rather than breaking if the items do not fit this tries a different set | ||
# of items. | ||
def conditional_group(states, opts = {}) | ||
group(states.first, opts.merge(expanded_states: states)) | ||
end | ||
|
||
# Alternative to group. This only breaks the required items rather then | ||
# all items if they do not fit. | ||
def fill(parts) | ||
assert_docs(parts) | ||
|
||
{type: :fill, parts: parts} | ||
end | ||
|
||
# Print first arg if the group breaks otherwise print the second. | ||
def if_break(break_contents, flat_contents) | ||
assert_doc(break_contents) unless break_contents.nil? | ||
assert_doc(flat_contents) unless flat_contents.nil? | ||
|
||
{type: :if_break, break_contents: break_contents, flat_contents: flat_contents} | ||
end | ||
|
||
# Append content to the end of a line. This gets placed just before a new line. | ||
def line_suffix(contents) | ||
assert_doc(contents) | ||
{type: :line_suffix, contents: contents} | ||
end | ||
|
||
# Join list of items with a separator. | ||
def join(sep, arr) | ||
result = [] | ||
arr.each_with_index do |element, index| | ||
unless index == 0 | ||
result << sep | ||
end | ||
result << element | ||
end | ||
concat(result) | ||
end | ||
|
||
def add_alignment_to_doc(doc, size, tab_width) | ||
return doc unless size > 0 | ||
(size/tab_width).times { doc = indent(doc) } | ||
doc = align(size % tab_width, doc) | ||
align(-Float::INFINITY, doc) | ||
end | ||
|
||
private | ||
|
||
def assert_docs(parts) | ||
parts.each(&method(:assert_doc)) | ||
end | ||
|
||
def assert_doc(val) | ||
unless val.is_a?(String) || (val.is_a?(Hash) && val[:type].is_a?(Symbol)) | ||
raise InvalidDocError.new("Value #{val.inspect} is not a valid document") | ||
end | ||
end | ||
end | ||
|
||
# Use this to ensure that line suffixes do not move to the last line in group. | ||
LINE_SUFFIX_BOUNDARY = {type: :line_suffix_boundary} | ||
# Use this to force the parent to break | ||
BREAK_PARENT = {type: :break_parent} | ||
# If the content fits on one line the newline will be replaced with a space. | ||
# Newlines are what triggers indentation to be added. | ||
LINE = {type: :line} | ||
# If the content fits on one line the newline will be replaced by nothing. | ||
SOFT_LINE = {type: :line, soft: true} | ||
# This newline is always included regardless of if the content fits on one | ||
# line or not. | ||
HARD_LINE = concat([{type: :line, hard: true}, BREAK_PARENT]) | ||
# This is a newline that is always included and does not cause the | ||
# indentation to change subsequently. | ||
LITERAL_LINE = concat([ | ||
{type: :line, hard: true, literal: true}, | ||
BREAK_PARENT, | ||
]) | ||
|
||
# This keeps track of the cursor in the document. | ||
CURSOR = {type: :cursor, placeholder: :cursor} | ||
end | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constants at the bottom seems a little odd to me? Especially as they are referenced publically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a little odd but the reason is that some of the constants utilize the methods defined further up. I thought that it might be best to keep them all together. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that makes sense. I think this is fine then.