1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/lib/syntax_suggest/core_ext.rb
schneems 490af8dbdb Sync SyntaxSuggest
```
$ tool/sync_default_gems.rb syntax_suggest
```
2022-08-19 10:02:24 +09:00

101 lines
2.6 KiB
Ruby

# frozen_string_literal: true
# Ruby 3.2+ has a cleaner way to hook into Ruby that doesn't use `require`
if SyntaxError.method_defined?(:detailed_message)
module SyntaxSuggest
class MiniStringIO
def initialize(isatty: $stderr.isatty)
@string = +""
@isatty = isatty
end
attr_reader :isatty
def puts(value = $/, **)
@string << value
end
attr_reader :string
end
end
SyntaxError.prepend Module.new {
def detailed_message(highlight: true, syntax_suggest: true, **kwargs)
return super unless syntax_suggest
require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE)
message = super
file = if highlight
SyntaxSuggest::PathnameFromMessage.new(super(highlight: false, **kwargs)).call.name
else
SyntaxSuggest::PathnameFromMessage.new(message).call.name
end
io = SyntaxSuggest::MiniStringIO.new
if file
SyntaxSuggest.call(
io: io,
source: file.read,
filename: file,
terminal: highlight
)
annotation = io.string
annotation + message
else
message
end
rescue => e
if ENV["SYNTAX_SUGGEST_DEBUG"]
$stderr.warn(e.message)
$stderr.warn(e.backtrace)
end
# Ignore internal errors
message
end
}
else
autoload :Pathname, "pathname"
# Monkey patch kernel to ensure that all `require` calls call the same
# method
module Kernel
module_function
alias_method :syntax_suggest_original_require, :require
alias_method :syntax_suggest_original_require_relative, :require_relative
alias_method :syntax_suggest_original_load, :load
def load(file, wrap = false)
syntax_suggest_original_load(file)
rescue SyntaxError => e
require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE)
SyntaxSuggest.handle_error(e)
end
def require(file)
syntax_suggest_original_require(file)
rescue SyntaxError => e
require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE)
SyntaxSuggest.handle_error(e)
end
def require_relative(file)
if Pathname.new(file).absolute?
syntax_suggest_original_require file
else
relative_from = caller_locations(1..1).first
relative_from_path = relative_from.absolute_path || relative_from.path
syntax_suggest_original_require File.expand_path("../#{file}", relative_from_path)
end
rescue SyntaxError => e
require "syntax_suggest/api" unless defined?(SyntaxSuggest::DEFAULT_VALUE)
SyntaxSuggest.handle_error(e)
end
end
end