The runebuf, search and complete data structures all maintain their
own cache of the terminal width and height. When the terminal is
resized, a signal is sent to a go routine which calls a function
that sets the new width and height to each data structure instance.
However, this races with the main thread reading the sizes.
Instead of introducing more locks, it makes sense that the terminal
itself caches it's width and height and the other structures just
get it as necessary. This removes all the racing.
As part of this change, search, complete and runebuf constructor
changes to no longer require the initial sizes. Also each structure
needs a reference to the Terminal so they can get the width/height.
As the io.Writer parameter is actually the terminal anyway, the
simpliest option was just to change the type from the io.Writer to
Terminal. I don't believe that anyone would be calling these
functions directly so the signature changes should be ok. I also
removed the no longer used OnWidthChange() and OnSizeChange()
functions from these three structures.
The completion candidates were not being cleaned up properly if the Enter
key was pressed while in complete mode. This could lead to both candidates
and any program output being mixed on the screen. Cleanly exit complete mode
and redraw when the Enter is pressed while in complete mode.
Main Features:
- If there are too many candidates returned by the completer,
completemode and completeselectmode did not work properly.
Similar to the bash completion pager, list candidates and
offer "--More--" on the end of each page. User can select
" ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to
stop listing. When paging completes, we also exit out of
completion mode.
- Added aggregate completion when entering completeselectmode
where the candiddates dwindle down sharing a larger common
prefix. This makes typing a little faster than having to
select. More bash-like behaviour.
Other Fixes:
- Fix various crashes where candidates are too wide for the
width of the screen and causes division by zero.
- Fix crash with wide (Asian characters) in completion.
- Streamline redrawing as CompleteRefresh was called too
often.
- Fix crashes around ctrl-a and ctrl-b in select mode when
candidates don't fit on a line
- Fix prev/next candidates in select mode when candidates
don't fit on a line
- Fix crash when ctrl-k was pressed in select mode. This
caused us to exitselectmode which cleaned up all the data
but left us in complete mode such that if CompleteRefresh
was callled directly, the data was not initialized.
- Fix complete and select mode redraw issues when candidates
did not fit on one line.
- Fix cursor position issues after CompleteRefresh especially
if the prompt and buffer also went over 1 line.
- Fix redraw issue where exiting completion mode using
certain key presses leaves candidates on the screen.
Fixes for Windows:
- Use window size for visible height/width instead of buffer size
- Adjust for Window's EOL behaviour.
Notes:
- Added Height info to different structures as the decision to
page or not required height information.
- Added OnSizeChange(). Didn't know if I could get rid of the
OnWidthChange()? Would be nice to remove the Width stuff and
just have Size (width + height info).
Introduce a new operation.isPrompting field which is true from when a
prompt has been written until data is returned to the caller.
When Write is called on the wrapWriter to write to stdout or stderr,
check if we are currently prompting the user for input and if so
clean up the prompt and write the data before redrawing the
prompt at its new location after the written data.
Previously terminal.IsReading() was used for this, but this had various
race conditions and it was not correct to check this field to make
prompt and buffer redrawing decisions. In turn, I removed all the
isReading code also. The old isReading() check was actually checking
if the terminal goroutine was actively waiting for more input.
- Don't overwrite existing text on same line as the prompt
- Don't refresh screen when simply appending characters to buffer
- Don't refresh screen unnessarily when pressing enter key
- Handle prompts longer than screen width.
- Fix wide characters in prompt
- Fix screen edge issue when next character is wide.
- Fix screen edge issue for masked characters
- Fix narrow masked characteter, masking wide input
- Fix wide masked character, masking narrow input
- Reworked backspacesequence for index to use same algorithm as used
for lineedge and reduce the control sequences to 2.
- Reworked cleanup to incorporate initial cursor column position
and avoid overwriting existing text as well as simplifying the
control sequences used.
- Fixed double width character detection and updated unit tests
- Handle emoji in text or prompts.
- Implement windows ANSI absolute horizonal position ansi code.
- Get windows cursor position directly and don't send ansi DSR code
- Don't write out empty mask runes
- Cleanup - removed unused hadCLean variable
* Expose RuneBuffer.Set through Operation's API
This allows a user to prefill a line before the user is given a prompt,
so that you can provide a default, user-editable input line.
* Add a Instance.ReadlineWithDefault API method
This will pre-fill the Operation.RuneBuffer with text before prompting
the user, and provide her with a method to edit the provided default.
* Add ClearScreen operation on Ctrl+L
* Remove TODO from clear screen in readme
* Don't use external command for ClearScreen
* Remove duplicate ClearScreen function