1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Refactored width calculations

This commit is contained in:
Nobuyoshi Nakada 2019-07-06 12:31:11 +09:00
parent 44aae5fee6
commit 688cef2169
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60

View file

@ -53,6 +53,7 @@ class Reline::LineEditor
OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/ OSC_REGEXP = /\e\]\d+(?:;[^;]+)*\a/
NON_PRINTING_START = "\1" NON_PRINTING_START = "\1"
NON_PRINTING_END = "\2" NON_PRINTING_END = "\2"
WIDTH_SCANNER = /\G(?:#{NON_PRINTING_START}|#{NON_PRINTING_END}|#{CSI_REGEXP}|#{OSC_REGEXP}|\X)/
def initialize(config) def initialize(config)
@config = config @config = config
@ -145,35 +146,23 @@ class Reline::LineEditor
width = 0 width = 0
rest = "#{prompt}#{str}".encode(Encoding::UTF_8) rest = "#{prompt}#{str}".encode(Encoding::UTF_8)
in_zero_width = false in_zero_width = false
loop do rest.scan(WIDTH_SCANNER) do |gc|
break if rest.empty? case gc
if rest.start_with?(NON_PRINTING_START) when NON_PRINTING_START
rest.delete_prefix!(NON_PRINTING_START)
in_zero_width = true in_zero_width = true
elsif rest.start_with?(NON_PRINTING_END) when NON_PRINTING_END
rest.delete_prefix!(NON_PRINTING_END)
in_zero_width = false in_zero_width = false
elsif rest.start_with?(CSI_REGEXP) when CSI_REGEXP, OSC_REGEXP
lines.last << $& lines.last << gc
rest = $'
elsif rest.start_with?(OSC_REGEXP)
lines.last << $&
rest = $'
else else
gcs = rest.grapheme_clusters unless in_zero_width
gc = gcs.first
rest = gcs[1..-1].join
if in_zero_width
mbchar_width = 0
else
mbchar_width = Reline::Unicode.get_mbchar_width(gc) mbchar_width = Reline::Unicode.get_mbchar_width(gc)
end if (width += mbchar_width) > max_width
width += mbchar_width width = mbchar_width
if width > max_width lines << nil
width = mbchar_width lines << String.new(encoding: @encoding)
lines << nil height += 1
lines << String.new(encoding: @encoding) end
height += 1
end end
lines.last << gc lines.last << gc
end end
@ -955,28 +944,17 @@ class Reline::LineEditor
width = 0 width = 0
rest = str.encode(Encoding::UTF_8) rest = str.encode(Encoding::UTF_8)
in_zero_width = false in_zero_width = false
loop do rest.scan(WIDTH_SCANNER) do |gc|
break if rest.empty? case gc
if rest.start_with?(NON_PRINTING_START) when NON_PRINTING_START
rest.delete_prefix!(NON_PRINTING_START)
in_zero_width = true in_zero_width = true
elsif rest.start_with?(NON_PRINTING_END) when NON_PRINTING_END
rest.delete_prefix!(NON_PRINTING_END)
in_zero_width = false in_zero_width = false
elsif rest.start_with?(CSI_REGEXP) when CSI_REGEXP, OSC_REGEXP
rest = $'
elsif rest.start_with?(OSC_REGEXP)
rest = $'
else else
gcs = rest.grapheme_clusters unless in_zero_width
gc = gcs.first width += Reline::Unicode.get_mbchar_width(gc)
rest = gcs[1..-1].join
if in_zero_width
mbchar_width = 0
else
mbchar_width = Reline::Unicode.get_mbchar_width(gc)
end end
width += mbchar_width
end end
end end
width width