rufo 0.0.24 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd6cf27bd7b2fb2451482dff10c6fe5a3930311e
4
- data.tar.gz: 7a4eebf1d5df0dc1ae9e05f9a04030cef866cdf2
3
+ metadata.gz: 200fb638506091280a985b092c7f56d51cc78ee6
4
+ data.tar.gz: fa2aa0c202892a85c4683b5fe50c39f7fdc9f440
5
5
  SHA512:
6
- metadata.gz: bd58dc896ab51bc57c5901fd5d1b46f29784d8f934de72176e21723bf542889520dc1a03f741ca14d2eddf618bbf66522ef758bd4612c1276937d533855d7ced
7
- data.tar.gz: a0e7d72efa0b67fc29bb893eac4be54dfdd3dfb9b90700aaef306e34de7303c947f86c3116cad7b0a3c06357a8eaf4ee786954cb6862e83d2998e429f0c3187c
6
+ metadata.gz: 461fd9e0fc701a914e1c5d8a8174f913ed1b1cb7c2d820d8b451c584558058b3bcd249e8cb8cd7dc0d2ecade21111cbdf4ac63e5246daf71374a860c32699331
7
+ data.tar.gz: 4ec02ecd32126046a380e6fff1a521605013b585320cbadc76f909aacbbed6af2c56cdbf20a289519d7c6be3d462bb14b3188b2d7688d2b74f9478a319120f07
data/README.md CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  **Ru**by **fo**rmatter
6
6
 
7
+ ## Why
8
+
9
+ Rufo's primary use case is as a text-editor plugin, to autoformat files on save or
10
+ on demand. For this reason it needs to be fast. If the formatter is slow, saving
11
+ a file becomes painful.
12
+
13
+ Right now, Rufo can format it's [formatter](https://github.com/asterite/rufo/blob/master/lib/rufo/formatter.rb),
14
+ a 3000+ lines file, in about 290ms. It can format a ~500 lines file in 180ms. Since most files
15
+ have less than 500 lines, the time is acceptable.
16
+
17
+ There's at least one other good Ruby formatter I know: [RuboCop](https://github.com/bbatsov/rubocop).
18
+ However, it takes between 2 and 5 seconds to format a 3000+ lines file, and about 1 second to format
19
+ a 500 lines file. A second is too much delay for a plugin editor. Additionally, RuboCop is much more
20
+ than just a code formatter. Rufo is and will always be a code formatter.
21
+
7
22
  ## Installation
8
23
 
9
24
  Add this line to your application's Gemfile:
@@ -47,6 +62,12 @@ according to **rufo**, and will exit with exit code 1.
47
62
 
48
63
  - Sublime Text: [sublime-rufo](https://github.com/asterite/sublime-rufo)
49
64
 
65
+ Did you write a plugin for your favorite editor? That's great! Let me know about it and
66
+ I will list it here.
67
+
68
+ Right now it would be great to have [Vim](http://www.vim.org/),
69
+ [Atom](https://atom.io/) and [Emacs](https://www.gnu.org/software/emacs/) plugins :-)
70
+
50
71
  ## Configuration
51
72
 
52
73
  Rufo follows most of the conventions found in this [Ruby style guide](https://github.com/bbatsov/ruby-style-guide). It does a bit more than that, and it can also be configured a bit.
@@ -214,7 +214,7 @@ class Rufo::Formatter
214
214
  end
215
215
  when :string_content
216
216
  # [:string_content, exp]
217
- visit_exps node[1..-1], false, false
217
+ visit_exps node[1..-1], with_lines: false
218
218
  when :string_embexpr
219
219
  # String interpolation piece ( #{exp} )
220
220
  visit_string_interpolation node
@@ -425,8 +425,8 @@ class Rufo::Formatter
425
425
  end
426
426
  end
427
427
 
428
- def visit_exps(exps, with_indent = false, with_lines = true)
429
- consume_end_of_line(true)
428
+ def visit_exps(exps, with_indent: false, with_lines: true)
429
+ consume_end_of_line(at_prefix: true)
430
430
 
431
431
  line_before_endline = nil
432
432
 
@@ -459,7 +459,7 @@ class Rufo::Formatter
459
459
  if with_lines
460
460
  exp_needs_two_lines = needs_two_lines?(exp)
461
461
 
462
- consume_end_of_line(false, !is_last, !is_last, exp_needs_two_lines)
462
+ consume_end_of_line(want_semicolon: !is_last, want_multiline: !is_last, needs_two_lines_on_comment: exp_needs_two_lines)
463
463
 
464
464
  # Make sure to put two lines before defs, class and others
465
465
  if !is_last && (exp_needs_two_lines || needs_two_lines?(exps[i + 1])) && @line <= line_before_endline + 1
@@ -514,7 +514,7 @@ class Rufo::Formatter
514
514
  def visit_string_literal_end(node)
515
515
  inner = node[1]
516
516
  inner = inner[1..-1] unless node[0] == :xstring_literal
517
- visit_exps(inner, false, false)
517
+ visit_exps(inner, with_lines: false)
518
518
 
519
519
  case current_token_kind
520
520
  when :on_heredoc_end
@@ -560,7 +560,7 @@ class Rufo::Formatter
560
560
  # [:string_embexpr, exps]
561
561
  consume_token :on_embexpr_beg
562
562
  skip_space_or_newline
563
- visit_exps node[1], false, false
563
+ visit_exps(node[1], with_lines: false)
564
564
  skip_space_or_newline
565
565
  consume_token :on_embexpr_end
566
566
  end
@@ -587,7 +587,7 @@ class Rufo::Formatter
587
587
  #
588
588
  # [:symbol, [:@ident, "foo", [1, 1]]]
589
589
  consume_token :on_symbeg
590
- visit_exps node[1..-1], false, false
590
+ visit_exps node[1..-1], with_lines: false
591
591
  end
592
592
 
593
593
  def visit_quoted_symbol_literal(node)
@@ -603,7 +603,7 @@ class Rufo::Formatter
603
603
  consume_token :on_label_end
604
604
  else
605
605
  consume_token :on_symbeg
606
- visit_exps exps, false, false
606
+ visit_exps exps, with_lines: false
607
607
  consume_token :on_tstring_end
608
608
  end
609
609
  end
@@ -633,7 +633,7 @@ class Rufo::Formatter
633
633
  line = @line
634
634
 
635
635
  visit target
636
- consume_space(!@align_assignments)
636
+ consume_space(want_preserve_whitespace: !@align_assignments)
637
637
  track_assignment
638
638
  consume_op "="
639
639
  visit_assign_value value
@@ -650,7 +650,7 @@ class Rufo::Formatter
650
650
  line = @line
651
651
 
652
652
  visit target
653
- consume_space(!@align_assignments)
653
+ consume_space(want_preserve_whitespace: !@align_assignments)
654
654
 
655
655
  # [:@op, "+=", [1, 2]],
656
656
  check :on_op
@@ -678,7 +678,7 @@ class Rufo::Formatter
678
678
  # A trailing comma can come after the left hand side
679
679
  consume_token :on_comma if comma?
680
680
 
681
- consume_space(!@align_assignments)
681
+ consume_space(want_preserve_whitespace: !@align_assignments)
682
682
  track_assignment
683
683
  consume_op "="
684
684
  visit_assign_value right
@@ -688,7 +688,7 @@ class Rufo::Formatter
688
688
  first_space = current_token if space?
689
689
  skip_space
690
690
 
691
- indent_after_space value, indentable_value?(value), true, first_space
691
+ indent_after_space value, sticky: indentable_value?(value), want_space: true, first_space: first_space
692
692
  end
693
693
 
694
694
  def indentable_value?(value)
@@ -748,7 +748,7 @@ class Rufo::Formatter
748
748
  _, cond, then_body, else_body = node
749
749
 
750
750
  visit cond
751
- consume_space(true)
751
+ consume_space(want_preserve_whitespace: true)
752
752
  consume_op "?"
753
753
 
754
754
  first_space = current_token if space?
@@ -764,7 +764,7 @@ class Rufo::Formatter
764
764
  end
765
765
 
766
766
  visit then_body
767
- consume_space(true)
767
+ consume_space(want_preserve_whitespace: true)
768
768
  consume_op ":"
769
769
 
770
770
  first_space = current_token if space?
@@ -796,9 +796,9 @@ class Rufo::Formatter
796
796
 
797
797
  visit body
798
798
 
799
- consume_space(true)
799
+ consume_space(want_preserve_whitespace: true)
800
800
  consume_keyword(suffix)
801
- consume_space(true)
801
+ consume_space(want_preserve_whitespace: true)
802
802
  visit cond
803
803
  end
804
804
 
@@ -967,6 +967,16 @@ class Rufo::Formatter
967
967
  end
968
968
 
969
969
  def flush_heredocs
970
+ if comment?
971
+ write_space unless @output[-1] == " "
972
+ write current_token_value.rstrip
973
+ next_token
974
+ write_line
975
+ if @heredocs.last[1]
976
+ write_indent(next_indent)
977
+ end
978
+ end
979
+
970
980
  printed = false
971
981
 
972
982
  until @heredocs.empty?
@@ -1038,7 +1048,7 @@ class Rufo::Formatter
1038
1048
  if args[0].is_a?(Symbol)
1039
1049
  visit args
1040
1050
  else
1041
- visit_exps args, false, false
1051
+ visit_exps args, with_lines: false
1042
1052
  end
1043
1053
  end
1044
1054
  end
@@ -1075,7 +1085,7 @@ class Rufo::Formatter
1075
1085
  consume_block_args args
1076
1086
 
1077
1087
  consume_space
1078
- visit_exps body, false, false
1088
+ visit_exps body, with_lines: false
1079
1089
  consume_space
1080
1090
 
1081
1091
  consume_token :on_rbrace
@@ -1138,7 +1148,7 @@ class Rufo::Formatter
1138
1148
  end
1139
1149
 
1140
1150
  consume_token :on_op
1141
- found_semicolon = skip_space_or_newline(true, true)
1151
+ found_semicolon = skip_space_or_newline(_want_semicolon: true, write_first_semicolon: true)
1142
1152
 
1143
1153
  if found_semicolon
1144
1154
  # Nothing
@@ -1276,7 +1286,7 @@ class Rufo::Formatter
1276
1286
  if node[0].is_a?(Symbol)
1277
1287
  visit node
1278
1288
  else
1279
- visit_exps node, false, false
1289
+ visit_exps node, with_lines: false
1280
1290
  end
1281
1291
  end
1282
1292
 
@@ -1389,7 +1399,7 @@ class Rufo::Formatter
1389
1399
  if current_token[0][0] == closing_brace_token[0][0]
1390
1400
  consume_token :on_lbrace
1391
1401
  consume_space
1392
- visit_exps body, false, false
1402
+ visit_exps body, with_lines: false
1393
1403
  consume_space
1394
1404
  consume_token :on_rbrace
1395
1405
  else
@@ -1440,7 +1450,7 @@ class Rufo::Formatter
1440
1450
 
1441
1451
  if newline? || comment?
1442
1452
  indent(base_column || @indent) do
1443
- consume_end_of_line(false, false, false)
1453
+ consume_end_of_line(want_multiline: false)
1444
1454
  write_indent
1445
1455
  end
1446
1456
  elsif first_space && @preserve_whitespace
@@ -1480,7 +1490,7 @@ class Rufo::Formatter
1480
1490
  consume_op_or_keyword op
1481
1491
 
1482
1492
  if op == :not
1483
- consume_space(true)
1493
+ consume_space(want_preserve_whitespace: true)
1484
1494
  else
1485
1495
  skip_space_or_newline
1486
1496
  end
@@ -1512,7 +1522,7 @@ class Rufo::Formatter
1512
1522
  end
1513
1523
 
1514
1524
  consume_op_or_keyword op
1515
- indent_after_space right, false, needs_space
1525
+ indent_after_space right, want_space: needs_space
1516
1526
  end
1517
1527
 
1518
1528
  def consume_op_or_keyword(op)
@@ -1685,7 +1695,7 @@ class Rufo::Formatter
1685
1695
  if node[1][0].is_a?(Symbol)
1686
1696
  visit node[1]
1687
1697
  else
1688
- visit_exps node[1], false, false
1698
+ visit_exps node[1], with_lines: false
1689
1699
  end
1690
1700
 
1691
1701
  skip_space_or_newline
@@ -1914,7 +1924,7 @@ class Rufo::Formatter
1914
1924
  if elements
1915
1925
  # [:assoclist_from_args, elements]
1916
1926
  push_hash(node) do
1917
- visit_literal_elements(elements[1], true)
1927
+ visit_literal_elements(elements[1], inside_hash: true)
1918
1928
  end
1919
1929
  else
1920
1930
  skip_space_or_newline
@@ -1938,7 +1948,7 @@ class Rufo::Formatter
1938
1948
 
1939
1949
  visit key
1940
1950
 
1941
- consume_space(!@align_hash_keys)
1951
+ consume_space(want_preserve_whitespace: !@align_hash_keys)
1942
1952
 
1943
1953
  track_hash_key
1944
1954
 
@@ -1946,7 +1956,7 @@ class Rufo::Formatter
1946
1956
  # or `"label": value`
1947
1957
  if symbol || !(key[0] == :@label || key[0] == :dyna_symbol)
1948
1958
  consume_op "=>"
1949
- consume_space(!@align_hash_keys)
1959
+ consume_space(want_preserve_whitespace: !@align_hash_keys)
1950
1960
  end
1951
1961
 
1952
1962
  visit value
@@ -1980,7 +1990,7 @@ class Rufo::Formatter
1980
1990
  write current_token_value
1981
1991
  next_token
1982
1992
 
1983
- visit_exps pieces, false, false
1993
+ visit_exps pieces, with_lines: false
1984
1994
 
1985
1995
  check :on_regexp_end
1986
1996
  write current_token_value
@@ -2132,7 +2142,7 @@ class Rufo::Formatter
2132
2142
  if node[1][0].is_a?(Symbol)
2133
2143
  visit node[1]
2134
2144
  else
2135
- visit_exps node[1], false, false
2145
+ visit_exps node[1], with_lines: false
2136
2146
  end
2137
2147
  end
2138
2148
  end
@@ -2177,7 +2187,7 @@ class Rufo::Formatter
2177
2187
  consume_token :on_tlambeg
2178
2188
 
2179
2189
  consume_space
2180
- visit_exps body, false, false
2190
+ visit_exps body, with_lines: false
2181
2191
  consume_space
2182
2192
 
2183
2193
  consume_token :on_rbrace
@@ -2267,7 +2277,7 @@ class Rufo::Formatter
2267
2277
  visit_comma_separated_list exps
2268
2278
  end
2269
2279
 
2270
- def visit_literal_elements(elements, inside_hash = false)
2280
+ def visit_literal_elements(elements, inside_hash: false)
2271
2281
  base_column = @column
2272
2282
  needs_final_space = inside_hash && space?
2273
2283
  skip_space
@@ -2298,20 +2308,35 @@ class Rufo::Formatter
2298
2308
  needed_indent = base_column
2299
2309
  end
2300
2310
 
2311
+ wrote_comma = false
2312
+
2301
2313
  elements.each_with_index do |elem, i|
2314
+ is_last = last?(i, elements)
2315
+ wrote_comma = false
2316
+
2302
2317
  if needs_trailing_comma
2303
2318
  indent(needed_indent) { visit elem }
2304
2319
  else
2305
2320
  visit elem
2306
2321
  end
2307
- skip_space
2322
+
2323
+ # We have to be careful not to aumatically write a heredoc on next_token,
2324
+ # because we miss the chance to write a comma to separate elements
2325
+ skip_space_no_heredoc_check
2326
+ wrote_comma = check_heredocs_in_literal_elements(is_last, needs_trailing_comma, wrote_comma)
2308
2327
 
2309
2328
  next unless comma?
2310
- is_last = last?(i, elements)
2311
2329
 
2312
- write "," unless is_last
2313
- next_token
2314
- skip_space
2330
+ unless is_last
2331
+ write ","
2332
+ wrote_comma = true
2333
+ end
2334
+
2335
+ # We have to be careful not to aumatically write a heredoc on next_token,
2336
+ # because we miss the chance to write a comma to separate elements
2337
+ next_token_no_heredoc_check
2338
+ skip_space_no_heredoc_check
2339
+ wrote_comma = check_heredocs_in_literal_elements(is_last, needs_trailing_comma, wrote_comma)
2315
2340
 
2316
2341
  if newline? || comment?
2317
2342
  if is_last
@@ -2326,7 +2351,8 @@ class Rufo::Formatter
2326
2351
  end
2327
2352
 
2328
2353
  if needs_trailing_comma
2329
- write ","
2354
+ write "," unless wrote_comma
2355
+
2330
2356
  consume_end_of_line
2331
2357
  write_indent
2332
2358
  elsif comment?
@@ -2340,6 +2366,18 @@ class Rufo::Formatter
2340
2366
  end
2341
2367
  end
2342
2368
 
2369
+ def check_heredocs_in_literal_elements(is_last, needs_trailing_comma, wrote_comma)
2370
+ if (newline? || comment?) && !@heredocs.empty?
2371
+ if !is_last || needs_trailing_comma
2372
+ write "," unless wrote_comma
2373
+ wrote_comma = true
2374
+ end
2375
+
2376
+ flush_heredocs
2377
+ end
2378
+ wrote_comma
2379
+ end
2380
+
2343
2381
  def visit_if(node)
2344
2382
  visit_if_or_unless node, "if"
2345
2383
  end
@@ -2348,7 +2386,7 @@ class Rufo::Formatter
2348
2386
  visit_if_or_unless node, "unless"
2349
2387
  end
2350
2388
 
2351
- def visit_if_or_unless(node, keyword, check_end = true)
2389
+ def visit_if_or_unless(node, keyword, check_end: true)
2352
2390
  # if cond
2353
2391
  # then_body
2354
2392
  # else
@@ -2378,7 +2416,7 @@ class Rufo::Formatter
2378
2416
  consume_keyword "else"
2379
2417
  indent_body else_body[1]
2380
2418
  when :elsif
2381
- visit_if_or_unless else_body, "elsif", false
2419
+ visit_if_or_unless else_body, "elsif", check_end: false
2382
2420
  else
2383
2421
  bug "expected else or elsif, not #{else_body[0]}"
2384
2422
  end
@@ -2444,7 +2482,7 @@ class Rufo::Formatter
2444
2482
  else
2445
2483
  write " do "
2446
2484
  end
2447
- visit_exps body, false, false
2485
+ visit_exps body, with_lines: false
2448
2486
  skip_space_or_newline
2449
2487
  write_space if is_do
2450
2488
  end
@@ -2544,7 +2582,7 @@ class Rufo::Formatter
2544
2582
  end
2545
2583
  end
2546
2584
 
2547
- def consume_space(want_preserve_whitespace = false)
2585
+ def consume_space(want_preserve_whitespace: false)
2548
2586
  first_space = current_token if space?
2549
2587
  skip_space
2550
2588
  if want_preserve_whitespace && @preserve_whitespace && !newline? && !comment? && first_space
@@ -2560,6 +2598,12 @@ class Rufo::Formatter
2560
2598
  next_token while space?
2561
2599
  end
2562
2600
 
2601
+ def skip_space_no_heredoc_check
2602
+ while space?
2603
+ next_token_no_heredoc_check
2604
+ end
2605
+ end
2606
+
2563
2607
  def skip_space_backslash
2564
2608
  return [false, false] unless space?
2565
2609
 
@@ -2572,7 +2616,7 @@ class Rufo::Formatter
2572
2616
  [has_slash_newline, first_space]
2573
2617
  end
2574
2618
 
2575
- def skip_space_or_newline(_want_semicolon = false, write_first_semicolon = false)
2619
+ def skip_space_or_newline(_want_semicolon: false, write_first_semicolon: false)
2576
2620
  found_newline = false
2577
2621
  found_comment = false
2578
2622
  found_semicolon = false
@@ -2668,7 +2712,7 @@ class Rufo::Formatter
2668
2712
  # - at_prefix: are we at a point before an expression? (if so, we don't need a space before the first comment)
2669
2713
  # - want_semicolon: do we want do print a semicolon to separate expressions?
2670
2714
  # - want_multiline: do we want multiple lines to appear, or at most one?
2671
- def consume_end_of_line(at_prefix = false, want_semicolon = false, want_multiline = true, needs_two_lines_on_comment = false)
2715
+ def consume_end_of_line(at_prefix: false, want_semicolon: false, want_multiline: true, needs_two_lines_on_comment: false)
2672
2716
  found_newline = false # Did we find any newline during this method?
2673
2717
  last = nil # Last token kind found
2674
2718
  multilple_lines = false # Did we pass through more than one newline?
@@ -2819,7 +2863,7 @@ class Rufo::Formatter
2819
2863
 
2820
2864
  def indent_body(exps)
2821
2865
  indent do
2822
- consume_end_of_line(false, false, false)
2866
+ consume_end_of_line(want_multiline: false)
2823
2867
  end
2824
2868
 
2825
2869
  # A then keyword can appear after a newline after an `if`, `unless`, etc.
@@ -2836,7 +2880,7 @@ class Rufo::Formatter
2836
2880
  skip_space_or_newline
2837
2881
  else
2838
2882
  indent do
2839
- visit_exps exps, true
2883
+ visit_exps exps, with_indent: true
2840
2884
  end
2841
2885
  write_line unless @last_was_newline
2842
2886
  end
@@ -2876,7 +2920,7 @@ class Rufo::Formatter
2876
2920
  @last_was_newline = false
2877
2921
  end
2878
2922
 
2879
- def indent_after_space(node, sticky = false, want_space = true, first_space = nil)
2923
+ def indent_after_space(node, sticky: false, want_space: true, first_space: nil)
2880
2924
  first_space = current_token if space?
2881
2925
 
2882
2926
  skip_space
@@ -3000,11 +3044,15 @@ class Rufo::Formatter
3000
3044
  def next_token
3001
3045
  @tokens.pop
3002
3046
 
3003
- if newline? && !@heredocs.empty?
3047
+ if (newline? || comment?) && !@heredocs.empty?
3004
3048
  flush_heredocs
3005
3049
  end
3006
3050
  end
3007
3051
 
3052
+ def next_token_no_heredoc_check
3053
+ @tokens.pop
3054
+ end
3055
+
3008
3056
  def last?(i, array)
3009
3057
  i == array.size - 1
3010
3058
  end
data/lib/rufo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rufo
2
- VERSION = "0.0.24"
2
+ VERSION = "0.0.25"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.24
4
+ version: 0.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ary Borenszweig