mbeditor 0.14.0 → 0.14.1

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/app/assets/javascripts/mbeditor/application.js +2 -0
  4. data/app/assets/javascripts/mbeditor/components/CombinedFileView.js +214 -0
  5. data/app/assets/javascripts/mbeditor/components/EditorPanel.js +13 -1
  6. data/app/assets/javascripts/mbeditor/components/ImportConflictModal.js +60 -5
  7. data/app/assets/javascripts/mbeditor/components/MbeditorApp.js +68 -8
  8. data/app/assets/javascripts/mbeditor/components/PastePlaceModal.js +329 -0
  9. data/app/assets/javascripts/mbeditor/components/ShortcutHelp.js +16 -0
  10. data/app/assets/javascripts/mbeditor/editor_plugins.js +20 -20
  11. data/app/assets/javascripts/mbeditor/file_service.js +10 -0
  12. data/app/assets/stylesheets/mbeditor/editor.css +30 -1
  13. data/app/assets/stylesheets/mbeditor/glass.css +11 -0
  14. data/app/assets/stylesheets/mbeditor/themes.css +3 -3
  15. data/app/controllers/mbeditor/editors_controller.rb +7 -0
  16. data/app/services/mbeditor/ruby_method_ranges_service.rb +120 -0
  17. data/lib/mbeditor/rack/pending_migration_bypass.rb +16 -1
  18. data/lib/mbeditor/route_map.rb +1 -0
  19. data/lib/mbeditor/version.rb +1 -1
  20. data/public/monaco-editor/VERSIONS +1 -1
  21. data/public/monaco-editor/codicon.ttf +0 -0
  22. data/public/monaco-editor/css.worker.js +41 -37
  23. data/public/monaco-editor/editor.worker.js +19 -15
  24. data/public/monaco-editor/html.worker.js +53 -49
  25. data/public/monaco-editor/json.worker.js +36 -32
  26. data/public/monaco-editor/monaco.css +1 -1
  27. data/public/monaco-editor/monaco.js +388 -301
  28. data/public/monaco-editor/ts.worker.js +226 -222
  29. data/vendor/assets/javascripts/axios.min.js +3 -3
  30. metadata +5 -2
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ripper"
4
+
5
+ module Mbeditor
6
+ # Line ranges of every method (and enclosing class/module) in Ruby source.
7
+ #
8
+ # Ripper rather than Prism: it is stdlib on every Ruby this gem supports.
9
+ # Events fire bottom-up, so a node's end line is the last significant token
10
+ # the scanner produced before it reduced, and owners are resolved afterwards
11
+ # by range containment instead of a stack.
12
+ #
13
+ # call(src) => { methods: [{ name:, singleton:, owner:, start_line:,
14
+ # doc_start_line:, end_line: }],
15
+ # owners: [{ kind:, name:, start_line:, end_line: }] }
16
+ # | { error: "..." } (owners also hold `class << self` as kind "sclass")
17
+ class RubyMethodRangesService
18
+ MAX_BYTES = 200 * 1024
19
+
20
+ # Tokens that carry no code; a def never ends on one of these.
21
+ BLANK = %i[sp nl ignored_nl comment embdoc_beg embdoc embdoc_end words_sep ignored_sp].freeze
22
+
23
+ class Collector < Ripper::SexpBuilder
24
+ attr_reader :methods_found, :owners_found
25
+
26
+ def initialize(*)
27
+ super
28
+ @methods_found = []
29
+ @owners_found = []
30
+ @last_line = 1
31
+ end
32
+
33
+ (Ripper::SCANNER_EVENTS - BLANK).each do |ev|
34
+ define_method(:"on_#{ev}") do |tok|
35
+ @last_line = lineno
36
+ super(tok)
37
+ end
38
+ end
39
+
40
+ def on_def(name, *rest)
41
+ record(name, false)
42
+ super
43
+ end
44
+
45
+ def on_defs(target, period, name, *rest)
46
+ record(name, true)
47
+ super
48
+ end
49
+
50
+ def on_class(const, *rest)
51
+ owner(:class, const)
52
+ super
53
+ end
54
+
55
+ def on_sclass(target, *rest)
56
+ @owners_found << { kind: "sclass", name: "<< self", start_line: first_line(target), end_line: @last_line }
57
+ super
58
+ end
59
+
60
+ def on_module(const, *rest)
61
+ owner(:module, const)
62
+ super
63
+ end
64
+
65
+ private
66
+
67
+ def record(ident, singleton)
68
+ @methods_found << { name: ident[1], singleton: singleton, start_line: ident[2][0], end_line: @last_line }
69
+ end
70
+
71
+ def owner(kind, const)
72
+ @owners_found << { kind: kind.to_s, name: const_name(const), start_line: first_line(const), end_line: @last_line }
73
+ end
74
+
75
+ def const_name(node)
76
+ return "" unless node.is_a?(Array)
77
+
78
+ case node[0]
79
+ when :@const then node[1]
80
+ when :const_ref, :var_ref, :top_const_ref then const_name(node[1])
81
+ when :const_path_ref then "#{const_name(node[1])}::#{const_name(node[2])}"
82
+ else ""
83
+ end
84
+ end
85
+
86
+ def first_line(node)
87
+ return node[2][0] if node.is_a?(Array) && node[0].is_a?(Symbol) && node[0].to_s.start_with?("@")
88
+
89
+ node.each { |c| l = first_line(c) if c.is_a?(Array); return l if l } if node.is_a?(Array)
90
+ nil
91
+ end
92
+ end
93
+
94
+ def self.call(source)
95
+ source = source.to_s
96
+ return { error: "Source too large" } if source.bytesize > MAX_BYTES
97
+
98
+ parser = Collector.new(source)
99
+ parser.parse
100
+ return { error: "Syntax error" } if parser.error?
101
+
102
+ lines = source.lines
103
+ owners = parser.owners_found.sort_by { |o| [o[:start_line], -o[:end_line]] }
104
+ methods = parser.methods_found.sort_by { |m| m[:start_line] }.map do |m|
105
+ chain = owners.select { |o| o[:start_line] <= m[:start_line] && o[:end_line] >= m[:end_line] }
106
+ m.merge(singleton: m[:singleton] || chain.any? { |o| o[:kind] == "sclass" },
107
+ owner: chain.reject { |o| o[:kind] == "sclass" }.map { |o| o[:name] }.join("::"), doc_start_line: doc_start(lines, m[:start_line]))
108
+ end
109
+ { methods: methods, owners: owners }
110
+ rescue StandardError, SystemStackError => e
111
+ { error: e.message }
112
+ end
113
+
114
+ def self.doc_start(lines, start_line)
115
+ line = start_line
116
+ line -= 1 while line > 1 && lines[line - 2].to_s.lstrip.start_with?("#")
117
+ line
118
+ end
119
+ end
120
+ end
@@ -33,6 +33,7 @@ module Mbeditor
33
33
  # is still told to migrate — they are just no longer prevented from working.
34
34
  class PendingMigrationBypass
35
35
  DEFAULT_ASSET_PREFIX = "/assets"
36
+ DEFAULT_CABLE_PATH = "/cable"
36
37
 
37
38
  def initialize(app, file_watcher: nil)
38
39
  @app = app
@@ -94,7 +95,21 @@ module Mbeditor
94
95
  prefix = Mbeditor::MountPath.resolve
95
96
  return true if path == prefix || path.start_with?("#{prefix}/")
96
97
 
97
- path.start_with?("#{asset_prefix}/")
98
+ return true if path.start_with?("#{asset_prefix}/")
99
+
100
+ # The cable carries presence, collaboration and file-change push. Left
101
+ # blocked it 500s on every reconnect, and the client's status chips
102
+ # flicker for as long as the migration stays pending.
103
+ path == cable_path || path.start_with?("#{cable_path}/")
104
+ end
105
+
106
+ def cable_path
107
+ @cable_path ||= begin
108
+ configured = Rails.application.config.action_cable.mount_path if Rails.application.config.respond_to?(:action_cable)
109
+ (configured.presence || DEFAULT_CABLE_PATH).to_s.chomp("/")
110
+ rescue StandardError
111
+ DEFAULT_CABLE_PATH
112
+ end
98
113
  end
99
114
 
100
115
  def asset_prefix
@@ -37,6 +37,7 @@ module Mbeditor
37
37
  get 'js_program', to: 'editors#js_program'
38
38
  post 'ruby_lsp', to: 'editors#ruby_lsp'
39
39
  post 'ruby_rename', to: 'editors#ruby_rename'
40
+ post 'ruby_methods', to: 'editors#ruby_methods'
40
41
  get 'model_graph', to: 'editors#model_graph'
41
42
  get 'exceptions', to: 'editors#exceptions'
42
43
  delete 'exceptions', to: 'editors#clear_exceptions'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mbeditor
4
- VERSION = "0.14.0"
4
+ VERSION = "0.14.1"
5
5
  end
@@ -1,3 +1,3 @@
1
- monaco-editor 0.55.1
1
+ monaco-editor 0.57.0
2
2
  monaco-vim 0.4.4
3
3
  esbuild 0.28.0
Binary file