Add more features, bug fixes and bugs ;-)

Most notably:
- Reflow is now working. Terminal size will fill the window and
cols/rows will be resized/calculated based on window and font size.
- Added support for different fonts (i.e. bold, italic, bolditalic).
- Enabled blinking characters.
- Adde more tests and caught a few subtle bugs.
- Removed renderer code (which was part of xterm.js) and just
doing naive rendering in terminal.gd, but it seems to perform
a lot faster.

Still not working completely:
- vim (some weirdness going on).
- vttest (more weirdness).

Todo:
- Fix the above.
- Draw the cursor!
- Improve performance. Performance is still not great. The terminal
becomes unusable when running `yes` or `cmatrix -r`.
This commit is contained in:
Leroy Hopson 2020-05-19 18:45:18 +07:00
parent 0769592a1b
commit 0d4e10f5ab
30 changed files with 2640 additions and 1157 deletions

View file

@ -4,7 +4,7 @@
extends Reference
signal buffer_activated(active_buffer, inactive_buffer)
signal resized
signal resized(cols, rows)
const BufferSet = preload("res://addons/godot_xterm/buffer/buffer_set.gd")
@ -29,11 +29,25 @@ func _get_buffer():
func _init(options_service):
_options_service = options_service
_options_service.connect("option_changed", self, "_option_changed")
cols = max(_options_service.options.cols, MINIMUM_COLS)
rows = max(_options_service.options.rows, MINIMUM_ROWS)
buffers = BufferSet.new(_options_service, self)
buffers.connect("buffer_activated", self, "_buffer_activated")
func resize(cols: int, rows: int) -> void:
self.cols = cols
self.rows = rows
buffers.resize(cols, rows)
#buffers.setup_tab_stops(cols)
emit_signal("resized", cols, rows)
func _buffer_activated(active_buffer, inactive_buffer):
emit_signal("buffer_activated", active_buffer, inactive_buffer)
func _option_changed(option: String) -> void:
if option == "cols" or option == "rows":
resize(_options_service.options.cols, _options_service.options.rows)

View file

@ -4,45 +4,72 @@
extends Reference
class TerminalOptions:
var cols: int
var rows: int
var cursor_blink: bool
var cursor_style
var cursor_width: int
var bell_sound
var bell_style
var draw_bold_text_in_bright_colors: bool
var fast_scroll_modifier
var fast_scroll_sensitivity: int
var font_family: Dictionary
var font_size: int
var font_weight: String
var font_weight_bold: String
var line_height: float
var link_tooltip_hover_duration: int
var letter_spacing: float
var log_level
var scrollback: int
var scroll_sensitivity: int
var screen_reader_mode: bool
var mac_option_is_meta: bool
var mac_option_click_forces_selection: bool
var minimum_contrast_ratio: float
var disable_stdin: bool
var allow_proposed_api: bool
var allow_transparency: bool
var tab_stop_width: int
var colors: Dictionary
var right_click_selects_word
var renderer_type
var window_options: Dictionary
var windows_mode: bool
var word_separator: String
var convert_eol: bool
var term_name: String
var cancel_events: bool
const Constants = preload("res://addons/godot_xterm/buffer/constants.gd")
const CursorStyle = Constants.CursorStyle
const UnderlineStyle = Constants.UnderlineStyle
const BellStyle = Constants.BellStyle
class TerminalOptions:
extends Reference
var cols: int = 80
var rows: int = 24
var cursor_blink: bool = false
var cursor_style = CursorStyle.BLOCK
# var cursor_width: int = 1
# var bell_sound: AudioStream = null
# var bell_style = BellStyle.NONE
# var draw_bold_text_in_bright_colors: bool = true
# var fast_scroll_modifier = "alt"
# var fast_scroll_sensitivity: int = 5
var font_family: Dictionary = {
# TODO
}
var font_size: int = 15
# var font_weight: String # TODO: Remove
# var font_weight_bold: String # TODO: Remove
var line_height: float = 1.0
# var link_tooltip_hover_duration: int # TODO: Remove
var letter_spacing: float = 0
# var log_level # TODO: implement
var scrollback: int = 1000
# var scroll_sensitivity: int = 1
var screen_reader_mode: bool = false
# var mac_option_is_meta: bool = false
# var mac_option_click_forces_selection: bool = false
# var minimum_contrast_ratio: float = 1
# var disable_stdin: bool = false
# var allow_proposed_api: bool = true
var allow_transparency: bool = false
var tab_stop_width: int = 8
# var colors: Dictionary = {
# 'black': Color(0, 0, 0)
# }
# var right_click_selects_word = "isMac" # TODO?
# var renderer_type = "canvas" # Remove?
var window_options: Dictionary = {
'set_win_lines': false,
}
var windows_mode: bool = false
# var word_separator: String = " ()[]{}',\""
var convert_eol: bool = true
# var term_name: String = "xterm"
# var cancel_events: bool = false
# Copies options from an `object` to itself.
func copy_from(object: Object):
for property in get_property_list():
if property.usage == PROPERTY_USAGE_SCRIPT_VARIABLE:
var p = object.get(property.name)
if p:
set(property.name, p)
var DEFAULT_OPTIONS = TerminalOptions.new()
signal option_changed
@ -51,3 +78,27 @@ var options
func _init(options):
self.options = options
# Set the font size based on the font_size option
_resize_fonts()
func set_option(key: String, value) -> void:
# TODO: sanitize and validate options.
# Don't fire an option change event if they didn't change
if options[key] == value:
return
options[key] = value
emit_signal("option_changed", key)
# Update other options accordingly.
match key:
"font_size":
_resize_fonts()
func _resize_fonts():
for font in options.font_family.values():
font.size = options.font_size