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