brakeman 6.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +68 -0
  3. data/README.md +5 -2
  4. data/bundle/load.rb +15 -14
  5. data/bundle/ruby/3.1.0/gems/csv-3.3.2/LICENSE.txt +33 -0
  6. data/bundle/ruby/3.1.0/gems/csv-3.3.2/NEWS.md +965 -0
  7. data/bundle/ruby/3.1.0/gems/csv-3.3.2/README.md +55 -0
  8. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/core_ext/array.rb +9 -0
  9. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/core_ext/string.rb +9 -0
  10. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/fields_converter.rb +96 -0
  11. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/input_record_separator.rb +18 -0
  12. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/parser.rb +1292 -0
  13. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/row.rb +757 -0
  14. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/table.rb +1055 -0
  15. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/version.rb +6 -0
  16. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv/writer.rb +209 -0
  17. data/bundle/ruby/3.1.0/gems/csv-3.3.2/lib/csv.rb +3017 -0
  18. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/Changelog.md +28 -0
  19. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/Gemfile +1 -0
  20. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/README.md +40 -1
  21. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/highline.gemspec +6 -1
  22. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/io_console_compatible.rb +1 -1
  23. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/question/answer_converter.rb +2 -5
  24. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/question.rb +23 -13
  25. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/question_asker.rb +3 -1
  26. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/terminal/io_console.rb +1 -1
  27. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/terminal/unix_stty.rb +6 -4
  28. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/terminal.rb +8 -6
  29. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/version.rb +1 -1
  30. data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline.rb +27 -6
  31. data/bundle/ruby/3.1.0/gems/parallel-1.26.3/lib/parallel/version.rb +4 -0
  32. data/bundle/ruby/{3.0.0/gems/parallel-1.23.0 → 3.1.0/gems/parallel-1.26.3}/lib/parallel.rb +76 -20
  33. data/bundle/ruby/3.1.0/gems/reline-0.6.0/COPYING +56 -0
  34. data/bundle/ruby/3.1.0/gems/reline-0.6.0/README.md +94 -0
  35. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/config.rb +373 -0
  36. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/face.rb +199 -0
  37. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/history.rb +76 -0
  38. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/io/ansi.rb +325 -0
  39. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/io/dumb.rb +120 -0
  40. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/io/windows.rb +530 -0
  41. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/io.rb +55 -0
  42. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor/base.rb +37 -0
  43. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor/composite.rb +17 -0
  44. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor/emacs.rb +517 -0
  45. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor/vi_command.rb +518 -0
  46. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor/vi_insert.rb +517 -0
  47. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_actor.rb +8 -0
  48. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/key_stroke.rb +119 -0
  49. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/kill_ring.rb +125 -0
  50. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/line_editor.rb +2382 -0
  51. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/unicode/east_asian_width.rb +1267 -0
  52. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/unicode.rb +415 -0
  53. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline/version.rb +3 -0
  54. data/bundle/ruby/3.1.0/gems/reline-0.6.0/lib/reline.rb +519 -0
  55. data/bundle/ruby/3.1.0/gems/reline-0.6.0/license_of_rb-readline +25 -0
  56. data/bundle/ruby/3.1.0/gems/rexml-3.4.0/LICENSE.txt +22 -0
  57. data/bundle/ruby/3.1.0/gems/rexml-3.4.0/NEWS.md +675 -0
  58. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/README.md +10 -1
  59. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/attribute.rb +17 -11
  60. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/document.rb +6 -2
  61. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/element.rb +19 -34
  62. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/entity.rb +9 -38
  63. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/formatters/pretty.rb +3 -3
  64. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/functions.rb +1 -2
  65. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/namespace.rb +8 -4
  66. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/node.rb +8 -4
  67. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parseexception.rb +1 -0
  68. data/bundle/ruby/3.1.0/gems/rexml-3.4.0/lib/rexml/parsers/baseparser.rb +866 -0
  69. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/pullparser.rb +16 -0
  70. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/sax2parser.rb +16 -19
  71. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/streamparser.rb +16 -10
  72. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/treeparser.rb +9 -21
  73. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/xpathparser.rb +136 -86
  74. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/rexml.rb +3 -1
  75. data/bundle/ruby/3.1.0/gems/rexml-3.4.0/lib/rexml/source.rb +369 -0
  76. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/text.rb +60 -61
  77. data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/xpath_parser.rb +7 -3
  78. data/bundle/ruby/{3.0.0/gems/ruby2ruby-2.4.4 → 3.1.0/gems/ruby2ruby-2.5.1}/History.rdoc +22 -0
  79. data/bundle/ruby/{3.0.0/gems/ruby2ruby-2.4.4 → 3.1.0/gems/ruby2ruby-2.5.1}/lib/ruby2ruby.rb +162 -26
  80. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/History.rdoc +18 -0
  81. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/compare/normalize.rb +1 -0
  82. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby20_parser.rb +4220 -4273
  83. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby20_parser.y +0 -10
  84. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby21_parser.rb +4203 -4238
  85. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby21_parser.y +0 -10
  86. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby22_parser.rb +4239 -4276
  87. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby22_parser.y +0 -10
  88. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby23_parser.rb +4235 -4240
  89. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1/lib/ruby24_parser.y → 3.1.0/gems/ruby_parser-3.20.3/lib/ruby23_parser.y} +1 -19
  90. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby24_parser.rb +4229 -4284
  91. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1/lib/ruby23_parser.y → 3.1.0/gems/ruby_parser-3.20.3/lib/ruby24_parser.y} +9 -11
  92. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby25_parser.rb +4220 -4275
  93. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby25_parser.y +0 -10
  94. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby26_parser.rb +4221 -4276
  95. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby26_parser.y +0 -10
  96. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby27_parser.rb +4138 -4207
  97. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby27_parser.y +0 -10
  98. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby30_parser.rb +5989 -5957
  99. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby30_parser.y +95 -72
  100. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby31_parser.rb +6157 -6172
  101. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby31_parser.y +96 -73
  102. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby32_parser.rb +6251 -6314
  103. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby32_parser.y +117 -93
  104. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby3_parser.yy +132 -73
  105. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_lexer.rb +15 -7
  106. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_lexer.rex.rb +1 -1
  107. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_lexer_strings.rb +2 -2
  108. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_parser.yy +0 -10
  109. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_parser_extras.rb +9 -9
  110. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/tools/munge.rb +8 -2
  111. data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/tools/ripper.rb +14 -12
  112. data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/History.rdoc +18 -0
  113. data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/pt_testcase.rb +1 -1
  114. data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/sexp.rb +1 -1
  115. data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/sexp_matcher.rb +1 -1
  116. data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/sexp_processor.rb +1 -1
  117. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/CHANGES +44 -8
  118. data/bundle/ruby/3.1.0/gems/slim-5.2.1/Gemfile +43 -0
  119. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/LICENSE +1 -1
  120. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/README.jp.md +28 -41
  121. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/README.md +66 -43
  122. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/code_attributes.rb +2 -1
  123. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/command.rb +2 -8
  124. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/controls.rb +1 -0
  125. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/do_inserter.rb +4 -3
  126. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/embedded.rb +17 -17
  127. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/end_inserter.rb +3 -2
  128. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/engine.rb +3 -0
  129. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/erb_converter.rb +1 -0
  130. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/filter.rb +1 -0
  131. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/grammar.rb +1 -0
  132. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/include.rb +1 -0
  133. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/interpolation.rb +1 -0
  134. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/logic_less/context.rb +6 -7
  135. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/logic_less/filter.rb +1 -0
  136. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/logic_less.rb +1 -0
  137. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/parser.rb +26 -39
  138. data/bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/railtie.rb +19 -0
  139. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/smart/escaper.rb +1 -1
  140. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/smart/filter.rb +3 -2
  141. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/smart/parser.rb +4 -3
  142. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/smart.rb +1 -0
  143. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/splat/builder.rb +16 -8
  144. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/splat/filter.rb +6 -4
  145. data/bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/template.rb +6 -0
  146. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/translator.rb +4 -3
  147. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim/version.rb +2 -1
  148. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/lib/slim.rb +2 -0
  149. data/bundle/ruby/{3.0.0/gems/slim-4.1.0 → 3.1.0/gems/slim-5.2.1}/slim.gemspec +14 -5
  150. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/CHANGES +39 -1
  151. data/bundle/ruby/3.1.0/gems/temple-0.10.3/Gemfile +2 -0
  152. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/README.md +1 -1
  153. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/engine.rb +1 -0
  154. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/erb/engine.rb +3 -0
  155. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/erb/parser.rb +2 -1
  156. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/erb/template.rb +1 -0
  157. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/erb/trimming.rb +1 -0
  158. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/exceptions.rb +1 -0
  159. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filter.rb +1 -0
  160. data/bundle/ruby/3.1.0/gems/temple-0.10.3/lib/temple/filters/ambles.rb +22 -0
  161. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/code_merger.rb +1 -0
  162. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/control_flow.rb +1 -0
  163. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/dynamic_inliner.rb +2 -1
  164. data/bundle/ruby/3.1.0/gems/temple-0.10.3/lib/temple/filters/dynamic_merger.rb +69 -0
  165. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/encoding.rb +1 -0
  166. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/eraser.rb +1 -0
  167. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/escapable.rb +1 -0
  168. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/multi_flattener.rb +1 -0
  169. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/remove_bom.rb +1 -0
  170. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/static_analyzer.rb +1 -0
  171. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/static_merger.rb +1 -0
  172. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/string_splitter.rb +13 -1
  173. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/filters/validator.rb +1 -0
  174. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generator.rb +5 -2
  175. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generators/array.rb +1 -0
  176. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generators/array_buffer.rb +1 -0
  177. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generators/erb.rb +1 -0
  178. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generators/rails_output_buffer.rb +4 -4
  179. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/generators/string_buffer.rb +2 -1
  180. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/grammar.rb +1 -0
  181. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/attribute_merger.rb +1 -0
  182. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/attribute_remover.rb +1 -0
  183. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/attribute_sorter.rb +1 -0
  184. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/dispatcher.rb +1 -0
  185. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/fast.rb +1 -0
  186. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/filter.rb +1 -0
  187. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/pretty.rb +1 -0
  188. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/html/safe.rb +1 -0
  189. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/map.rb +1 -0
  190. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/mixins/dispatcher.rb +1 -0
  191. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/mixins/engine_dsl.rb +1 -0
  192. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/mixins/grammar_dsl.rb +4 -2
  193. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/mixins/options.rb +1 -0
  194. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/mixins/template.rb +1 -0
  195. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/parser.rb +1 -0
  196. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/static_analyzer.rb +1 -0
  197. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/templates/rails.rb +7 -2
  198. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/templates/tilt.rb +2 -9
  199. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/templates.rb +1 -0
  200. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple/utils.rb +5 -15
  201. data/bundle/ruby/3.1.0/gems/temple-0.10.3/lib/temple/version.rb +4 -0
  202. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/lib/temple.rb +3 -0
  203. data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/temple.gemspec +4 -6
  204. data/bundle/ruby/3.1.0/gems/terminal-table-3.0.2/History.rdoc +142 -0
  205. data/bundle/ruby/3.1.0/gems/terminal-table-3.0.2/README.md +417 -0
  206. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/cell.rb +8 -8
  207. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/row.rb +18 -4
  208. data/bundle/ruby/3.1.0/gems/terminal-table-3.0.2/lib/terminal-table/separator.rb +66 -0
  209. data/bundle/ruby/3.1.0/gems/terminal-table-3.0.2/lib/terminal-table/style.rb +284 -0
  210. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/table.rb +47 -18
  211. data/bundle/ruby/3.1.0/gems/terminal-table-3.0.2/lib/terminal-table/util.rb +13 -0
  212. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/version.rb +1 -1
  213. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table.rb +2 -2
  214. data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/terminal-table.gemspec +3 -3
  215. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/COPYING +1 -0
  216. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/_emacs_org.rb +2 -0
  217. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/_handlebars.rb +2 -0
  218. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/_jbuilder.rb +2 -0
  219. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/_org.rb +2 -0
  220. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/asciidoc.rb +15 -0
  221. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/babel.rb +8 -0
  222. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/builder.rb +42 -0
  223. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/cli.rb +134 -0
  224. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/coffee.rb +39 -0
  225. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/commonmarker.rb +95 -0
  226. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/creole.rb +16 -0
  227. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/csv.rb +6 -18
  228. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/erb.rb +23 -21
  229. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/erubi.rb +55 -0
  230. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/etanni.rb +5 -4
  231. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/haml.rb +94 -0
  232. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/kramdown.rb +13 -0
  233. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/liquid.rb +10 -17
  234. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/livescript.rb +11 -0
  235. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/mapping.rb +228 -109
  236. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/markaby.rb +5 -7
  237. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/nokogiri.rb +11 -10
  238. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/pandoc.rb +39 -0
  239. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/pipeline.rb +19 -0
  240. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/plain.rb +5 -0
  241. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/prawn.rb +28 -0
  242. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/radius.rb +41 -0
  243. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/rdiscount.rb +23 -0
  244. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/rdoc.rb +11 -0
  245. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/redcarpet.rb +31 -0
  246. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/redcloth.rb +13 -0
  247. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/rst-pandoc.rb +10 -0
  248. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/sass.rb +78 -0
  249. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/slim.rb +5 -0
  250. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/string.rb +9 -3
  251. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/template.rb +479 -0
  252. data/bundle/ruby/3.1.0/gems/tilt-2.5.0/lib/tilt/typescript.rb +19 -0
  253. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt/yajl.rb +5 -11
  254. data/bundle/ruby/{3.0.0/gems/tilt-2.0.11 → 3.1.0/gems/tilt-2.5.0}/lib/tilt.rb +60 -43
  255. data/bundle/ruby/{3.0.0/gems/unicode-display_width-1.8.0 → 3.1.0/gems/unicode-display_width-2.6.0}/CHANGELOG.md +65 -2
  256. data/bundle/ruby/{3.0.0/gems/unicode-display_width-1.8.0 → 3.1.0/gems/unicode-display_width-2.6.0}/MIT-LICENSE.txt +1 -1
  257. data/bundle/ruby/{3.0.0/gems/unicode-display_width-1.8.0 → 3.1.0/gems/unicode-display_width-2.6.0}/README.md +67 -20
  258. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/data/display_width.marshal.gz +0 -0
  259. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/constants.rb +10 -0
  260. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/index.rb +34 -0
  261. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/no_string_ext.rb +8 -0
  262. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width/string_ext.rb +9 -0
  263. data/bundle/ruby/3.1.0/gems/unicode-display_width-2.6.0/lib/unicode/display_width.rb +123 -0
  264. data/lib/brakeman/app_tree.rb +31 -11
  265. data/lib/brakeman/checks/check_deserialize.rb +4 -1
  266. data/lib/brakeman/checks/check_eol_rails.rb +6 -0
  267. data/lib/brakeman/checks/check_eol_ruby.rb +1 -0
  268. data/lib/brakeman/checks/check_evaluation.rb +20 -2
  269. data/lib/brakeman/checks/check_execute.rb +28 -0
  270. data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -0
  271. data/lib/brakeman/checks/check_ransack.rb +53 -0
  272. data/lib/brakeman/checks/check_render.rb +6 -1
  273. data/lib/brakeman/checks/check_session_settings.rb +2 -3
  274. data/lib/brakeman/checks/check_sql.rb +1 -1
  275. data/lib/brakeman/checks/check_unscoped_find.rb +1 -1
  276. data/lib/brakeman/file_parser.rb +35 -2
  277. data/lib/brakeman/options.rb +41 -4
  278. data/lib/brakeman/parsers/erubis_patch.rb +11 -0
  279. data/lib/brakeman/parsers/rails2_erubis.rb +3 -0
  280. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +4 -0
  281. data/lib/brakeman/parsers/rails3_erubis.rb +5 -1
  282. data/lib/brakeman/parsers/slim_embedded.rb +2 -0
  283. data/lib/brakeman/processors/alias_processor.rb +48 -19
  284. data/lib/brakeman/processors/lib/file_type_detector.rb +9 -7
  285. data/lib/brakeman/processors/lib/module_helper.rb +31 -1
  286. data/lib/brakeman/processors/library_processor.rb +6 -0
  287. data/lib/brakeman/report/ignore/config.rb +0 -1
  288. data/lib/brakeman/report/pager.rb +1 -1
  289. data/lib/brakeman/report/report_markdown.rb +1 -1
  290. data/lib/brakeman/report/report_sarif.rb +122 -2
  291. data/lib/brakeman/report/report_table.rb +2 -2
  292. data/lib/brakeman/report/report_tabs.rb +0 -1
  293. data/lib/brakeman/report/report_text.rb +8 -1
  294. data/lib/brakeman/rescanner.rb +40 -390
  295. data/lib/brakeman/scanner.rb +160 -74
  296. data/lib/brakeman/tracker/config.rb +22 -8
  297. data/lib/brakeman/tracker/controller.rb +14 -10
  298. data/lib/brakeman/tracker/file_cache.rb +83 -0
  299. data/lib/brakeman/tracker.rb +20 -3
  300. data/lib/brakeman/util.rb +1 -3
  301. data/lib/brakeman/version.rb +1 -1
  302. data/lib/brakeman/warning.rb +1 -1
  303. data/lib/brakeman/warning_codes.rb +1 -0
  304. data/lib/brakeman.rb +16 -5
  305. data/lib/ruby_parser/bm_sexp.rb +5 -1
  306. metadata +432 -406
  307. data/bundle/ruby/3.0.0/gems/parallel-1.23.0/lib/parallel/version.rb +0 -4
  308. data/bundle/ruby/3.0.0/gems/rexml-3.2.5/NEWS.md +0 -178
  309. data/bundle/ruby/3.0.0/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +0 -694
  310. data/bundle/ruby/3.0.0/gems/rexml-3.2.5/lib/rexml/source.rb +0 -298
  311. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/CHANGES.md +0 -154
  312. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/Gemfile +0 -11
  313. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/LICENSE.txt +0 -22
  314. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/README.md +0 -191
  315. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/bundle_install_all_ruby_versions.sh +0 -11
  316. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/deep.rb +0 -34
  317. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/libyaml_checker.rb +0 -36
  318. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb +0 -181
  319. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/date.rb +0 -37
  320. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/hexadecimal.rb +0 -12
  321. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/parse/sexagesimal.rb +0 -26
  322. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_handler.rb +0 -99
  323. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/psych_resolver.rb +0 -52
  324. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/resolver.rb +0 -94
  325. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/safe_to_ruby_visitor.rb +0 -29
  326. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb +0 -39
  327. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_hack.rb +0 -36
  328. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_node_monkeypatch.rb +0 -43
  329. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/syck_resolver.rb +0 -38
  330. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_boolean.rb +0 -21
  331. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_date.rb +0 -13
  332. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_float.rb +0 -33
  333. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_integer.rb +0 -26
  334. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_nil.rb +0 -18
  335. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/to_symbol.rb +0 -17
  336. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform/transformation_map.rb +0 -47
  337. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/transform.rb +0 -41
  338. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml/version.rb +0 -3
  339. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/lib/safe_yaml.rb +0 -94
  340. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/run_specs_all_ruby_versions.sh +0 -38
  341. data/bundle/ruby/3.0.0/gems/safe_yaml-1.0.5/safe_yaml.gemspec +0 -19
  342. data/bundle/ruby/3.0.0/gems/slim-4.1.0/Gemfile +0 -70
  343. data/bundle/ruby/3.0.0/gems/slim-4.1.0/lib/slim/template.rb +0 -19
  344. data/bundle/ruby/3.0.0/gems/temple-0.8.2/Gemfile +0 -3
  345. data/bundle/ruby/3.0.0/gems/temple-0.8.2/lib/temple/version.rb +0 -3
  346. data/bundle/ruby/3.0.0/gems/terminal-table-1.8.0/History.rdoc +0 -85
  347. data/bundle/ruby/3.0.0/gems/terminal-table-1.8.0/README.rdoc +0 -247
  348. data/bundle/ruby/3.0.0/gems/terminal-table-1.8.0/lib/terminal-table/separator.rb +0 -14
  349. data/bundle/ruby/3.0.0/gems/terminal-table-1.8.0/lib/terminal-table/style.rb +0 -79
  350. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/asciidoc.rb +0 -27
  351. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/babel.rb +0 -16
  352. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/bluecloth.rb +0 -24
  353. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/builder.rb +0 -37
  354. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/coffee.rb +0 -58
  355. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/commonmarker.rb +0 -88
  356. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/creole.rb +0 -25
  357. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/dummy.rb +0 -3
  358. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/erubi.rb +0 -32
  359. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/erubis.rb +0 -43
  360. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/haml.rb +0 -86
  361. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/kramdown.rb +0 -25
  362. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/less.rb +0 -30
  363. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/livescript.rb +0 -23
  364. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/maruku.rb +0 -22
  365. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/pandoc.rb +0 -57
  366. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/plain.rb +0 -16
  367. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/prawn.rb +0 -43
  368. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/radius.rb +0 -48
  369. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/rdiscount.rb +0 -39
  370. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/rdoc.rb +0 -40
  371. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/redcarpet.rb +0 -86
  372. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/redcloth.rb +0 -23
  373. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/rst-pandoc.rb +0 -23
  374. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/sass.rb +0 -78
  375. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/sigil.rb +0 -34
  376. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/template.rb +0 -308
  377. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/typescript.rb +0 -26
  378. data/bundle/ruby/3.0.0/gems/tilt-2.0.11/lib/tilt/wikicloth.rb +0 -22
  379. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/data/display_width.marshal.gz +0 -0
  380. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/lib/unicode/display_width/constants.rb +0 -8
  381. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/lib/unicode/display_width/index.rb +0 -12
  382. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/lib/unicode/display_width/no_string_ext.rb +0 -7
  383. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/lib/unicode/display_width/string_ext.rb +0 -17
  384. data/bundle/ruby/3.0.0/gems/unicode-display_width-1.8.0/lib/unicode/display_width.rb +0 -51
  385. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/CHANGES.txt +0 -0
  386. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/MIT-LICENSE +0 -0
  387. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/README.txt +0 -0
  388. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/contrib/erubis +0 -0
  389. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/contrib/erubis-run.rb +0 -0
  390. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/contrib/inline-require +0 -0
  391. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/context.rb +0 -0
  392. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/converter.rb +0 -0
  393. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/ec.rb +0 -0
  394. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/ecpp.rb +0 -0
  395. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/ejava.rb +0 -0
  396. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/ejavascript.rb +0 -0
  397. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/enhanced.rb +0 -0
  398. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/eperl.rb +0 -0
  399. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/ephp.rb +0 -0
  400. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/eruby.rb +0 -0
  401. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/escheme.rb +0 -0
  402. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine/optimized.rb +0 -0
  403. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/engine.rb +0 -0
  404. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/enhancer.rb +0 -0
  405. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/error.rb +0 -0
  406. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/evaluator.rb +0 -0
  407. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/generator.rb +0 -0
  408. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/helper.rb +0 -0
  409. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/helpers/rails_form_helper.rb +0 -0
  410. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/helpers/rails_helper.rb +0 -0
  411. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/local-setting.rb +0 -0
  412. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/main.rb +0 -0
  413. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/preprocessing.rb +0 -0
  414. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/tiny.rb +0 -0
  415. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis/util.rb +0 -0
  416. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/lib/erubis.rb +0 -0
  417. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/erubis-2.7.0/setup.rb +0 -0
  418. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/CHANGELOG.md +0 -0
  419. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/FAQ.md +0 -0
  420. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/Gemfile +0 -0
  421. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/MIT-LICENSE +0 -0
  422. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/README.md +0 -0
  423. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/REFERENCE.md +0 -0
  424. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/TODO +0 -0
  425. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/haml.gemspec +0 -0
  426. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/attribute_builder.rb +0 -0
  427. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/attribute_compiler.rb +0 -0
  428. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/attribute_parser.rb +0 -0
  429. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/buffer.rb +0 -0
  430. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/compiler.rb +0 -0
  431. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/engine.rb +0 -0
  432. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/error.rb +0 -0
  433. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/escapable.rb +0 -0
  434. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/exec.rb +0 -0
  435. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/filters.rb +0 -0
  436. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/generator.rb +0 -0
  437. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/action_view_extensions.rb +0 -0
  438. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/action_view_mods.rb +0 -0
  439. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/action_view_xss_mods.rb +0 -0
  440. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/safe_erubi_template.rb +0 -0
  441. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/safe_erubis_template.rb +0 -0
  442. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers/xss_mods.rb +0 -0
  443. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/helpers.rb +0 -0
  444. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/options.rb +0 -0
  445. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/parser.rb +0 -0
  446. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/plugin.rb +0 -0
  447. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/railtie.rb +0 -0
  448. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/sass_rails_filter.rb +0 -0
  449. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/template/options.rb +0 -0
  450. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/template.rb +0 -0
  451. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/temple_engine.rb +0 -0
  452. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/temple_line_counter.rb +0 -0
  453. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/util.rb +0 -0
  454. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml/version.rb +0 -0
  455. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/lib/haml.rb +0 -0
  456. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/yard/default/fulldoc/html/css/common.sass +0 -0
  457. /data/bundle/ruby/{3.0.0 → 3.1.0}/gems/haml-5.2.2/yard/default/layout/html/footer.erb +0 -0
  458. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/AUTHORS +0 -0
  459. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/COPYING +0 -0
  460. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/LICENSE +0 -0
  461. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/TODO +0 -0
  462. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/builtin_styles.rb +0 -0
  463. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/color_scheme.rb +0 -0
  464. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/compatibility.rb +0 -0
  465. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/custom_errors.rb +0 -0
  466. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/import.rb +0 -0
  467. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/list.rb +0 -0
  468. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/list_renderer.rb +0 -0
  469. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/menu/item.rb +0 -0
  470. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/menu.rb +0 -0
  471. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/paginator.rb +0 -0
  472. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/simulate.rb +0 -0
  473. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/statement.rb +0 -0
  474. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/string.rb +0 -0
  475. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/string_extensions.rb +0 -0
  476. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/style.rb +0 -0
  477. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/template_renderer.rb +0 -0
  478. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/terminal/ncurses.rb +0 -0
  479. /data/bundle/ruby/{3.0.0/gems/highline-2.1.0 → 3.1.0/gems/highline-3.1.1}/lib/highline/wrapper.rb +0 -0
  480. /data/bundle/ruby/{3.0.0/gems/parallel-1.23.0 → 3.1.0/gems/parallel-1.26.3}/MIT-LICENSE.txt +0 -0
  481. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5/LICENSE.txt → 3.1.0/gems/reline-0.6.0/BSDL} +0 -0
  482. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/attlistdecl.rb +0 -0
  483. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/cdata.rb +0 -0
  484. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/child.rb +0 -0
  485. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/comment.rb +0 -0
  486. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/doctype.rb +0 -0
  487. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/dtd/attlistdecl.rb +0 -0
  488. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/dtd/dtd.rb +0 -0
  489. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/dtd/elementdecl.rb +0 -0
  490. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/dtd/entitydecl.rb +0 -0
  491. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/dtd/notationdecl.rb +0 -0
  492. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/encoding.rb +0 -0
  493. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/formatters/default.rb +0 -0
  494. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/formatters/transitive.rb +0 -0
  495. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/instruction.rb +0 -0
  496. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/light/node.rb +0 -0
  497. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/output.rb +0 -0
  498. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parent.rb +0 -0
  499. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/lightparser.rb +0 -0
  500. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/parsers/ultralightparser.rb +0 -0
  501. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/quickpath.rb +0 -0
  502. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/sax2listener.rb +0 -0
  503. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/security.rb +0 -0
  504. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/streamlistener.rb +0 -0
  505. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/undefinednamespaceexception.rb +0 -0
  506. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/validation/relaxng.rb +0 -0
  507. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/validation/validation.rb +0 -0
  508. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/validation/validationexception.rb +0 -0
  509. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/xmldecl.rb +0 -0
  510. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/xmltokens.rb +0 -0
  511. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml/xpath.rb +0 -0
  512. /data/bundle/ruby/{3.0.0/gems/rexml-3.2.5 → 3.1.0/gems/rexml-3.4.0}/lib/rexml.rb +0 -0
  513. /data/bundle/ruby/{3.0.0/gems/ruby2ruby-2.4.4 → 3.1.0/gems/ruby2ruby-2.5.1}/Manifest.txt +0 -0
  514. /data/bundle/ruby/{3.0.0/gems/ruby2ruby-2.4.4 → 3.1.0/gems/ruby2ruby-2.5.1}/README.rdoc +0 -0
  515. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/Manifest.txt +0 -0
  516. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/README.rdoc +0 -0
  517. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/debugging.md +0 -0
  518. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/gauntlet.md +0 -0
  519. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/rp_extensions.rb +0 -0
  520. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/rp_stringscanner.rb +0 -0
  521. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_lexer.rex +0 -0
  522. /data/bundle/ruby/{3.0.0/gems/ruby_parser-3.20.1 → 3.1.0/gems/ruby_parser-3.20.3}/lib/ruby_parser.rb +0 -0
  523. /data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/Manifest.txt +0 -0
  524. /data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/README.rdoc +0 -0
  525. /data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/composite_sexp_processor.rb +0 -0
  526. /data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/strict_sexp.rb +0 -0
  527. /data/bundle/ruby/{3.0.0/gems/sexp_processor-4.17.0 → 3.1.0/gems/sexp_processor-4.17.3}/lib/unique.rb +0 -0
  528. /data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/EXPRESSIONS.md +0 -0
  529. /data/bundle/ruby/{3.0.0/gems/temple-0.8.2 → 3.1.0/gems/temple-0.10.3}/LICENSE +0 -0
  530. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/Gemfile +0 -0
  531. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/LICENSE.txt +0 -0
  532. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/Manifest +0 -0
  533. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/Todo.rdoc +0 -0
  534. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/import.rb +0 -0
  535. /data/bundle/ruby/{3.0.0/gems/terminal-table-1.8.0 → 3.1.0/gems/terminal-table-3.0.2}/lib/terminal-table/table_helper.rb +0 -0
@@ -0,0 +1,2382 @@
1
+ require 'reline/kill_ring'
2
+ require 'reline/unicode'
3
+
4
+ require 'tempfile'
5
+
6
+ class Reline::LineEditor
7
+ # TODO: Use "private alias_method" idiom after drop Ruby 2.5.
8
+ attr_reader :byte_pointer
9
+ attr_accessor :confirm_multiline_termination_proc
10
+ attr_accessor :completion_proc
11
+ attr_accessor :completion_append_character
12
+ attr_accessor :output_modifier_proc
13
+ attr_accessor :prompt_proc
14
+ attr_accessor :auto_indent_proc
15
+ attr_accessor :dig_perfect_match_proc
16
+
17
+ VI_MOTIONS = %i{
18
+ ed_prev_char
19
+ ed_next_char
20
+ vi_zero
21
+ ed_move_to_beg
22
+ ed_move_to_end
23
+ vi_to_column
24
+ vi_next_char
25
+ vi_prev_char
26
+ vi_next_word
27
+ vi_prev_word
28
+ vi_to_next_char
29
+ vi_to_prev_char
30
+ vi_end_word
31
+ vi_next_big_word
32
+ vi_prev_big_word
33
+ vi_end_big_word
34
+ }
35
+
36
+ module CompletionState
37
+ NORMAL = :normal
38
+ MENU = :menu
39
+ MENU_WITH_PERFECT_MATCH = :menu_with_perfect_match
40
+ PERFECT_MATCH = :perfect_match
41
+ end
42
+
43
+ RenderedScreen = Struct.new(:base_y, :lines, :cursor_y, keyword_init: true)
44
+
45
+ CompletionJourneyState = Struct.new(:line_index, :pre, :target, :post, :list, :pointer)
46
+ NullActionState = [nil, nil].freeze
47
+
48
+ class MenuInfo
49
+ attr_reader :list
50
+
51
+ def initialize(list)
52
+ @list = list
53
+ end
54
+
55
+ def lines(screen_width)
56
+ return [] if @list.empty?
57
+
58
+ list = @list.sort
59
+ sizes = list.map { |item| Reline::Unicode.calculate_width(item) }
60
+ item_width = sizes.max + 2
61
+ num_cols = [screen_width / item_width, 1].max
62
+ num_rows = list.size.fdiv(num_cols).ceil
63
+ list_with_padding = list.zip(sizes).map { |item, size| item + ' ' * (item_width - size) }
64
+ aligned = (list_with_padding + [nil] * (num_rows * num_cols - list_with_padding.size)).each_slice(num_rows).to_a.transpose
65
+ aligned.map do |row|
66
+ row.join.rstrip
67
+ end
68
+ end
69
+ end
70
+
71
+ MINIMUM_SCROLLBAR_HEIGHT = 1
72
+
73
+ def initialize(config)
74
+ @config = config
75
+ @completion_append_character = ''
76
+ @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
77
+ reset_variables
78
+ end
79
+
80
+ def io_gate
81
+ Reline::IOGate
82
+ end
83
+
84
+ def encoding
85
+ io_gate.encoding
86
+ end
87
+
88
+ def set_pasting_state(in_pasting)
89
+ # While pasting, text to be inserted is stored to @continuous_insertion_buffer.
90
+ # After pasting, this buffer should be force inserted.
91
+ process_insert(force: true) if @in_pasting && !in_pasting
92
+ @in_pasting = in_pasting
93
+ end
94
+
95
+ private def check_mode_string
96
+ if @config.show_mode_in_prompt
97
+ if @config.editing_mode_is?(:vi_command)
98
+ @config.vi_cmd_mode_string
99
+ elsif @config.editing_mode_is?(:vi_insert)
100
+ @config.vi_ins_mode_string
101
+ elsif @config.editing_mode_is?(:emacs)
102
+ @config.emacs_mode_string
103
+ else
104
+ '?'
105
+ end
106
+ end
107
+ end
108
+
109
+ private def check_multiline_prompt(buffer, mode_string)
110
+ if @vi_arg
111
+ prompt = "(arg: #{@vi_arg}) "
112
+ elsif @searching_prompt
113
+ prompt = @searching_prompt
114
+ else
115
+ prompt = @prompt
116
+ end
117
+ if !@is_multiline
118
+ mode_string = check_mode_string
119
+ prompt = mode_string + prompt if mode_string
120
+ [prompt] + [''] * (buffer.size - 1)
121
+ elsif @prompt_proc
122
+ prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") }
123
+ prompt_list.map!{ prompt } if @vi_arg or @searching_prompt
124
+ prompt_list = [prompt] if prompt_list.empty?
125
+ prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string
126
+ prompt = prompt_list[@line_index]
127
+ prompt = prompt_list[0] if prompt.nil?
128
+ prompt = prompt_list.last if prompt.nil?
129
+ if buffer.size > prompt_list.size
130
+ (buffer.size - prompt_list.size).times do
131
+ prompt_list << prompt_list.last
132
+ end
133
+ end
134
+ prompt_list
135
+ else
136
+ prompt = mode_string + prompt if mode_string
137
+ [prompt] * buffer.size
138
+ end
139
+ end
140
+
141
+ def reset(prompt = '')
142
+ @screen_size = Reline::IOGate.get_screen_size
143
+ reset_variables(prompt)
144
+ @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
145
+ if ENV.key?('RELINE_ALT_SCROLLBAR')
146
+ @full_block = '::'
147
+ @upper_half_block = "''"
148
+ @lower_half_block = '..'
149
+ @block_elem_width = 2
150
+ elsif Reline::IOGate.win?
151
+ @full_block = '█'
152
+ @upper_half_block = '▀'
153
+ @lower_half_block = '▄'
154
+ @block_elem_width = 1
155
+ elsif encoding == Encoding::UTF_8
156
+ @full_block = '█'
157
+ @upper_half_block = '▀'
158
+ @lower_half_block = '▄'
159
+ @block_elem_width = Reline::Unicode.calculate_width('█')
160
+ else
161
+ @full_block = '::'
162
+ @upper_half_block = "''"
163
+ @lower_half_block = '..'
164
+ @block_elem_width = 2
165
+ end
166
+ end
167
+
168
+ def handle_signal
169
+ handle_interrupted
170
+ handle_resized
171
+ end
172
+
173
+ private def handle_resized
174
+ return unless @resized
175
+
176
+ @screen_size = Reline::IOGate.get_screen_size
177
+ @resized = false
178
+ scroll_into_view
179
+ Reline::IOGate.move_cursor_up @rendered_screen.cursor_y
180
+ @rendered_screen.base_y = Reline::IOGate.cursor_pos.y
181
+ clear_rendered_screen_cache
182
+ render
183
+ end
184
+
185
+ private def handle_interrupted
186
+ return unless @interrupted
187
+
188
+ @interrupted = false
189
+ clear_dialogs
190
+ render
191
+ cursor_to_bottom_offset = @rendered_screen.lines.size - @rendered_screen.cursor_y
192
+ Reline::IOGate.scroll_down cursor_to_bottom_offset
193
+ Reline::IOGate.move_cursor_column 0
194
+ clear_rendered_screen_cache
195
+ case @old_trap
196
+ when 'DEFAULT', 'SYSTEM_DEFAULT'
197
+ raise Interrupt
198
+ when 'IGNORE'
199
+ # Do nothing
200
+ when 'EXIT'
201
+ exit
202
+ else
203
+ @old_trap.call if @old_trap.respond_to?(:call)
204
+ end
205
+ end
206
+
207
+ def set_signal_handlers
208
+ Reline::IOGate.set_winch_handler do
209
+ @resized = true
210
+ end
211
+ @old_trap = Signal.trap('INT') do
212
+ @interrupted = true
213
+ end
214
+ end
215
+
216
+ def finalize
217
+ Signal.trap('INT', @old_trap)
218
+ end
219
+
220
+ def eof?
221
+ @eof
222
+ end
223
+
224
+ def reset_variables(prompt = '')
225
+ @prompt = prompt.gsub("\n", "\\n")
226
+ @mark_pointer = nil
227
+ @is_multiline = false
228
+ @finished = false
229
+ @history_pointer = nil
230
+ @kill_ring ||= Reline::KillRing.new
231
+ @vi_clipboard = ''
232
+ @vi_arg = nil
233
+ @waiting_proc = nil
234
+ @vi_waiting_operator = nil
235
+ @vi_waiting_operator_arg = nil
236
+ @completion_journey_state = nil
237
+ @completion_state = CompletionState::NORMAL
238
+ @perfect_matched = nil
239
+ @menu_info = nil
240
+ @searching_prompt = nil
241
+ @just_cursor_moving = false
242
+ @eof = false
243
+ @continuous_insertion_buffer = String.new(encoding: encoding)
244
+ @scroll_partial_screen = 0
245
+ @drop_terminate_spaces = false
246
+ @in_pasting = false
247
+ @auto_indent_proc = nil
248
+ @dialogs = []
249
+ @interrupted = false
250
+ @resized = false
251
+ @cache = {}
252
+ @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
253
+ @input_lines = [[[""], 0, 0]]
254
+ @input_lines_position = 0
255
+ @restoring = false
256
+ @prev_action_state = NullActionState
257
+ @next_action_state = NullActionState
258
+ reset_line
259
+ end
260
+
261
+ def reset_line
262
+ @byte_pointer = 0
263
+ @buffer_of_lines = [String.new(encoding: encoding)]
264
+ @line_index = 0
265
+ @cache.clear
266
+ @line_backup_in_history = nil
267
+ end
268
+
269
+ def multiline_on
270
+ @is_multiline = true
271
+ end
272
+
273
+ def multiline_off
274
+ @is_multiline = false
275
+ end
276
+
277
+ private def insert_new_line(cursor_line, next_line)
278
+ @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: encoding))
279
+ @buffer_of_lines[@line_index] = cursor_line
280
+ @line_index += 1
281
+ @byte_pointer = 0
282
+ if @auto_indent_proc && !@in_pasting
283
+ if next_line.empty?
284
+ (
285
+ # For compatibility, use this calculation instead of just `process_auto_indent @line_index - 1, cursor_dependent: false`
286
+ indent1 = @auto_indent_proc.(@buffer_of_lines.take(@line_index - 1).push(''), @line_index - 1, 0, true)
287
+ indent2 = @auto_indent_proc.(@buffer_of_lines.take(@line_index), @line_index - 1, @buffer_of_lines[@line_index - 1].bytesize, false)
288
+ indent = indent2 || indent1
289
+ @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A\s*/, '')
290
+ )
291
+ process_auto_indent @line_index, add_newline: true
292
+ else
293
+ process_auto_indent @line_index - 1, cursor_dependent: false
294
+ process_auto_indent @line_index, add_newline: true # Need for compatibility
295
+ process_auto_indent @line_index, cursor_dependent: false
296
+ end
297
+ end
298
+ end
299
+
300
+ private def split_line_by_width(str, max_width, offset: 0)
301
+ Reline::Unicode.split_line_by_width(str, max_width, encoding, offset: offset)
302
+ end
303
+
304
+ def current_byte_pointer_cursor
305
+ calculate_width(current_line.byteslice(0, @byte_pointer))
306
+ end
307
+
308
+ private def calculate_nearest_cursor(cursor)
309
+ line_to_calc = current_line
310
+ new_cursor_max = calculate_width(line_to_calc)
311
+ new_cursor = 0
312
+ new_byte_pointer = 0
313
+ height = 1
314
+ max_width = screen_width
315
+ if @config.editing_mode_is?(:vi_command)
316
+ last_byte_size = Reline::Unicode.get_prev_mbchar_size(line_to_calc, line_to_calc.bytesize)
317
+ if last_byte_size > 0
318
+ last_mbchar = line_to_calc.byteslice(line_to_calc.bytesize - last_byte_size, last_byte_size)
319
+ last_width = Reline::Unicode.get_mbchar_width(last_mbchar)
320
+ end_of_line_cursor = new_cursor_max - last_width
321
+ else
322
+ end_of_line_cursor = new_cursor_max
323
+ end
324
+ else
325
+ end_of_line_cursor = new_cursor_max
326
+ end
327
+ line_to_calc.grapheme_clusters.each do |gc|
328
+ mbchar = gc.encode(Encoding::UTF_8)
329
+ mbchar_width = Reline::Unicode.get_mbchar_width(mbchar)
330
+ now = new_cursor + mbchar_width
331
+ if now > end_of_line_cursor or now > cursor
332
+ break
333
+ end
334
+ new_cursor += mbchar_width
335
+ if new_cursor > max_width * height
336
+ height += 1
337
+ end
338
+ new_byte_pointer += gc.bytesize
339
+ end
340
+ @byte_pointer = new_byte_pointer
341
+ end
342
+
343
+ def with_cache(key, *deps)
344
+ cached_deps, value = @cache[key]
345
+ if cached_deps != deps
346
+ @cache[key] = [deps, value = yield(*deps, cached_deps, value)]
347
+ end
348
+ value
349
+ end
350
+
351
+ def modified_lines
352
+ with_cache(__method__, whole_lines, finished?) do |whole, complete|
353
+ modify_lines(whole, complete)
354
+ end
355
+ end
356
+
357
+ def prompt_list
358
+ with_cache(__method__, whole_lines, check_mode_string, @vi_arg, @searching_prompt) do |lines, mode_string|
359
+ check_multiline_prompt(lines, mode_string)
360
+ end
361
+ end
362
+
363
+ def screen_height
364
+ @screen_size.first
365
+ end
366
+
367
+ def screen_width
368
+ @screen_size.last
369
+ end
370
+
371
+ def screen_scroll_top
372
+ @scroll_partial_screen
373
+ end
374
+
375
+ def wrapped_prompt_and_input_lines
376
+ with_cache(__method__, @buffer_of_lines.size, modified_lines, prompt_list, screen_width) do |n, lines, prompts, width, prev_cache_key, cached_value|
377
+ prev_n, prev_lines, prev_prompts, prev_width = prev_cache_key
378
+ cached_wraps = {}
379
+ if prev_width == width
380
+ prev_n.times do |i|
381
+ cached_wraps[[prev_prompts[i], prev_lines[i]]] = cached_value[i]
382
+ end
383
+ end
384
+
385
+ n.times.map do |i|
386
+ prompt = prompts[i] || ''
387
+ line = lines[i] || ''
388
+ if (cached = cached_wraps[[prompt, line]])
389
+ next cached
390
+ end
391
+ *wrapped_prompts, code_line_prompt = split_line_by_width(prompt, width)
392
+ wrapped_lines = split_line_by_width(line, width, offset: calculate_width(code_line_prompt, true))
393
+ wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
394
+ end
395
+ end
396
+ end
397
+
398
+ def calculate_overlay_levels(overlay_levels)
399
+ levels = []
400
+ overlay_levels.each do |x, w, l|
401
+ levels.fill(l, x, w)
402
+ end
403
+ levels
404
+ end
405
+
406
+ def render_line_differential(old_items, new_items)
407
+ old_levels = calculate_overlay_levels(old_items.zip(new_items).each_with_index.map {|((x, w, c), (nx, _nw, nc)), i| [x, w, c == nc && x == nx ? i : -1] if x }.compact)
408
+ new_levels = calculate_overlay_levels(new_items.each_with_index.map { |(x, w), i| [x, w, i] if x }.compact).take(screen_width)
409
+ base_x = 0
410
+ new_levels.zip(old_levels).chunk { |n, o| n == o ? :skip : n || :blank }.each do |level, chunk|
411
+ width = chunk.size
412
+ if level == :skip
413
+ # do nothing
414
+ elsif level == :blank
415
+ Reline::IOGate.move_cursor_column base_x
416
+ Reline::IOGate.write "#{Reline::IOGate.reset_color_sequence}#{' ' * width}"
417
+ else
418
+ x, w, content = new_items[level]
419
+ cover_begin = base_x != 0 && new_levels[base_x - 1] == level
420
+ cover_end = new_levels[base_x + width] == level
421
+ pos = 0
422
+ unless x == base_x && w == width
423
+ content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true)
424
+ end
425
+ Reline::IOGate.move_cursor_column x + pos
426
+ Reline::IOGate.write "#{Reline::IOGate.reset_color_sequence}#{content}#{Reline::IOGate.reset_color_sequence}"
427
+ end
428
+ base_x += width
429
+ end
430
+ if old_levels.size > new_levels.size
431
+ Reline::IOGate.move_cursor_column new_levels.size
432
+ Reline::IOGate.erase_after_cursor
433
+ end
434
+ end
435
+
436
+ # Calculate cursor position in word wrapped content.
437
+ def wrapped_cursor_position
438
+ prompt_width = calculate_width(prompt_list[@line_index], true)
439
+ line_before_cursor = Reline::Unicode.escape_for_print(whole_lines[@line_index].byteslice(0, @byte_pointer))
440
+ wrapped_line_before_cursor = split_line_by_width(' ' * prompt_width + line_before_cursor, screen_width)
441
+ wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
442
+ wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
443
+ [wrapped_cursor_x, wrapped_cursor_y]
444
+ end
445
+
446
+ def clear_dialogs
447
+ @dialogs.each do |dialog|
448
+ dialog.contents = nil
449
+ dialog.trap_key = nil
450
+ end
451
+ end
452
+
453
+ def update_dialogs(key = nil)
454
+ wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
455
+ @dialogs.each do |dialog|
456
+ dialog.trap_key = nil
457
+ update_each_dialog(dialog, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top, key)
458
+ end
459
+ end
460
+
461
+ def render_finished
462
+ Reline::IOGate.buffered_output do
463
+ render_differential([], 0, 0)
464
+ lines = @buffer_of_lines.size.times.map do |i|
465
+ line = Reline::Unicode.strip_non_printing_start_end(prompt_list[i]) + modified_lines[i]
466
+ wrapped_lines = split_line_by_width(line, screen_width)
467
+ wrapped_lines.last.empty? ? "#{line} " : line
468
+ end
469
+ Reline::IOGate.write lines.map { |l| "#{l}\r\n" }.join
470
+ end
471
+ end
472
+
473
+ def print_nomultiline_prompt
474
+ Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
475
+ # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence.
476
+ Reline::IOGate.write Reline::Unicode.strip_non_printing_start_end(@prompt) if @prompt && !@is_multiline
477
+ ensure
478
+ Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
479
+ end
480
+
481
+ def render
482
+ wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
483
+ new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
484
+ prompt_width = Reline::Unicode.calculate_width(prompt, true)
485
+ [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
486
+ end
487
+ if @menu_info
488
+ @menu_info.lines(screen_width).each do |item|
489
+ new_lines << [[0, Reline::Unicode.calculate_width(item), item]]
490
+ end
491
+ @menu_info = nil # TODO: do not change state here
492
+ end
493
+
494
+ @dialogs.each_with_index do |dialog, index|
495
+ next unless dialog.contents
496
+
497
+ x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
498
+ y_range.each do |row|
499
+ next if row < 0 || row >= screen_height
500
+
501
+ dialog_rows = new_lines[row] ||= []
502
+ # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
503
+ dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
504
+ end
505
+ end
506
+
507
+ Reline::IOGate.buffered_output do
508
+ render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top
509
+ end
510
+ end
511
+
512
+ # Reflects lines to be rendered and new cursor position to the screen
513
+ # by calculating the difference from the previous render.
514
+
515
+ private def render_differential(new_lines, new_cursor_x, new_cursor_y)
516
+ Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win?
517
+ rendered_lines = @rendered_screen.lines
518
+ cursor_y = @rendered_screen.cursor_y
519
+ if new_lines != rendered_lines
520
+ # Hide cursor while rendering to avoid cursor flickering.
521
+ Reline::IOGate.hide_cursor
522
+ num_lines = [[new_lines.size, rendered_lines.size].max, screen_height].min
523
+ if @rendered_screen.base_y + num_lines > screen_height
524
+ Reline::IOGate.scroll_down(num_lines - cursor_y - 1)
525
+ @rendered_screen.base_y = screen_height - num_lines
526
+ cursor_y = num_lines - 1
527
+ end
528
+ num_lines.times do |i|
529
+ rendered_line = rendered_lines[i] || []
530
+ line_to_render = new_lines[i] || []
531
+ next if rendered_line == line_to_render
532
+
533
+ Reline::IOGate.move_cursor_down i - cursor_y
534
+ cursor_y = i
535
+ unless rendered_lines[i]
536
+ Reline::IOGate.move_cursor_column 0
537
+ Reline::IOGate.erase_after_cursor
538
+ end
539
+ render_line_differential(rendered_line, line_to_render)
540
+ end
541
+ @rendered_screen.lines = new_lines
542
+ Reline::IOGate.show_cursor
543
+ end
544
+ Reline::IOGate.move_cursor_column new_cursor_x
545
+ Reline::IOGate.move_cursor_down new_cursor_y - cursor_y
546
+ @rendered_screen.cursor_y = new_cursor_y
547
+ ensure
548
+ Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win?
549
+ end
550
+
551
+ private def clear_rendered_screen_cache
552
+ @rendered_screen.lines = []
553
+ @rendered_screen.cursor_y = 0
554
+ end
555
+
556
+ def upper_space_height(wrapped_cursor_y)
557
+ wrapped_cursor_y - screen_scroll_top
558
+ end
559
+
560
+ def rest_height(wrapped_cursor_y)
561
+ screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
562
+ end
563
+
564
+ def rerender
565
+ render unless @in_pasting
566
+ end
567
+
568
+ class DialogProcScope
569
+ CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
570
+
571
+ def initialize(line_editor, config, proc_to_exec, context)
572
+ @line_editor = line_editor
573
+ @config = config
574
+ @proc_to_exec = proc_to_exec
575
+ @context = context
576
+ @cursor_pos = Reline::CursorPos.new
577
+ end
578
+
579
+ def context
580
+ @context
581
+ end
582
+
583
+ def retrieve_completion_block(_unused = false)
584
+ preposing, target, postposing, _quote = @line_editor.retrieve_completion_block
585
+ [preposing, target, postposing]
586
+ end
587
+
588
+ def call_completion_proc_with_checking_args(pre, target, post)
589
+ @line_editor.call_completion_proc_with_checking_args(pre, target, post)
590
+ end
591
+
592
+ def set_dialog(dialog)
593
+ @dialog = dialog
594
+ end
595
+
596
+ def dialog
597
+ @dialog
598
+ end
599
+
600
+ def set_cursor_pos(col, row)
601
+ @cursor_pos.x = col
602
+ @cursor_pos.y = row
603
+ end
604
+
605
+ def set_key(key)
606
+ @key = key
607
+ end
608
+
609
+ def key
610
+ @key
611
+ end
612
+
613
+ def cursor_pos
614
+ @cursor_pos
615
+ end
616
+
617
+ def just_cursor_moving
618
+ @line_editor.instance_variable_get(:@just_cursor_moving)
619
+ end
620
+
621
+ def screen_width
622
+ @line_editor.screen_width
623
+ end
624
+
625
+ def screen_height
626
+ @line_editor.screen_height
627
+ end
628
+
629
+ def preferred_dialog_height
630
+ _wrapped_cursor_x, wrapped_cursor_y = @line_editor.wrapped_cursor_position
631
+ [@line_editor.upper_space_height(wrapped_cursor_y), @line_editor.rest_height(wrapped_cursor_y), (screen_height + 6) / 5].max
632
+ end
633
+
634
+ def completion_journey_data
635
+ @line_editor.dialog_proc_scope_completion_journey_data
636
+ end
637
+
638
+ def config
639
+ @config
640
+ end
641
+
642
+ def call
643
+ instance_exec(&@proc_to_exec)
644
+ end
645
+ end
646
+
647
+ class Dialog
648
+ attr_reader :name, :contents, :width
649
+ attr_accessor :scroll_top, :pointer, :column, :vertical_offset, :trap_key
650
+
651
+ def initialize(name, config, proc_scope)
652
+ @name = name
653
+ @config = config
654
+ @proc_scope = proc_scope
655
+ @width = nil
656
+ @scroll_top = 0
657
+ @trap_key = nil
658
+ end
659
+
660
+ def set_cursor_pos(col, row)
661
+ @proc_scope.set_cursor_pos(col, row)
662
+ end
663
+
664
+ def width=(v)
665
+ @width = v
666
+ end
667
+
668
+ def contents=(contents)
669
+ @contents = contents
670
+ if contents and @width.nil?
671
+ @width = contents.map{ |line| Reline::Unicode.calculate_width(line, true) }.max
672
+ end
673
+ end
674
+
675
+ def call(key)
676
+ @proc_scope.set_dialog(self)
677
+ @proc_scope.set_key(key)
678
+ dialog_render_info = @proc_scope.call
679
+ if @trap_key
680
+ if @trap_key.any?{ |i| i.is_a?(Array) } # multiple trap
681
+ @trap_key.each do |t|
682
+ @config.add_oneshot_key_binding(t, @name)
683
+ end
684
+ else
685
+ @config.add_oneshot_key_binding(@trap_key, @name)
686
+ end
687
+ end
688
+ dialog_render_info
689
+ end
690
+ end
691
+
692
+ def add_dialog_proc(name, p, context = nil)
693
+ dialog = Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context))
694
+ if index = @dialogs.find_index { |d| d.name == name }
695
+ @dialogs[index] = dialog
696
+ else
697
+ @dialogs << dialog
698
+ end
699
+ end
700
+
701
+ DIALOG_DEFAULT_HEIGHT = 20
702
+
703
+ private def dialog_range(dialog, dialog_y)
704
+ x_range = dialog.column...dialog.column + dialog.width
705
+ y_range = dialog_y + dialog.vertical_offset...dialog_y + dialog.vertical_offset + dialog.contents.size
706
+ [x_range, y_range]
707
+ end
708
+
709
+ private def update_each_dialog(dialog, cursor_column, cursor_row, key = nil)
710
+ dialog.set_cursor_pos(cursor_column, cursor_row)
711
+ dialog_render_info = dialog.call(key)
712
+ if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
713
+ dialog.contents = nil
714
+ dialog.trap_key = nil
715
+ return
716
+ end
717
+ contents = dialog_render_info.contents
718
+ pointer = dialog.pointer
719
+ if dialog_render_info.width
720
+ dialog.width = dialog_render_info.width
721
+ else
722
+ dialog.width = contents.map { |l| calculate_width(l, true) }.max
723
+ end
724
+ height = dialog_render_info.height || DIALOG_DEFAULT_HEIGHT
725
+ height = contents.size if contents.size < height
726
+ if contents.size > height
727
+ if dialog.pointer
728
+ if dialog.pointer < 0
729
+ dialog.scroll_top = 0
730
+ elsif (dialog.pointer - dialog.scroll_top) >= (height - 1)
731
+ dialog.scroll_top = dialog.pointer - (height - 1)
732
+ elsif (dialog.pointer - dialog.scroll_top) < 0
733
+ dialog.scroll_top = dialog.pointer
734
+ end
735
+ pointer = dialog.pointer - dialog.scroll_top
736
+ else
737
+ dialog.scroll_top = 0
738
+ end
739
+ contents = contents[dialog.scroll_top, height]
740
+ end
741
+ if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
742
+ bar_max_height = height * 2
743
+ moving_distance = (dialog_render_info.contents.size - height) * 2
744
+ position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
745
+ bar_height = (bar_max_height * ((contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
746
+ bar_height = MINIMUM_SCROLLBAR_HEIGHT if bar_height < MINIMUM_SCROLLBAR_HEIGHT
747
+ scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i
748
+ else
749
+ scrollbar_pos = nil
750
+ end
751
+ dialog.column = dialog_render_info.pos.x
752
+ dialog.width += @block_elem_width if scrollbar_pos
753
+ diff = (dialog.column + dialog.width) - screen_width
754
+ if diff > 0
755
+ dialog.column -= diff
756
+ end
757
+ if rest_height(screen_scroll_top + cursor_row) - dialog_render_info.pos.y >= height
758
+ dialog.vertical_offset = dialog_render_info.pos.y + 1
759
+ elsif cursor_row >= height
760
+ dialog.vertical_offset = dialog_render_info.pos.y - height
761
+ else
762
+ dialog.vertical_offset = dialog_render_info.pos.y + 1
763
+ end
764
+ if dialog.column < 0
765
+ dialog.column = 0
766
+ dialog.width = screen_width
767
+ end
768
+ face = Reline::Face[dialog_render_info.face || :default]
769
+ scrollbar_sgr = face[:scrollbar]
770
+ default_sgr = face[:default]
771
+ enhanced_sgr = face[:enhanced]
772
+ dialog.contents = contents.map.with_index do |item, i|
773
+ line_sgr = i == pointer ? enhanced_sgr : default_sgr
774
+ str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width)
775
+ str, = Reline::Unicode.take_mbchar_range(item, 0, str_width, padding: true)
776
+ colored_content = "#{line_sgr}#{str}"
777
+ if scrollbar_pos
778
+ if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height)
779
+ colored_content + scrollbar_sgr + @full_block
780
+ elsif scrollbar_pos <= (i * 2) and (i * 2) < (scrollbar_pos + bar_height)
781
+ colored_content + scrollbar_sgr + @upper_half_block
782
+ elsif scrollbar_pos <= (i * 2 + 1) and (i * 2) < (scrollbar_pos + bar_height)
783
+ colored_content + scrollbar_sgr + @lower_half_block
784
+ else
785
+ colored_content + scrollbar_sgr + ' ' * @block_elem_width
786
+ end
787
+ else
788
+ colored_content
789
+ end
790
+ end
791
+ end
792
+
793
+ private def modify_lines(before, complete)
794
+ if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: complete)
795
+ after.lines("\n").map { |l| l.chomp('') }
796
+ else
797
+ before.map { |l| Reline::Unicode.escape_for_print(l) }
798
+ end
799
+ end
800
+
801
+ def editing_mode
802
+ @config.editing_mode
803
+ end
804
+
805
+ private def menu(list)
806
+ @menu_info = MenuInfo.new(list)
807
+ end
808
+
809
+ private def filter_normalize_candidates(target, list)
810
+ target = target.downcase if @config.completion_ignore_case
811
+ list.select do |item|
812
+ next unless item
813
+ unless Encoding.compatible?(target.encoding, item.encoding)
814
+ # Workaround for Readline test
815
+ if defined?(::Readline) && ::Readline == ::Reline
816
+ raise Encoding::CompatibilityError, "incompatible character encodings: #{target.encoding} and #{item.encoding}"
817
+ end
818
+ end
819
+
820
+ if @config.completion_ignore_case
821
+ item.downcase.start_with?(target)
822
+ else
823
+ item.start_with?(target)
824
+ end
825
+ end.map do |item|
826
+ item.unicode_normalize
827
+ rescue Encoding::CompatibilityError
828
+ item
829
+ end.uniq
830
+ end
831
+
832
+ private def perform_completion(preposing, target, postposing, quote, list)
833
+ candidates = filter_normalize_candidates(target, list)
834
+
835
+ case @completion_state
836
+ when CompletionState::PERFECT_MATCH
837
+ if @dig_perfect_match_proc
838
+ @dig_perfect_match_proc.call(@perfect_matched)
839
+ return
840
+ end
841
+ when CompletionState::MENU
842
+ menu(candidates)
843
+ return
844
+ when CompletionState::MENU_WITH_PERFECT_MATCH
845
+ menu(candidates)
846
+ @completion_state = CompletionState::PERFECT_MATCH
847
+ return
848
+ end
849
+
850
+ completed = Reline::Unicode.common_prefix(candidates, ignore_case: @config.completion_ignore_case)
851
+ return if completed.empty?
852
+
853
+ append_character = ''
854
+ if candidates.include?(completed)
855
+ if candidates.one?
856
+ append_character = quote || completion_append_character.to_s
857
+ @completion_state = CompletionState::PERFECT_MATCH
858
+ elsif @config.show_all_if_ambiguous
859
+ menu(candidates)
860
+ @completion_state = CompletionState::PERFECT_MATCH
861
+ else
862
+ @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
863
+ end
864
+ @perfect_matched = completed
865
+ else
866
+ @completion_state = CompletionState::MENU
867
+ menu(candidates) if @config.show_all_if_ambiguous
868
+ end
869
+ @buffer_of_lines[@line_index] = (preposing + completed + append_character + postposing).split("\n")[@line_index] || String.new(encoding: encoding)
870
+ line_to_pointer = (preposing + completed + append_character).split("\n")[@line_index] || String.new(encoding: encoding)
871
+ @byte_pointer = line_to_pointer.bytesize
872
+ end
873
+
874
+ def dialog_proc_scope_completion_journey_data
875
+ return nil unless @completion_journey_state
876
+ line_index = @completion_journey_state.line_index
877
+ pre_lines = @buffer_of_lines[0...line_index].map { |line| line + "\n" }
878
+ post_lines = @buffer_of_lines[(line_index + 1)..-1].map { |line| line + "\n" }
879
+ DialogProcScope::CompletionJourneyData.new(
880
+ pre_lines.join + @completion_journey_state.pre,
881
+ @completion_journey_state.post + post_lines.join,
882
+ @completion_journey_state.list,
883
+ @completion_journey_state.pointer
884
+ )
885
+ end
886
+
887
+ private def move_completed_list(direction)
888
+ @completion_journey_state ||= retrieve_completion_journey_state
889
+ return false unless @completion_journey_state
890
+
891
+ if (delta = { up: -1, down: +1 }[direction])
892
+ @completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size
893
+ end
894
+ completed = @completion_journey_state.list[@completion_journey_state.pointer]
895
+ set_current_line(@completion_journey_state.pre + completed + @completion_journey_state.post, @completion_journey_state.pre.bytesize + completed.bytesize)
896
+ true
897
+ end
898
+
899
+ private def retrieve_completion_journey_state
900
+ preposing, target, postposing, quote = retrieve_completion_block
901
+ list = call_completion_proc(preposing, target, postposing, quote)
902
+ return unless list.is_a?(Array)
903
+
904
+ candidates = list.select{ |item| item.start_with?(target) }
905
+ return if candidates.empty?
906
+
907
+ pre = preposing.split("\n", -1).last || ''
908
+ post = postposing.split("\n", -1).first || ''
909
+ CompletionJourneyState.new(
910
+ @line_index, pre, target, post, [target] + candidates, 0
911
+ )
912
+ end
913
+
914
+ private def run_for_operators(key, method_symbol, &block)
915
+ if @vi_waiting_operator
916
+ if VI_MOTIONS.include?(method_symbol)
917
+ old_byte_pointer = @byte_pointer
918
+ @vi_arg = (@vi_arg || 1) * @vi_waiting_operator_arg
919
+ block.(true)
920
+ unless @waiting_proc
921
+ byte_pointer_diff = @byte_pointer - old_byte_pointer
922
+ @byte_pointer = old_byte_pointer
923
+ method_obj = method(@vi_waiting_operator)
924
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
925
+ cleanup_waiting
926
+ end
927
+ else
928
+ # Ignores operator when not motion is given.
929
+ block.(false)
930
+ cleanup_waiting
931
+ end
932
+ @vi_arg = nil
933
+ else
934
+ block.(false)
935
+ end
936
+ end
937
+
938
+ private def argumentable?(method_obj)
939
+ method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :arg }
940
+ end
941
+
942
+ private def inclusive?(method_obj)
943
+ # If a motion method with the keyword argument "inclusive" follows the
944
+ # operator, it must contain the character at the cursor position.
945
+ method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :inclusive }
946
+ end
947
+
948
+ def wrap_method_call(method_symbol, method_obj, key, with_operator = false)
949
+ if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil?
950
+ not_insertion = method_symbol != :ed_insert
951
+ process_insert(force: not_insertion)
952
+ end
953
+ if @vi_arg and argumentable?(method_obj)
954
+ if with_operator and inclusive?(method_obj)
955
+ method_obj.(key, arg: @vi_arg, inclusive: true)
956
+ else
957
+ method_obj.(key, arg: @vi_arg)
958
+ end
959
+ else
960
+ if with_operator and inclusive?(method_obj)
961
+ method_obj.(key, inclusive: true)
962
+ else
963
+ method_obj.(key)
964
+ end
965
+ end
966
+ end
967
+
968
+ private def cleanup_waiting
969
+ @waiting_proc = nil
970
+ @vi_waiting_operator = nil
971
+ @vi_waiting_operator_arg = nil
972
+ @searching_prompt = nil
973
+ @drop_terminate_spaces = false
974
+ end
975
+
976
+ ARGUMENT_DIGIT_METHODS = %i[ed_digit vi_zero ed_argument_digit]
977
+ VI_WAITING_ACCEPT_METHODS = %i[vi_change_meta vi_delete_meta vi_yank ed_insert ed_argument_digit]
978
+
979
+ private def process_key(key, method_symbol)
980
+ if @waiting_proc
981
+ cleanup_waiting unless key.size == 1
982
+ end
983
+ if @vi_waiting_operator
984
+ cleanup_waiting unless VI_WAITING_ACCEPT_METHODS.include?(method_symbol) || VI_MOTIONS.include?(method_symbol)
985
+ end
986
+
987
+ if @waiting_proc
988
+ old_byte_pointer = @byte_pointer
989
+ @waiting_proc.call(key)
990
+ if @vi_waiting_operator
991
+ byte_pointer_diff = @byte_pointer - old_byte_pointer
992
+ @byte_pointer = old_byte_pointer
993
+ method_obj = method(@vi_waiting_operator)
994
+ wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
995
+ cleanup_waiting
996
+ end
997
+ @kill_ring.process
998
+ return
999
+ end
1000
+
1001
+ # Reject multibyte input (converted to ed_insert) in vi_command mode
1002
+ return if method_symbol == :ed_insert && @config.editing_mode_is?(:vi_command)
1003
+
1004
+ if method_symbol and respond_to?(method_symbol, true)
1005
+ method_obj = method(method_symbol)
1006
+ end
1007
+ if @vi_arg
1008
+ if ARGUMENT_DIGIT_METHODS.include?(method_symbol)
1009
+ ed_argument_digit(key)
1010
+ else
1011
+ if argumentable?(method_obj)
1012
+ run_for_operators(key, method_symbol) do |with_operator|
1013
+ wrap_method_call(method_symbol, method_obj, key, with_operator)
1014
+ end
1015
+ elsif method_obj
1016
+ wrap_method_call(method_symbol, method_obj, key)
1017
+ end
1018
+ @kill_ring.process
1019
+ @vi_arg = nil
1020
+ end
1021
+ elsif method_obj
1022
+ if method_symbol == :ed_argument_digit
1023
+ wrap_method_call(method_symbol, method_obj, key)
1024
+ else
1025
+ run_for_operators(key, method_symbol) do |with_operator|
1026
+ wrap_method_call(method_symbol, method_obj, key, with_operator)
1027
+ end
1028
+ end
1029
+ @kill_ring.process
1030
+ end
1031
+ end
1032
+
1033
+ def update(key)
1034
+ modified = input_key(key)
1035
+ unless @in_pasting
1036
+ scroll_into_view
1037
+ @just_cursor_moving = !modified
1038
+ update_dialogs(key)
1039
+ @just_cursor_moving = false
1040
+ end
1041
+ end
1042
+
1043
+ def input_key(key)
1044
+ save_old_buffer
1045
+ @config.reset_oneshot_key_bindings
1046
+ if key.char.nil?
1047
+ process_insert(force: true)
1048
+ @eof = buffer_empty?
1049
+ finish
1050
+ return
1051
+ end
1052
+ @dialogs.each do |dialog|
1053
+ if key.method_symbol == dialog.name
1054
+ return
1055
+ end
1056
+ end
1057
+ @completion_occurs = false
1058
+
1059
+ process_key(key.char, key.method_symbol)
1060
+ if @config.editing_mode_is?(:vi_command) and @byte_pointer > 0 and @byte_pointer == current_line.bytesize
1061
+ byte_size = Reline::Unicode.get_prev_mbchar_size(@buffer_of_lines[@line_index], @byte_pointer)
1062
+ @byte_pointer -= byte_size
1063
+ end
1064
+
1065
+ @prev_action_state, @next_action_state = @next_action_state, NullActionState
1066
+
1067
+ unless @completion_occurs
1068
+ @completion_state = CompletionState::NORMAL
1069
+ @completion_journey_state = nil
1070
+ end
1071
+
1072
+ push_input_lines unless @restoring
1073
+ @restoring = false
1074
+
1075
+ if @in_pasting
1076
+ clear_dialogs
1077
+ return
1078
+ end
1079
+
1080
+ modified = @old_buffer_of_lines != @buffer_of_lines
1081
+ if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
1082
+ # Auto complete starts only when edited
1083
+ process_insert(force: true)
1084
+ @completion_journey_state = retrieve_completion_journey_state
1085
+ end
1086
+ modified
1087
+ end
1088
+
1089
+ def save_old_buffer
1090
+ @old_buffer_of_lines = @buffer_of_lines.dup
1091
+ end
1092
+
1093
+ def push_input_lines
1094
+ if @old_buffer_of_lines == @buffer_of_lines
1095
+ @input_lines[@input_lines_position] = [@buffer_of_lines.dup, @byte_pointer, @line_index]
1096
+ else
1097
+ @input_lines = @input_lines[0..@input_lines_position]
1098
+ @input_lines_position += 1
1099
+ @input_lines.push([@buffer_of_lines.dup, @byte_pointer, @line_index])
1100
+ end
1101
+ trim_input_lines
1102
+ end
1103
+
1104
+ MAX_INPUT_LINES = 100
1105
+ def trim_input_lines
1106
+ if @input_lines.size > MAX_INPUT_LINES
1107
+ @input_lines.shift
1108
+ @input_lines_position -= 1
1109
+ end
1110
+ end
1111
+
1112
+ def scroll_into_view
1113
+ _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
1114
+ if wrapped_cursor_y < screen_scroll_top
1115
+ @scroll_partial_screen = wrapped_cursor_y
1116
+ end
1117
+ if wrapped_cursor_y >= screen_scroll_top + screen_height
1118
+ @scroll_partial_screen = wrapped_cursor_y - screen_height + 1
1119
+ end
1120
+ end
1121
+
1122
+ def call_completion_proc(pre, target, post, quote)
1123
+ Reline.core.instance_variable_set(:@completion_quote_character, quote)
1124
+ result = call_completion_proc_with_checking_args(pre, target, post)
1125
+ Reline.core.instance_variable_set(:@completion_quote_character, nil)
1126
+ result
1127
+ end
1128
+
1129
+ def call_completion_proc_with_checking_args(pre, target, post)
1130
+ if @completion_proc and target
1131
+ argnum = @completion_proc.parameters.inject(0) { |result, item|
1132
+ case item.first
1133
+ when :req, :opt
1134
+ result + 1
1135
+ when :rest
1136
+ break 3
1137
+ end
1138
+ }
1139
+ case argnum
1140
+ when 1
1141
+ result = @completion_proc.(target)
1142
+ when 2
1143
+ result = @completion_proc.(target, pre)
1144
+ when 3..Float::INFINITY
1145
+ result = @completion_proc.(target, pre, post)
1146
+ end
1147
+ end
1148
+ result
1149
+ end
1150
+
1151
+ private def process_auto_indent(line_index = @line_index, cursor_dependent: true, add_newline: false)
1152
+ return if @in_pasting
1153
+ return unless @auto_indent_proc
1154
+
1155
+ line = @buffer_of_lines[line_index]
1156
+ byte_pointer = cursor_dependent && @line_index == line_index ? @byte_pointer : line.bytesize
1157
+ new_indent = @auto_indent_proc.(@buffer_of_lines.take(line_index + 1).push(''), line_index, byte_pointer, add_newline)
1158
+ return unless new_indent
1159
+
1160
+ new_line = ' ' * new_indent + line.lstrip
1161
+ @buffer_of_lines[line_index] = new_line
1162
+ if @line_index == line_index
1163
+ indent_diff = new_line.bytesize - line.bytesize
1164
+ @byte_pointer = [@byte_pointer + indent_diff, 0].max
1165
+ end
1166
+ end
1167
+
1168
+ def line()
1169
+ @buffer_of_lines.join("\n") unless eof?
1170
+ end
1171
+
1172
+ def current_line
1173
+ @buffer_of_lines[@line_index]
1174
+ end
1175
+
1176
+ def set_current_line(line, byte_pointer = nil)
1177
+ cursor = current_byte_pointer_cursor
1178
+ @buffer_of_lines[@line_index] = line
1179
+ if byte_pointer
1180
+ @byte_pointer = byte_pointer
1181
+ else
1182
+ calculate_nearest_cursor(cursor)
1183
+ end
1184
+ process_auto_indent
1185
+ end
1186
+
1187
+ def retrieve_completion_block
1188
+ quote_characters = Reline.completer_quote_characters
1189
+ before = current_line.byteslice(0, @byte_pointer).grapheme_clusters
1190
+ quote = nil
1191
+ # Calcualte closing quote when cursor is at the end of the line
1192
+ if current_line.bytesize == @byte_pointer && !quote_characters.empty?
1193
+ escaped = false
1194
+ before.each do |c|
1195
+ if escaped
1196
+ escaped = false
1197
+ next
1198
+ elsif c == '\\'
1199
+ escaped = true
1200
+ elsif quote
1201
+ quote = nil if c == quote
1202
+ elsif quote_characters.include?(c)
1203
+ quote = c
1204
+ end
1205
+ end
1206
+ end
1207
+
1208
+ word_break_characters = quote_characters + Reline.completer_word_break_characters
1209
+ break_index = before.rindex { |c| word_break_characters.include?(c) || quote_characters.include?(c) } || -1
1210
+ preposing = before.take(break_index + 1).join
1211
+ target = before.drop(break_index + 1).join
1212
+ postposing = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
1213
+ lines = whole_lines
1214
+ if @line_index > 0
1215
+ preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
1216
+ end
1217
+ if (lines.size - 1) > @line_index
1218
+ postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
1219
+ end
1220
+ [preposing.encode(encoding), target.encode(encoding), postposing.encode(encoding), quote&.encode(encoding)]
1221
+ end
1222
+
1223
+ def confirm_multiline_termination
1224
+ temp_buffer = @buffer_of_lines.dup
1225
+ @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
1226
+ end
1227
+
1228
+ def insert_multiline_text(text)
1229
+ pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
1230
+ post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
1231
+ lines = (pre + Reline::Unicode.safe_encode(text, encoding).gsub(/\r\n?/, "\n") + post).split("\n", -1)
1232
+ lines << '' if lines.empty?
1233
+ @buffer_of_lines[@line_index, 1] = lines
1234
+ @line_index += lines.size - 1
1235
+ @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
1236
+ end
1237
+
1238
+ def insert_text(text)
1239
+ if @buffer_of_lines[@line_index].bytesize == @byte_pointer
1240
+ @buffer_of_lines[@line_index] += text
1241
+ else
1242
+ @buffer_of_lines[@line_index] = byteinsert(@buffer_of_lines[@line_index], @byte_pointer, text)
1243
+ end
1244
+ @byte_pointer += text.bytesize
1245
+ process_auto_indent
1246
+ end
1247
+
1248
+ def delete_text(start = nil, length = nil)
1249
+ if start.nil? and length.nil?
1250
+ if @buffer_of_lines.size == 1
1251
+ @buffer_of_lines[@line_index] = ''
1252
+ @byte_pointer = 0
1253
+ elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0
1254
+ @buffer_of_lines.pop
1255
+ @line_index -= 1
1256
+ @byte_pointer = 0
1257
+ elsif @line_index < (@buffer_of_lines.size - 1)
1258
+ @buffer_of_lines.delete_at(@line_index)
1259
+ @byte_pointer = 0
1260
+ end
1261
+ elsif not start.nil? and not length.nil?
1262
+ if current_line
1263
+ before = current_line.byteslice(0, start)
1264
+ after = current_line.byteslice(start + length, current_line.bytesize)
1265
+ set_current_line(before + after)
1266
+ end
1267
+ elsif start.is_a?(Range)
1268
+ range = start
1269
+ first = range.first
1270
+ last = range.last
1271
+ last = current_line.bytesize - 1 if last > current_line.bytesize
1272
+ last += current_line.bytesize if last < 0
1273
+ first += current_line.bytesize if first < 0
1274
+ range = range.exclude_end? ? first...last : first..last
1275
+ line = current_line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(encoding)
1276
+ set_current_line(line)
1277
+ else
1278
+ set_current_line(current_line.byteslice(0, start))
1279
+ end
1280
+ end
1281
+
1282
+ def byte_pointer=(val)
1283
+ @byte_pointer = val
1284
+ end
1285
+
1286
+ def whole_lines
1287
+ @buffer_of_lines.dup
1288
+ end
1289
+
1290
+ def whole_buffer
1291
+ whole_lines.join("\n")
1292
+ end
1293
+
1294
+ private def buffer_empty?
1295
+ current_line.empty? and @buffer_of_lines.size == 1
1296
+ end
1297
+
1298
+ def finished?
1299
+ @finished
1300
+ end
1301
+
1302
+ def finish
1303
+ @finished = true
1304
+ @config.reset
1305
+ end
1306
+
1307
+ private def byteslice!(str, byte_pointer, size)
1308
+ new_str = str.byteslice(0, byte_pointer)
1309
+ new_str << str.byteslice(byte_pointer + size, str.bytesize)
1310
+ [new_str, str.byteslice(byte_pointer, size)]
1311
+ end
1312
+
1313
+ private def byteinsert(str, byte_pointer, other)
1314
+ new_str = str.byteslice(0, byte_pointer)
1315
+ new_str << other
1316
+ new_str << str.byteslice(byte_pointer, str.bytesize)
1317
+ new_str
1318
+ end
1319
+
1320
+ private def calculate_width(str, allow_escape_code = false)
1321
+ Reline::Unicode.calculate_width(str, allow_escape_code)
1322
+ end
1323
+
1324
+ private def key_delete(key)
1325
+ if @config.editing_mode_is?(:vi_insert)
1326
+ ed_delete_next_char(key)
1327
+ elsif @config.editing_mode_is?(:emacs)
1328
+ em_delete(key)
1329
+ end
1330
+ end
1331
+
1332
+ private def key_newline(key)
1333
+ if @is_multiline
1334
+ next_line = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
1335
+ cursor_line = current_line.byteslice(0, @byte_pointer)
1336
+ insert_new_line(cursor_line, next_line)
1337
+ end
1338
+ end
1339
+
1340
+ private def complete(_key)
1341
+ return if @config.disable_completion
1342
+
1343
+ process_insert(force: true)
1344
+ if @config.autocompletion
1345
+ @completion_state = CompletionState::NORMAL
1346
+ @completion_occurs = move_completed_list(:down)
1347
+ else
1348
+ @completion_journey_state = nil
1349
+ pre, target, post, quote = retrieve_completion_block
1350
+ result = call_completion_proc(pre, target, post, quote)
1351
+ if result.is_a?(Array)
1352
+ @completion_occurs = true
1353
+ perform_completion(pre, target, post, quote, result)
1354
+ end
1355
+ end
1356
+ end
1357
+
1358
+ private def completion_journey_move(direction)
1359
+ return if @config.disable_completion
1360
+
1361
+ process_insert(force: true)
1362
+ @completion_state = CompletionState::NORMAL
1363
+ @completion_occurs = move_completed_list(direction)
1364
+ end
1365
+
1366
+ private def menu_complete(_key)
1367
+ completion_journey_move(:down)
1368
+ end
1369
+
1370
+ private def menu_complete_backward(_key)
1371
+ completion_journey_move(:up)
1372
+ end
1373
+
1374
+ private def completion_journey_up(_key)
1375
+ completion_journey_move(:up) if @config.autocompletion
1376
+ end
1377
+
1378
+ # Editline:: +ed-unassigned+ This editor command always results in an error.
1379
+ # GNU Readline:: There is no corresponding macro.
1380
+ private def ed_unassigned(key) end # do nothing
1381
+
1382
+ private def process_insert(force: false)
1383
+ return if @continuous_insertion_buffer.empty? or (@in_pasting and not force)
1384
+ insert_text(@continuous_insertion_buffer)
1385
+ @continuous_insertion_buffer.clear
1386
+ end
1387
+
1388
+ # Editline:: +ed-insert+ (vi input: almost all; emacs: printable characters)
1389
+ # In insert mode, insert the input character left of the cursor
1390
+ # position. In replace mode, overwrite the character at the
1391
+ # cursor and move the cursor to the right by one character
1392
+ # position. Accept an argument to do this repeatedly. It is an
1393
+ # error if the input character is the NUL character (+Ctrl-@+).
1394
+ # Failure to enlarge the edit buffer also results in an error.
1395
+ # Editline:: +ed-digit+ (emacs: 0 to 9) If in argument input mode, append
1396
+ # the input digit to the argument being read. Otherwise, call
1397
+ # +ed-insert+. It is an error if the input character is not a
1398
+ # digit or if the existing argument is already greater than a
1399
+ # million.
1400
+ # GNU Readline:: +self-insert+ (a, b, A, 1, !, …) Insert yourself.
1401
+ private def ed_insert(str)
1402
+ begin
1403
+ str.encode(Encoding::UTF_8)
1404
+ rescue Encoding::UndefinedConversionError
1405
+ return
1406
+ end
1407
+ if @in_pasting
1408
+ @continuous_insertion_buffer << str
1409
+ return
1410
+ elsif not @continuous_insertion_buffer.empty?
1411
+ process_insert
1412
+ end
1413
+
1414
+ insert_text(str)
1415
+ end
1416
+ alias_method :ed_digit, :ed_insert
1417
+ alias_method :self_insert, :ed_insert
1418
+
1419
+ private def insert_raw_char(str, arg: 1)
1420
+ arg.times do
1421
+ if str == "\C-j" or str == "\C-m"
1422
+ key_newline(str)
1423
+ elsif str != "\0"
1424
+ # Ignore NUL.
1425
+ ed_insert(str)
1426
+ end
1427
+ end
1428
+ end
1429
+
1430
+ private def ed_next_char(key, arg: 1)
1431
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
1432
+ if (@byte_pointer < current_line.bytesize)
1433
+ @byte_pointer += byte_size
1434
+ elsif @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1
1435
+ @byte_pointer = 0
1436
+ @line_index += 1
1437
+ end
1438
+ arg -= 1
1439
+ ed_next_char(key, arg: arg) if arg > 0
1440
+ end
1441
+ alias_method :forward_char, :ed_next_char
1442
+
1443
+ private def ed_prev_char(key, arg: 1)
1444
+ if @byte_pointer > 0
1445
+ byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
1446
+ @byte_pointer -= byte_size
1447
+ elsif @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0
1448
+ @line_index -= 1
1449
+ @byte_pointer = current_line.bytesize
1450
+ end
1451
+ arg -= 1
1452
+ ed_prev_char(key, arg: arg) if arg > 0
1453
+ end
1454
+ alias_method :backward_char, :ed_prev_char
1455
+
1456
+ private def vi_first_print(key)
1457
+ @byte_pointer = Reline::Unicode.vi_first_print(current_line)
1458
+ end
1459
+
1460
+ private def ed_move_to_beg(key)
1461
+ @byte_pointer = 0
1462
+ end
1463
+ alias_method :beginning_of_line, :ed_move_to_beg
1464
+ alias_method :vi_zero, :ed_move_to_beg
1465
+
1466
+ private def ed_move_to_end(key)
1467
+ @byte_pointer = current_line.bytesize
1468
+ end
1469
+ alias_method :end_of_line, :ed_move_to_end
1470
+
1471
+ private def generate_searcher(search_key)
1472
+ search_word = String.new(encoding: encoding)
1473
+ hit_pointer = nil
1474
+ lambda do |key|
1475
+ search_again = false
1476
+ case key
1477
+ when "\C-h", "\C-?"
1478
+ grapheme_clusters = search_word.grapheme_clusters
1479
+ if grapheme_clusters.size > 0
1480
+ grapheme_clusters.pop
1481
+ search_word = grapheme_clusters.join
1482
+ end
1483
+ when "\C-r", "\C-s"
1484
+ search_again = true if search_key == key
1485
+ search_key = key
1486
+ else
1487
+ search_word << key
1488
+ end
1489
+ hit = nil
1490
+ if not search_word.empty? and @line_backup_in_history&.include?(search_word)
1491
+ hit_pointer = Reline::HISTORY.size
1492
+ hit = @line_backup_in_history
1493
+ else
1494
+ if search_again
1495
+ if search_word.empty? and Reline.last_incremental_search
1496
+ search_word = Reline.last_incremental_search
1497
+ end
1498
+ if @history_pointer
1499
+ case search_key
1500
+ when "\C-r"
1501
+ history_pointer_base = 0
1502
+ history = Reline::HISTORY[0..(@history_pointer - 1)]
1503
+ when "\C-s"
1504
+ history_pointer_base = @history_pointer + 1
1505
+ history = Reline::HISTORY[(@history_pointer + 1)..-1]
1506
+ end
1507
+ else
1508
+ history_pointer_base = 0
1509
+ history = Reline::HISTORY
1510
+ end
1511
+ elsif @history_pointer
1512
+ case search_key
1513
+ when "\C-r"
1514
+ history_pointer_base = 0
1515
+ history = Reline::HISTORY[0..@history_pointer]
1516
+ when "\C-s"
1517
+ history_pointer_base = @history_pointer
1518
+ history = Reline::HISTORY[@history_pointer..-1]
1519
+ end
1520
+ else
1521
+ history_pointer_base = 0
1522
+ history = Reline::HISTORY
1523
+ end
1524
+ case search_key
1525
+ when "\C-r"
1526
+ hit_index = history.rindex { |item|
1527
+ item.include?(search_word)
1528
+ }
1529
+ when "\C-s"
1530
+ hit_index = history.index { |item|
1531
+ item.include?(search_word)
1532
+ }
1533
+ end
1534
+ if hit_index
1535
+ hit_pointer = history_pointer_base + hit_index
1536
+ hit = Reline::HISTORY[hit_pointer]
1537
+ end
1538
+ end
1539
+ case search_key
1540
+ when "\C-r"
1541
+ prompt_name = 'reverse-i-search'
1542
+ when "\C-s"
1543
+ prompt_name = 'i-search'
1544
+ end
1545
+ prompt_name = "failed #{prompt_name}" unless hit
1546
+ [search_word, prompt_name, hit_pointer]
1547
+ end
1548
+ end
1549
+
1550
+ private def incremental_search_history(key)
1551
+ backup = @buffer_of_lines.dup, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history
1552
+ searcher = generate_searcher(key)
1553
+ @searching_prompt = "(reverse-i-search)`': "
1554
+ termination_keys = ["\C-j"]
1555
+ termination_keys.concat(@config.isearch_terminators.chars) if @config.isearch_terminators
1556
+ @waiting_proc = ->(k) {
1557
+ if k == "\C-g"
1558
+ # cancel search and restore buffer
1559
+ @buffer_of_lines, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history = backup
1560
+ @searching_prompt = nil
1561
+ @waiting_proc = nil
1562
+ elsif !termination_keys.include?(k) && (k.match?(/[[:print:]]/) || k == "\C-h" || k == "\C-?" || k == "\C-r" || k == "\C-s")
1563
+ search_word, prompt_name, hit_pointer = searcher.call(k)
1564
+ Reline.last_incremental_search = search_word
1565
+ @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
1566
+ @searching_prompt += ': ' unless @is_multiline
1567
+ move_history(hit_pointer, line: :end, cursor: :end) if hit_pointer
1568
+ else
1569
+ # terminaton_keys and other keys will terminalte
1570
+ move_history(@history_pointer, line: :end, cursor: :start)
1571
+ @searching_prompt = nil
1572
+ @waiting_proc = nil
1573
+ end
1574
+ }
1575
+ end
1576
+
1577
+ private def vi_search_prev(key)
1578
+ incremental_search_history(key)
1579
+ end
1580
+ alias_method :reverse_search_history, :vi_search_prev
1581
+
1582
+ private def vi_search_next(key)
1583
+ incremental_search_history(key)
1584
+ end
1585
+ alias_method :forward_search_history, :vi_search_next
1586
+
1587
+ private def search_history(prefix, pointer_range)
1588
+ pointer_range.each do |pointer|
1589
+ lines = Reline::HISTORY[pointer].split("\n")
1590
+ lines.each_with_index do |line, index|
1591
+ return [pointer, index] if line.start_with?(prefix)
1592
+ end
1593
+ end
1594
+ nil
1595
+ end
1596
+
1597
+ private def ed_search_prev_history(key, arg: 1)
1598
+ substr = prev_action_state_value(:search_history) == :empty ? '' : current_line.byteslice(0, @byte_pointer)
1599
+ return if @history_pointer == 0
1600
+ return if @history_pointer.nil? && substr.empty? && !current_line.empty?
1601
+
1602
+ history_range = 0...(@history_pointer || Reline::HISTORY.size)
1603
+ h_pointer, line_index = search_history(substr, history_range.reverse_each)
1604
+ return unless h_pointer
1605
+ move_history(h_pointer, line: line_index || :start, cursor: substr.empty? ? :end : @byte_pointer)
1606
+ arg -= 1
1607
+ set_next_action_state(:search_history, :empty) if substr.empty?
1608
+ ed_search_prev_history(key, arg: arg) if arg > 0
1609
+ end
1610
+ alias_method :history_search_backward, :ed_search_prev_history
1611
+
1612
+ private def ed_search_next_history(key, arg: 1)
1613
+ substr = prev_action_state_value(:search_history) == :empty ? '' : current_line.byteslice(0, @byte_pointer)
1614
+ return if @history_pointer.nil?
1615
+
1616
+ history_range = @history_pointer + 1...Reline::HISTORY.size
1617
+ h_pointer, line_index = search_history(substr, history_range)
1618
+ return if h_pointer.nil? and not substr.empty?
1619
+
1620
+ move_history(h_pointer, line: line_index || :start, cursor: substr.empty? ? :end : @byte_pointer)
1621
+ arg -= 1
1622
+ set_next_action_state(:search_history, :empty) if substr.empty?
1623
+ ed_search_next_history(key, arg: arg) if arg > 0
1624
+ end
1625
+ alias_method :history_search_forward, :ed_search_next_history
1626
+
1627
+ private def move_history(history_pointer, line:, cursor:)
1628
+ history_pointer ||= Reline::HISTORY.size
1629
+ return if history_pointer < 0 || history_pointer > Reline::HISTORY.size
1630
+ old_history_pointer = @history_pointer || Reline::HISTORY.size
1631
+ if old_history_pointer == Reline::HISTORY.size
1632
+ @line_backup_in_history = whole_buffer
1633
+ else
1634
+ Reline::HISTORY[old_history_pointer] = whole_buffer
1635
+ end
1636
+ if history_pointer == Reline::HISTORY.size
1637
+ buf = @line_backup_in_history
1638
+ @history_pointer = @line_backup_in_history = nil
1639
+ else
1640
+ buf = Reline::HISTORY[history_pointer]
1641
+ @history_pointer = history_pointer
1642
+ end
1643
+ @buffer_of_lines = buf.split("\n")
1644
+ @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty?
1645
+ @line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line
1646
+ @byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor
1647
+ end
1648
+
1649
+ private def ed_prev_history(key, arg: 1)
1650
+ if @line_index > 0
1651
+ cursor = current_byte_pointer_cursor
1652
+ @line_index -= 1
1653
+ calculate_nearest_cursor(cursor)
1654
+ return
1655
+ end
1656
+ move_history(
1657
+ (@history_pointer || Reline::HISTORY.size) - 1,
1658
+ line: :end,
1659
+ cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
1660
+ )
1661
+ arg -= 1
1662
+ ed_prev_history(key, arg: arg) if arg > 0
1663
+ end
1664
+ alias_method :previous_history, :ed_prev_history
1665
+
1666
+ private def ed_next_history(key, arg: 1)
1667
+ if @line_index < (@buffer_of_lines.size - 1)
1668
+ cursor = current_byte_pointer_cursor
1669
+ @line_index += 1
1670
+ calculate_nearest_cursor(cursor)
1671
+ return
1672
+ end
1673
+ move_history(
1674
+ (@history_pointer || Reline::HISTORY.size) + 1,
1675
+ line: :start,
1676
+ cursor: @config.editing_mode_is?(:vi_command) ? :start : :end,
1677
+ )
1678
+ arg -= 1
1679
+ ed_next_history(key, arg: arg) if arg > 0
1680
+ end
1681
+ alias_method :next_history, :ed_next_history
1682
+
1683
+ private def ed_newline(key)
1684
+ process_insert(force: true)
1685
+ if @is_multiline
1686
+ if @config.editing_mode_is?(:vi_command)
1687
+ if @line_index < (@buffer_of_lines.size - 1)
1688
+ ed_next_history(key) # means cursor down
1689
+ else
1690
+ # should check confirm_multiline_termination to finish?
1691
+ finish
1692
+ end
1693
+ else
1694
+ if @line_index == (@buffer_of_lines.size - 1)
1695
+ if confirm_multiline_termination
1696
+ finish
1697
+ else
1698
+ key_newline(key)
1699
+ end
1700
+ else
1701
+ # should check confirm_multiline_termination to finish?
1702
+ @line_index = @buffer_of_lines.size - 1
1703
+ @byte_pointer = current_line.bytesize
1704
+ finish
1705
+ end
1706
+ end
1707
+ else
1708
+ finish
1709
+ end
1710
+ end
1711
+
1712
+ private def em_delete_prev_char(key, arg: 1)
1713
+ arg.times do
1714
+ if @byte_pointer == 0 and @line_index > 0
1715
+ @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
1716
+ @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
1717
+ @line_index -= 1
1718
+ elsif @byte_pointer > 0
1719
+ byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
1720
+ line, = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
1721
+ set_current_line(line, @byte_pointer - byte_size)
1722
+ end
1723
+ end
1724
+ process_auto_indent
1725
+ end
1726
+ alias_method :backward_delete_char, :em_delete_prev_char
1727
+
1728
+ # Editline:: +ed-kill-line+ (vi command: +D+, +Ctrl-K+; emacs: +Ctrl-K+,
1729
+ # +Ctrl-U+) + Kill from the cursor to the end of the line.
1730
+ # GNU Readline:: +kill-line+ (+C-k+) Kill the text from point to the end of
1731
+ # the line. With a negative numeric argument, kill backward
1732
+ # from the cursor to the beginning of the current line.
1733
+ private def ed_kill_line(key)
1734
+ if current_line.bytesize > @byte_pointer
1735
+ line, deleted = byteslice!(current_line, @byte_pointer, current_line.bytesize - @byte_pointer)
1736
+ set_current_line(line, line.bytesize)
1737
+ @kill_ring.append(deleted)
1738
+ elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
1739
+ set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
1740
+ end
1741
+ end
1742
+ alias_method :kill_line, :ed_kill_line
1743
+
1744
+ # Editline:: +vi_change_to_eol+ (vi command: +C+) + Kill and change from the cursor to the end of the line.
1745
+ private def vi_change_to_eol(key)
1746
+ ed_kill_line(key)
1747
+
1748
+ @config.editing_mode = :vi_insert
1749
+ end
1750
+
1751
+ # Editline:: +vi-kill-line-prev+ (vi: +Ctrl-U+) Delete the string from the
1752
+ # beginning of the edit buffer to the cursor and save it to the
1753
+ # cut buffer.
1754
+ # GNU Readline:: +unix-line-discard+ (+C-u+) Kill backward from the cursor
1755
+ # to the beginning of the current line.
1756
+ private def vi_kill_line_prev(key)
1757
+ if @byte_pointer > 0
1758
+ line, deleted = byteslice!(current_line, 0, @byte_pointer)
1759
+ set_current_line(line, 0)
1760
+ @kill_ring.append(deleted, true)
1761
+ end
1762
+ end
1763
+ alias_method :unix_line_discard, :vi_kill_line_prev
1764
+
1765
+ # Editline:: +em-kill-line+ (not bound) Delete the entire contents of the
1766
+ # edit buffer and save it to the cut buffer. +vi-kill-line-prev+
1767
+ # GNU Readline:: +kill-whole-line+ (not bound) Kill all characters on the
1768
+ # current line, no matter where point is.
1769
+ private def em_kill_line(key)
1770
+ if current_line.size > 0
1771
+ @kill_ring.append(current_line.dup, true)
1772
+ set_current_line('', 0)
1773
+ end
1774
+ end
1775
+ alias_method :kill_whole_line, :em_kill_line
1776
+
1777
+ private def em_delete(key)
1778
+ if buffer_empty? and key == "\C-d"
1779
+ @eof = true
1780
+ finish
1781
+ elsif @byte_pointer < current_line.bytesize
1782
+ splitted_last = current_line.byteslice(@byte_pointer, current_line.bytesize)
1783
+ mbchar = splitted_last.grapheme_clusters.first
1784
+ line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize)
1785
+ set_current_line(line)
1786
+ elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
1787
+ set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
1788
+ end
1789
+ end
1790
+ alias_method :delete_char, :em_delete
1791
+
1792
+ private def em_delete_or_list(key)
1793
+ if current_line.empty? or @byte_pointer < current_line.bytesize
1794
+ em_delete(key)
1795
+ elsif !@config.autocompletion # show completed list
1796
+ pre, target, post, quote = retrieve_completion_block
1797
+ result = call_completion_proc(pre, target, post, quote)
1798
+ if result.is_a?(Array)
1799
+ candidates = filter_normalize_candidates(target, result)
1800
+ menu(candidates)
1801
+ end
1802
+ end
1803
+ end
1804
+ alias_method :delete_char_or_list, :em_delete_or_list
1805
+
1806
+ private def em_yank(key)
1807
+ yanked = @kill_ring.yank
1808
+ insert_text(yanked) if yanked
1809
+ end
1810
+ alias_method :yank, :em_yank
1811
+
1812
+ private def em_yank_pop(key)
1813
+ yanked, prev_yank = @kill_ring.yank_pop
1814
+ if yanked
1815
+ line, = byteslice!(current_line, @byte_pointer - prev_yank.bytesize, prev_yank.bytesize)
1816
+ set_current_line(line, @byte_pointer - prev_yank.bytesize)
1817
+ insert_text(yanked)
1818
+ end
1819
+ end
1820
+ alias_method :yank_pop, :em_yank_pop
1821
+
1822
+ private def ed_clear_screen(key)
1823
+ Reline::IOGate.clear_screen
1824
+ @screen_size = Reline::IOGate.get_screen_size
1825
+ @rendered_screen.base_y = 0
1826
+ clear_rendered_screen_cache
1827
+ end
1828
+ alias_method :clear_screen, :ed_clear_screen
1829
+
1830
+ private def em_next_word(key)
1831
+ if current_line.bytesize > @byte_pointer
1832
+ byte_size = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
1833
+ @byte_pointer += byte_size
1834
+ end
1835
+ end
1836
+ alias_method :forward_word, :em_next_word
1837
+
1838
+ private def ed_prev_word(key)
1839
+ if @byte_pointer > 0
1840
+ byte_size = Reline::Unicode.em_backward_word(current_line, @byte_pointer)
1841
+ @byte_pointer -= byte_size
1842
+ end
1843
+ end
1844
+ alias_method :backward_word, :ed_prev_word
1845
+
1846
+ private def em_delete_next_word(key)
1847
+ if current_line.bytesize > @byte_pointer
1848
+ byte_size = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
1849
+ line, word = byteslice!(current_line, @byte_pointer, byte_size)
1850
+ set_current_line(line)
1851
+ @kill_ring.append(word)
1852
+ end
1853
+ end
1854
+ alias_method :kill_word, :em_delete_next_word
1855
+
1856
+ private def ed_delete_prev_word(key)
1857
+ if @byte_pointer > 0
1858
+ byte_size = Reline::Unicode.em_backward_word(current_line, @byte_pointer)
1859
+ line, word = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
1860
+ set_current_line(line, @byte_pointer - byte_size)
1861
+ @kill_ring.append(word, true)
1862
+ end
1863
+ end
1864
+ alias_method :backward_kill_word, :ed_delete_prev_word
1865
+
1866
+ private def ed_transpose_chars(key)
1867
+ if @byte_pointer > 0
1868
+ if @byte_pointer < current_line.bytesize
1869
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
1870
+ @byte_pointer += byte_size
1871
+ end
1872
+ back1_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
1873
+ if (@byte_pointer - back1_byte_size) > 0
1874
+ back2_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer - back1_byte_size)
1875
+ back2_pointer = @byte_pointer - back1_byte_size - back2_byte_size
1876
+ line, back2_mbchar = byteslice!(current_line, back2_pointer, back2_byte_size)
1877
+ set_current_line(byteinsert(line, @byte_pointer - back2_byte_size, back2_mbchar))
1878
+ end
1879
+ end
1880
+ end
1881
+ alias_method :transpose_chars, :ed_transpose_chars
1882
+
1883
+ private def ed_transpose_words(key)
1884
+ left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(current_line, @byte_pointer)
1885
+ before = current_line.byteslice(0, left_word_start)
1886
+ left_word = current_line.byteslice(left_word_start, middle_start - left_word_start)
1887
+ middle = current_line.byteslice(middle_start, right_word_start - middle_start)
1888
+ right_word = current_line.byteslice(right_word_start, after_start - right_word_start)
1889
+ after = current_line.byteslice(after_start, current_line.bytesize - after_start)
1890
+ return if left_word.empty? or right_word.empty?
1891
+ from_head_to_left_word = before + right_word + middle + left_word
1892
+ set_current_line(from_head_to_left_word + after, from_head_to_left_word.bytesize)
1893
+ end
1894
+ alias_method :transpose_words, :ed_transpose_words
1895
+
1896
+ private def em_capitol_case(key)
1897
+ if current_line.bytesize > @byte_pointer
1898
+ byte_size, new_str = Reline::Unicode.em_forward_word_with_capitalization(current_line, @byte_pointer)
1899
+ before = current_line.byteslice(0, @byte_pointer)
1900
+ after = current_line.byteslice((@byte_pointer + byte_size)..-1)
1901
+ set_current_line(before + new_str + after, @byte_pointer + new_str.bytesize)
1902
+ end
1903
+ end
1904
+ alias_method :capitalize_word, :em_capitol_case
1905
+
1906
+ private def em_lower_case(key)
1907
+ if current_line.bytesize > @byte_pointer
1908
+ byte_size = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
1909
+ part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
1910
+ mbchar =~ /[A-Z]/ ? mbchar.downcase : mbchar
1911
+ }.join
1912
+ rest = current_line.byteslice((@byte_pointer + byte_size)..-1)
1913
+ line = current_line.byteslice(0, @byte_pointer) + part
1914
+ set_current_line(line + rest, line.bytesize)
1915
+ end
1916
+ end
1917
+ alias_method :downcase_word, :em_lower_case
1918
+
1919
+ private def em_upper_case(key)
1920
+ if current_line.bytesize > @byte_pointer
1921
+ byte_size = Reline::Unicode.em_forward_word(current_line, @byte_pointer)
1922
+ part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar|
1923
+ mbchar =~ /[a-z]/ ? mbchar.upcase : mbchar
1924
+ }.join
1925
+ rest = current_line.byteslice((@byte_pointer + byte_size)..-1)
1926
+ line = current_line.byteslice(0, @byte_pointer) + part
1927
+ set_current_line(line + rest, line.bytesize)
1928
+ end
1929
+ end
1930
+ alias_method :upcase_word, :em_upper_case
1931
+
1932
+ private def em_kill_region(key)
1933
+ if @byte_pointer > 0
1934
+ byte_size = Reline::Unicode.em_big_backward_word(current_line, @byte_pointer)
1935
+ line, deleted = byteslice!(current_line, @byte_pointer - byte_size, byte_size)
1936
+ set_current_line(line, @byte_pointer - byte_size)
1937
+ @kill_ring.append(deleted, true)
1938
+ end
1939
+ end
1940
+ alias_method :unix_word_rubout, :em_kill_region
1941
+
1942
+ private def copy_for_vi(text)
1943
+ if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command)
1944
+ @vi_clipboard = text
1945
+ end
1946
+ end
1947
+
1948
+ private def vi_insert(key)
1949
+ @config.editing_mode = :vi_insert
1950
+ end
1951
+
1952
+ private def vi_add(key)
1953
+ @config.editing_mode = :vi_insert
1954
+ ed_next_char(key)
1955
+ end
1956
+
1957
+ private def vi_command_mode(key)
1958
+ ed_prev_char(key)
1959
+ @config.editing_mode = :vi_command
1960
+ end
1961
+ alias_method :vi_movement_mode, :vi_command_mode
1962
+
1963
+ private def vi_next_word(key, arg: 1)
1964
+ if current_line.bytesize > @byte_pointer
1965
+ byte_size = Reline::Unicode.vi_forward_word(current_line, @byte_pointer, @drop_terminate_spaces)
1966
+ @byte_pointer += byte_size
1967
+ end
1968
+ arg -= 1
1969
+ vi_next_word(key, arg: arg) if arg > 0
1970
+ end
1971
+
1972
+ private def vi_prev_word(key, arg: 1)
1973
+ if @byte_pointer > 0
1974
+ byte_size = Reline::Unicode.vi_backward_word(current_line, @byte_pointer)
1975
+ @byte_pointer -= byte_size
1976
+ end
1977
+ arg -= 1
1978
+ vi_prev_word(key, arg: arg) if arg > 0
1979
+ end
1980
+
1981
+ private def vi_end_word(key, arg: 1, inclusive: false)
1982
+ if current_line.bytesize > @byte_pointer
1983
+ byte_size = Reline::Unicode.vi_forward_end_word(current_line, @byte_pointer)
1984
+ @byte_pointer += byte_size
1985
+ end
1986
+ arg -= 1
1987
+ if inclusive and arg.zero?
1988
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
1989
+ if byte_size > 0
1990
+ @byte_pointer += byte_size
1991
+ end
1992
+ end
1993
+ vi_end_word(key, arg: arg) if arg > 0
1994
+ end
1995
+
1996
+ private def vi_next_big_word(key, arg: 1)
1997
+ if current_line.bytesize > @byte_pointer
1998
+ byte_size = Reline::Unicode.vi_big_forward_word(current_line, @byte_pointer)
1999
+ @byte_pointer += byte_size
2000
+ end
2001
+ arg -= 1
2002
+ vi_next_big_word(key, arg: arg) if arg > 0
2003
+ end
2004
+
2005
+ private def vi_prev_big_word(key, arg: 1)
2006
+ if @byte_pointer > 0
2007
+ byte_size = Reline::Unicode.vi_big_backward_word(current_line, @byte_pointer)
2008
+ @byte_pointer -= byte_size
2009
+ end
2010
+ arg -= 1
2011
+ vi_prev_big_word(key, arg: arg) if arg > 0
2012
+ end
2013
+
2014
+ private def vi_end_big_word(key, arg: 1, inclusive: false)
2015
+ if current_line.bytesize > @byte_pointer
2016
+ byte_size = Reline::Unicode.vi_big_forward_end_word(current_line, @byte_pointer)
2017
+ @byte_pointer += byte_size
2018
+ end
2019
+ arg -= 1
2020
+ if inclusive and arg.zero?
2021
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
2022
+ if byte_size > 0
2023
+ @byte_pointer += byte_size
2024
+ end
2025
+ end
2026
+ vi_end_big_word(key, arg: arg) if arg > 0
2027
+ end
2028
+
2029
+ private def vi_delete_prev_char(key)
2030
+ if @byte_pointer == 0 and @line_index > 0
2031
+ @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize
2032
+ @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index)
2033
+ @line_index -= 1
2034
+ process_auto_indent cursor_dependent: false
2035
+ elsif @byte_pointer > 0
2036
+ byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
2037
+ @byte_pointer -= byte_size
2038
+ line, _ = byteslice!(current_line, @byte_pointer, byte_size)
2039
+ set_current_line(line)
2040
+ end
2041
+ end
2042
+
2043
+ private def vi_insert_at_bol(key)
2044
+ ed_move_to_beg(key)
2045
+ @config.editing_mode = :vi_insert
2046
+ end
2047
+
2048
+ private def vi_add_at_eol(key)
2049
+ ed_move_to_end(key)
2050
+ @config.editing_mode = :vi_insert
2051
+ end
2052
+
2053
+ private def ed_delete_prev_char(key, arg: 1)
2054
+ deleted = +''
2055
+ arg.times do
2056
+ if @byte_pointer > 0
2057
+ byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer)
2058
+ @byte_pointer -= byte_size
2059
+ line, mbchar = byteslice!(current_line, @byte_pointer, byte_size)
2060
+ set_current_line(line)
2061
+ deleted.prepend(mbchar)
2062
+ end
2063
+ end
2064
+ copy_for_vi(deleted)
2065
+ end
2066
+
2067
+ private def vi_change_meta(key, arg: nil)
2068
+ if @vi_waiting_operator
2069
+ set_current_line('', 0) if @vi_waiting_operator == :vi_change_meta_confirm && arg.nil?
2070
+ @vi_waiting_operator = nil
2071
+ @vi_waiting_operator_arg = nil
2072
+ else
2073
+ @drop_terminate_spaces = true
2074
+ @vi_waiting_operator = :vi_change_meta_confirm
2075
+ @vi_waiting_operator_arg = arg || 1
2076
+ end
2077
+ end
2078
+
2079
+ private def vi_change_meta_confirm(byte_pointer_diff)
2080
+ vi_delete_meta_confirm(byte_pointer_diff)
2081
+ @config.editing_mode = :vi_insert
2082
+ @drop_terminate_spaces = false
2083
+ end
2084
+
2085
+ private def vi_delete_meta(key, arg: nil)
2086
+ if @vi_waiting_operator
2087
+ set_current_line('', 0) if @vi_waiting_operator == :vi_delete_meta_confirm && arg.nil?
2088
+ @vi_waiting_operator = nil
2089
+ @vi_waiting_operator_arg = nil
2090
+ else
2091
+ @vi_waiting_operator = :vi_delete_meta_confirm
2092
+ @vi_waiting_operator_arg = arg || 1
2093
+ end
2094
+ end
2095
+
2096
+ private def vi_delete_meta_confirm(byte_pointer_diff)
2097
+ if byte_pointer_diff > 0
2098
+ line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff)
2099
+ elsif byte_pointer_diff < 0
2100
+ line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2101
+ else
2102
+ return
2103
+ end
2104
+ copy_for_vi(cut)
2105
+ set_current_line(line, @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0))
2106
+ end
2107
+
2108
+ private def vi_yank(key, arg: nil)
2109
+ if @vi_waiting_operator
2110
+ copy_for_vi(current_line) if @vi_waiting_operator == :vi_yank_confirm && arg.nil?
2111
+ @vi_waiting_operator = nil
2112
+ @vi_waiting_operator_arg = nil
2113
+ else
2114
+ @vi_waiting_operator = :vi_yank_confirm
2115
+ @vi_waiting_operator_arg = arg || 1
2116
+ end
2117
+ end
2118
+
2119
+ private def vi_yank_confirm(byte_pointer_diff)
2120
+ if byte_pointer_diff > 0
2121
+ cut = current_line.byteslice(@byte_pointer, byte_pointer_diff)
2122
+ elsif byte_pointer_diff < 0
2123
+ cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff)
2124
+ else
2125
+ return
2126
+ end
2127
+ copy_for_vi(cut)
2128
+ end
2129
+
2130
+ private def vi_list_or_eof(key)
2131
+ if buffer_empty?
2132
+ @eof = true
2133
+ finish
2134
+ else
2135
+ ed_newline(key)
2136
+ end
2137
+ end
2138
+ alias_method :vi_end_of_transmission, :vi_list_or_eof
2139
+ alias_method :vi_eof_maybe, :vi_list_or_eof
2140
+
2141
+ private def ed_delete_next_char(key, arg: 1)
2142
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
2143
+ unless current_line.empty? || byte_size == 0
2144
+ line, mbchar = byteslice!(current_line, @byte_pointer, byte_size)
2145
+ copy_for_vi(mbchar)
2146
+ if @byte_pointer > 0 && current_line.bytesize == @byte_pointer + byte_size
2147
+ byte_size = Reline::Unicode.get_prev_mbchar_size(line, @byte_pointer)
2148
+ set_current_line(line, @byte_pointer - byte_size)
2149
+ else
2150
+ set_current_line(line, @byte_pointer)
2151
+ end
2152
+ end
2153
+ arg -= 1
2154
+ ed_delete_next_char(key, arg: arg) if arg > 0
2155
+ end
2156
+
2157
+ private def vi_to_history_line(key)
2158
+ if Reline::HISTORY.empty?
2159
+ return
2160
+ end
2161
+ move_history(0, line: :start, cursor: :start)
2162
+ end
2163
+
2164
+ private def vi_histedit(key)
2165
+ path = Tempfile.open { |fp|
2166
+ fp.write whole_lines.join("\n")
2167
+ fp.path
2168
+ }
2169
+ system("#{ENV['EDITOR']} #{path}")
2170
+ @buffer_of_lines = File.read(path).split("\n")
2171
+ @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty?
2172
+ @line_index = 0
2173
+ finish
2174
+ end
2175
+
2176
+ private def vi_paste_prev(key, arg: 1)
2177
+ if @vi_clipboard.size > 0
2178
+ cursor_point = @vi_clipboard.grapheme_clusters[0..-2].join
2179
+ set_current_line(byteinsert(current_line, @byte_pointer, @vi_clipboard), @byte_pointer + cursor_point.bytesize)
2180
+ end
2181
+ arg -= 1
2182
+ vi_paste_prev(key, arg: arg) if arg > 0
2183
+ end
2184
+
2185
+ private def vi_paste_next(key, arg: 1)
2186
+ if @vi_clipboard.size > 0
2187
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
2188
+ line = byteinsert(current_line, @byte_pointer + byte_size, @vi_clipboard)
2189
+ set_current_line(line, @byte_pointer + @vi_clipboard.bytesize)
2190
+ end
2191
+ arg -= 1
2192
+ vi_paste_next(key, arg: arg) if arg > 0
2193
+ end
2194
+
2195
+ private def ed_argument_digit(key)
2196
+ # key is expected to be `ESC digit` or `digit`
2197
+ num = key[/\d/].to_i
2198
+ @vi_arg = (@vi_arg || 0) * 10 + num
2199
+ end
2200
+
2201
+ private def vi_to_column(key, arg: 0)
2202
+ # Implementing behavior of vi, not Readline's vi-mode.
2203
+ @byte_pointer, = current_line.grapheme_clusters.inject([0, 0]) { |(total_byte_size, total_width), gc|
2204
+ mbchar_width = Reline::Unicode.get_mbchar_width(gc)
2205
+ break [total_byte_size, total_width] if (total_width + mbchar_width) >= arg
2206
+ [total_byte_size + gc.bytesize, total_width + mbchar_width]
2207
+ }
2208
+ end
2209
+
2210
+ private def vi_replace_char(key, arg: 1)
2211
+ @waiting_proc = ->(k) {
2212
+ if arg == 1
2213
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
2214
+ before = current_line.byteslice(0, @byte_pointer)
2215
+ remaining_point = @byte_pointer + byte_size
2216
+ after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
2217
+ set_current_line(before + k + after)
2218
+ @waiting_proc = nil
2219
+ elsif arg > 1
2220
+ byte_size = 0
2221
+ arg.times do
2222
+ byte_size += Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer + byte_size)
2223
+ end
2224
+ before = current_line.byteslice(0, @byte_pointer)
2225
+ remaining_point = @byte_pointer + byte_size
2226
+ after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
2227
+ replaced = k * arg
2228
+ set_current_line(before + replaced + after, @byte_pointer + replaced.bytesize)
2229
+ @waiting_proc = nil
2230
+ end
2231
+ }
2232
+ end
2233
+
2234
+ private def vi_next_char(key, arg: 1, inclusive: false)
2235
+ @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, inclusive: inclusive) }
2236
+ end
2237
+
2238
+ private def vi_to_next_char(key, arg: 1, inclusive: false)
2239
+ @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, need_prev_char: true, inclusive: inclusive) }
2240
+ end
2241
+
2242
+ private def search_next_char(key, arg, need_prev_char: false, inclusive: false)
2243
+ prev_total = nil
2244
+ total = nil
2245
+ found = false
2246
+ current_line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar|
2247
+ # total has [byte_size, cursor]
2248
+ unless total
2249
+ # skip cursor point
2250
+ width = Reline::Unicode.get_mbchar_width(mbchar)
2251
+ total = [mbchar.bytesize, width]
2252
+ else
2253
+ if key == mbchar
2254
+ arg -= 1
2255
+ if arg.zero?
2256
+ found = true
2257
+ break
2258
+ end
2259
+ end
2260
+ width = Reline::Unicode.get_mbchar_width(mbchar)
2261
+ prev_total = total
2262
+ total = [total.first + mbchar.bytesize, total.last + width]
2263
+ end
2264
+ end
2265
+ if not need_prev_char and found and total
2266
+ byte_size, _ = total
2267
+ @byte_pointer += byte_size
2268
+ elsif need_prev_char and found and prev_total
2269
+ byte_size, _ = prev_total
2270
+ @byte_pointer += byte_size
2271
+ end
2272
+ if inclusive
2273
+ byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
2274
+ if byte_size > 0
2275
+ @byte_pointer += byte_size
2276
+ end
2277
+ end
2278
+ @waiting_proc = nil
2279
+ end
2280
+
2281
+ private def vi_prev_char(key, arg: 1)
2282
+ @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) }
2283
+ end
2284
+
2285
+ private def vi_to_prev_char(key, arg: 1)
2286
+ @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) }
2287
+ end
2288
+
2289
+ private def search_prev_char(key, arg, need_next_char = false)
2290
+ prev_total = nil
2291
+ total = nil
2292
+ found = false
2293
+ current_line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
2294
+ # total has [byte_size, cursor]
2295
+ unless total
2296
+ # skip cursor point
2297
+ width = Reline::Unicode.get_mbchar_width(mbchar)
2298
+ total = [mbchar.bytesize, width]
2299
+ else
2300
+ if key == mbchar
2301
+ arg -= 1
2302
+ if arg.zero?
2303
+ found = true
2304
+ break
2305
+ end
2306
+ end
2307
+ width = Reline::Unicode.get_mbchar_width(mbchar)
2308
+ prev_total = total
2309
+ total = [total.first + mbchar.bytesize, total.last + width]
2310
+ end
2311
+ end
2312
+ if not need_next_char and found and total
2313
+ byte_size, _ = total
2314
+ @byte_pointer -= byte_size
2315
+ elsif need_next_char and found and prev_total
2316
+ byte_size, _ = prev_total
2317
+ @byte_pointer -= byte_size
2318
+ end
2319
+ @waiting_proc = nil
2320
+ end
2321
+
2322
+ private def vi_join_lines(key, arg: 1)
2323
+ if @buffer_of_lines.size > @line_index + 1
2324
+ next_line = @buffer_of_lines.delete_at(@line_index + 1).lstrip
2325
+ set_current_line(current_line + ' ' + next_line, current_line.bytesize)
2326
+ end
2327
+ arg -= 1
2328
+ vi_join_lines(key, arg: arg) if arg > 0
2329
+ end
2330
+
2331
+ private def em_set_mark(key)
2332
+ @mark_pointer = [@byte_pointer, @line_index]
2333
+ end
2334
+ alias_method :set_mark, :em_set_mark
2335
+
2336
+ private def em_exchange_mark(key)
2337
+ return unless @mark_pointer
2338
+ new_pointer = [@byte_pointer, @line_index]
2339
+ @byte_pointer, @line_index = @mark_pointer
2340
+ @mark_pointer = new_pointer
2341
+ end
2342
+ alias_method :exchange_point_and_mark, :em_exchange_mark
2343
+
2344
+ private def emacs_editing_mode(key)
2345
+ @config.editing_mode = :emacs
2346
+ end
2347
+
2348
+ private def vi_editing_mode(key)
2349
+ @config.editing_mode = :vi_insert
2350
+ end
2351
+
2352
+ private def move_undo_redo(direction)
2353
+ @restoring = true
2354
+ return unless (0..@input_lines.size - 1).cover?(@input_lines_position + direction)
2355
+
2356
+ @input_lines_position += direction
2357
+ buffer_of_lines, byte_pointer, line_index = @input_lines[@input_lines_position]
2358
+ @buffer_of_lines = buffer_of_lines.dup
2359
+ @line_index = line_index
2360
+ @byte_pointer = byte_pointer
2361
+ end
2362
+
2363
+ private def undo(_key)
2364
+ move_undo_redo(-1)
2365
+ end
2366
+
2367
+ private def redo(_key)
2368
+ move_undo_redo(+1)
2369
+ end
2370
+
2371
+ private def prev_action_state_value(type)
2372
+ @prev_action_state[0] == type ? @prev_action_state[1] : nil
2373
+ end
2374
+
2375
+ private def set_next_action_state(type, value)
2376
+ @next_action_state = [type, value]
2377
+ end
2378
+
2379
+ private def re_read_init_file(_key)
2380
+ @config.reload
2381
+ end
2382
+ end