Module: RuVim::DisplayWidth

Defined in:
lib/ruvim/display_width.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ambiguous_codepoint?(code) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/ruvim/display_width.rb', line 156

def ambiguous_codepoint?(code)
  (0x00A1..0x00A1).cover?(code) ||
    (0x00A4..0x00A4).cover?(code) ||
    (0x00A7..0x00A8).cover?(code) ||
    (0x00AA..0x00AA).cover?(code) ||
    (0x00AD..0x00AE).cover?(code) ||
    (0x00B0..0x00B4).cover?(code) ||
    (0x00B6..0x00BA).cover?(code) ||
    (0x00BC..0x00BF).cover?(code) ||
    (0x0391..0x03A9).cover?(code) ||
    (0x03B1..0x03C9).cover?(code) ||
    (0x2010..0x2010).cover?(code) ||
    (0x2013..0x2016).cover?(code) ||
    (0x2018..0x2019).cover?(code) ||
    (0x201C..0x201D).cover?(code) ||
    (0x2020..0x2022).cover?(code) ||
    (0x2024..0x2027).cover?(code) ||
    (0x2030..0x2030).cover?(code) ||
    (0x2032..0x2033).cover?(code) ||
    (0x2035..0x2035).cover?(code) ||
    (0x203B..0x203B).cover?(code) ||
    (0x203E..0x203E).cover?(code) ||
    (0x2460..0x24E9).cover?(code) ||
    (0x2500..0x257F).cover?(code)
end

.cached_codepoint_width(code) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/ruvim/display_width.rb', line 105

def cached_codepoint_width(code)
  aw = ambiguous_width
  @codepoint_width_cache ||= {}
  key = [code, aw]
  return @codepoint_width_cache[key] if @codepoint_width_cache.key?(key)

  @codepoint_width_cache[key] = uncached_codepoint_width(code)
end

.codepoint_cacheable?(code) ⇒ Boolean

Shared helpers (used by pure Ruby path; kept available for tests)

Returns:

  • (Boolean)


101
102
103
# File 'lib/ruvim/display_width.rb', line 101

def codepoint_cacheable?(code)
  !code.nil? && !code.zero?
end

.combining_mark?(code) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
130
131
# File 'lib/ruvim/display_width.rb', line 125

def combining_mark?(code)
  (0x0300..0x036F).cover?(code) ||
    (0x1AB0..0x1AFF).cover?(code) ||
    (0x1DC0..0x1DFF).cover?(code) ||
    (0x20D0..0x20FF).cover?(code) ||
    (0xFE20..0xFE2F).cover?(code)
end

.emoji_codepoint?(code) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
154
# File 'lib/ruvim/display_width.rb', line 151

def emoji_codepoint?(code)
  (0x1F300..0x1FAFF).cover?(code) ||
    (0x2600..0x27BF).cover?(code)
end

.uncached_codepoint_width(code) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'lib/ruvim/display_width.rb', line 114

def uncached_codepoint_width(code)
  return 0 if code.zero?
  return 0 if combining_mark?(code)
  return 0 if zero_width_codepoint?(code)
  return ambiguous_width if ambiguous_codepoint?(code)
  return 2 if emoji_codepoint?(code)
  return 2 if wide_codepoint?(code)

  1
end

.wide_codepoint?(code) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
142
143
144
145
146
147
148
149
# File 'lib/ruvim/display_width.rb', line 139

def wide_codepoint?(code)
  (0x1100..0x115F).cover?(code) ||
    (0x2329..0x232A).cover?(code) ||
    (0x2E80..0xA4CF).cover?(code) ||
    (0xAC00..0xD7A3).cover?(code) ||
    (0xF900..0xFAFF).cover?(code) ||
    (0xFE10..0xFE19).cover?(code) ||
    (0xFE30..0xFE6F).cover?(code) ||
    (0xFF00..0xFF60).cover?(code) ||
    (0xFFE0..0xFFE6).cover?(code)
end

.zero_width_codepoint?(code) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
136
137
# File 'lib/ruvim/display_width.rb', line 133

def zero_width_codepoint?(code)
  (0x200D..0x200D).cover?(code) ||
    (0xFE00..0xFE0F).cover?(code) ||
    (0xE0100..0xE01EF).cover?(code)
end

Instance Method Details

#ambiguous_widthObject



32
33
34
# File 'lib/ruvim/display_width.rb', line 32

def ambiguous_width
  sync_ambiguous_width
end

#cell_width(ch, col: 0, tabstop: 2) ⇒ Object

---- Pure Ruby fallback ----



17
18
19
20
# File 'lib/ruvim/display_width.rb', line 17

def cell_width(ch, col: 0, tabstop: 2)
  sync_ambiguous_width
  DisplayWidthExt.cell_width(ch, col:, tabstop:)
end

#display_width(str, tabstop: 2, start_col: 0) ⇒ Object



22
23
24
25
# File 'lib/ruvim/display_width.rb', line 22

def display_width(str, tabstop: 2, start_col: 0)
  sync_ambiguous_width
  DisplayWidthExt.display_width(str, tabstop:, start_col:)
end

#expand_tabs(str, tabstop: 2, start_col: 0) ⇒ Object



27
28
29
30
# File 'lib/ruvim/display_width.rb', line 27

def expand_tabs(str, tabstop: 2, start_col: 0)
  sync_ambiguous_width
  DisplayWidthExt.expand_tabs(str, tabstop:, start_col:)
end

#sync_ambiguous_widthObject



36
37
38
39
40
41
42
43
44
# File 'lib/ruvim/display_width.rb', line 36

def sync_ambiguous_width
  env = ::ENV["RUVIM_AMBIGUOUS_WIDTH"]
  if !defined?(@ambiguous_width_cached) || @ambiguous_width_env != env
    @ambiguous_width_env = env
    @ambiguous_width_cached = (env == "2" ? 2 : 1)
    DisplayWidthExt.set_ambiguous_width(@ambiguous_width_cached)
  end
  @ambiguous_width_cached
end