godot-xterm/addons/godot_xterm/buffer/buffer.gd

142 lines
3.5 KiB
GDScript3
Raw Normal View History

2020-05-10 12:56:49 +02:00
# Copyright (c) 2017 The xterm.js authors. All rights reserved.
# Ported to GDScript by the GodotXterm authors.
# License MIT
extends Reference
const BufferLine = preload("res://addons/godot_xterm/buffer/buffer_line.gd")
const CellData = preload("res://addons/godot_xterm/buffer/cell_data.gd")
const Charsets = preload("res://addons/godot_xterm/data/charsets.gd")
const Constants = preload("res://addons/godot_xterm/buffer/constants.gd")
const CircularList = preload("res://addons/godot_xterm/circular_list.gd")
const AttributeData = preload("res://addons/godot_xterm/buffer/attribute_data.gd")
const MAX_BUFFER_SIZE = 4294967295 # 2^32 - 1
var lines
var ydisp: int = 0
var ybase: int = 0
var y: int = 0
var x: int = 0
var scroll_bottom: int
var scroll_top: int
var tabs = {}
var saved_y: int = 0
var saved_x: int = 0
var saved_cur_attr_data = AttributeData.new()
var saved_charset = Charsets.DEFAULT_CHARSET
var markers: Array = []
var _null_cell = CellData.from_char_data([0, Constants.NULL_CELL_CHAR,
Constants.NULL_CELL_WIDTH, Constants.NULL_CELL_CODE])
var _whitespace_cell = CellData.from_char_data([0, Constants.WHITESPACE_CELL_CHAR,
Constants.WHITESPACE_CELL_WIDTH, Constants.WHITESPACE_CELL_CODE])
var _cols: int
var _rows: int
var _has_scrollback
var _options_service
var _buffer_service
func _init(has_scrollback: bool, options_service, buffer_service):
_has_scrollback = has_scrollback
_options_service = options_service
_buffer_service = buffer_service
_cols = buffer_service.cols
_rows = buffer_service.rows
lines = CircularList.new(_get_correct_buffer_length(_rows))
scroll_top = 0
scroll_bottom = _rows - 1
setup_tab_stops()
func get_null_cell(attr = null):
if attr:
_null_cell.fg = attr.fg
_null_cell.bg = attr.bg
_null_cell.extended = attr.extended
else:
_null_cell.fg = 0
_null_cell.bg = 0
_null_cell.extended = AttributeData.ExtendedAttrs.new()
return _null_cell
func get_blank_line(attr, is_wrapped: bool = false):
return BufferLine.new(_buffer_service.cols, get_null_cell(attr), is_wrapped)
func _get_correct_buffer_length(rows: int) -> int:
if not _has_scrollback:
return rows
else:
var correct_buffer_length = rows + _options_service.options.scrollback
return correct_buffer_length if correct_buffer_length < MAX_BUFFER_SIZE else MAX_BUFFER_SIZE
# Fills the viewport with blank lines.
func fill_viewport_rows(fill_attr = null) -> void:
if lines.length == 0:
if not fill_attr:
fill_attr = AttributeData.new()
var i = _rows
while i:
lines.push(get_blank_line(fill_attr))
i -= 1
# Clears the buffer to it's initial state, discarding all previous data.
func clear() -> void:
ydisp = 0
ybase = 0
y = 0
x = 0
lines = CircularList.new(_get_correct_buffer_length(_rows))
scroll_top = 0
scroll_bottom = _rows - 1
setup_tab_stops()
func get_wrapped_range_for_line(y: int) -> Dictionary:
var first = y
var last = y
# Scan upwards for wrapped lines
while first > 0 and lines.get_el(first).is_wrapped:
first -= 1
# Scan downwards for wrapped lines
while last + 1 < lines.length and lines.get_el(last + 1).is_wrapped:
last += 1
return {"first": first, "last": last}
func setup_tab_stops(i = null) -> void:
if i == null:
return
if not tabs.get(i):
i = prev_stop(i)
else:
tabs = {}
i = 0
while i < _cols:
tabs[i] = true
i += _options_service.options.tab_stop_width
func prev_stop(x: int) -> int:
if x == null:
x = self.x
while not tabs.get(x - 1, false) and x - 1 > 0:
x - 1
return _cols - 1 if x > _cols else 0 if x < 0 else x