Changes `write()` method of native pipe and terminal to accept a
PoolByteArray rather than String. This means that `get_string_from_utf8()`
is no longer called on data coming from PTY and being sent to Terminal.
The terminal state machine already has a UTF8 parser which maintains
its state across calls to `write()`. This means that we can write half
the bytes of a single unicode character in one call and the remaining half
in the next call and the state machine will parse it correctly.
On the other hand, the `get_string_from_utf8()` method of Godot's
PoolByteArray requires that the array contains completely valid UTF8,
otherwise we get errors such as "Unicode error: invalid skip".
The data coming from PTY can be arbitrarily split in the middle of a
unicode character meaning that we will sometimes get errors when calling
`get_string_from_utf8()` on it. This is more likely to occur when there
is a large amount of output (i.e. it's more likely to be split). In other
cases, the data might intentionally contain invalid unicode such as when
printing binary files or random data (e.g. `cat /bin/sh`, `cat /dev/random`).
We avoid these errors by passing the PoolByteArray data directly to the terminal
state machine.
In addition to fixing unicode errors, this commit:
- Prevents repeated calls to pipes `_read_cb()` method that would block Godot
and result in a crash with the message "ERROR: All memory pool allocations
are in use" that resulted from writing data to an ever-increasing number of
PoolByteArrays before any of them could be freed. This could be triggered by
running the `cat /dev/urandom` command after making the change to `write()`
mentioned above.
- Prevents memory leaks by freeing libuv buffers after they have been copied
to PoolByteArrays.
Fixes#55.
Prevents scrollback buffer reset (i.e. scrolling to the bottom of
terminal output) when pressing modifier keys in isolation or when
copying text using the shortcut Ctrl+Shift+C.
Fixes error that would sometimes occur when closing the Terminal after
calling write() but before the VisualServer had finished drawing the
current frame.
Makes for pretty paths when extending scripts:
`extends "res://addons/godot_xterm/terminal.gd"`
vs.
`extends "res://addons/godot_xterm/nodes/terminal/terminal.gd"`
Currently "res://addons/godot_xterm/pty.gd" is acutally `pty_unix.gd`.
This is okay for now as the PTY node is only supported on Unix
platforms. However, we will need to sort it out when adding Windows
support as part of #25.
Also remove the GDXterm namespace.
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`.