Commit Graph

63 Commits

Author SHA1 Message Date
Thomas O'Dowd c30c5a000a Fix terminal resize race conditions
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.
2023-03-05 12:21:35 +09:00
Thomas O'Dowd 86f47fbf9e Fix candidate cleanup redraw issue if Enter key pressed in Complete Mode.
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.
2023-03-04 18:59:22 +09:00
Thomas O'Dowd 5346085511 A Pager to list completion candidates if they don't fit on one page.
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).
2023-03-04 18:59:22 +09:00
Thomas O'Dowd 62ab2cfd17 Fix race condition between writing and prompting.
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.
2023-03-04 18:35:07 +09:00
Thomas O'Dowd d9af567781 Various screen redraw fixes for wide characters, narrow screens etc.
- 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
2023-02-28 11:00:57 +09:00
ChenYe 7f93d88cd5 fixing deadloop when input is filtered 2022-07-15 20:48:48 +08:00
ChenYe 80e2d1961b
restore term when receive signal (#200)
* restore term when receive signal

add `CaptureExitSignal` to capture exit signals and exit gracefull(disabled by default)

* update deps
2022-04-24 21:25:55 +08:00
soopsio f6d7a1f6fb Fix ioloop groutine leaks bug. (#136)
* Fix ioloop groutine leaks bug.

* fix func (o *Operation) ioloop()  L:125 hangs
2017-12-08 09:17:16 +08:00
Eugene Apollonsky 6a4bc7b4fe operation: fix SetConfig races (#131) 2017-10-03 22:59:50 +08:00
Thomas Bradford 707fd8ecaa intercept line rendering using a 'Painter' (#116) 2017-10-01 22:58:28 -05:00
Sagar Mittal 9f56defe66 Add barebones support for yank/paste (#120) 2017-10-01 22:57:50 -05:00
Paul Tagliamonte 41eea22f71 Add two API methods to set RuneBuffer state before prompting the user (#105)
* 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.
2017-03-14 07:49:21 +08:00
Jiří Setnička f892600c35 Ability to filter out input runes (#104)
Could be used to mask/disable some actions (like Ctrl-Z, or searching by
Ctrl-R and Ctrl-S)
2017-02-20 09:51:01 +08:00
chzyer 27fdf0b285 Fix: a backup plan when can't get size of terminal (#71)
* fix (0,0) size

* fix
2016-08-31 23:51:28 +08:00
chzyer b411b0f4b2 fixes: flush chars if got io.EOF without '\n' (#58) 2016-06-19 23:06:37 +08:00
Steven Oud 92c174e5fb Add ClearScreen operation on Ctrl+L (#56)
* Add ClearScreen operation on Ctrl+L

* Remove TODO from clear screen in readme

* Don't use external command for ClearScreen

* Remove duplicate ClearScreen function
2016-05-16 17:59:35 +08:00
chzyer 3ea5940c39 support suspend process (#48)
* support suspend process

* fix suspend in windows

* add comments
2016-04-17 21:05:00 +08:00
chzyer 218eb7fff6 [example] Add a IM example 2016-03-31 10:55:53 +08:00
chzyer 1e409caaf3 return remain line if interrupt. 2016-03-25 17:08:13 +08:00
chzyer b57eccfd02 add remote mode 2016-03-13 18:32:48 +08:00
Cheney 867002449c refactory 2016-03-05 15:45:42 +08:00
Lu Guanqun d45b1ac5fc add a new API to set auto complete 2016-02-23 13:15:23 +08:00
Cheney 15e7be4ac2 add new interface and fixed crash if stdout isn't a tty 2016-02-18 11:25:41 +08:00
Cheney 6368045a0b report error if it save history fail 2016-02-18 08:41:35 +08:00
Cheney 21acaf90fd fixed crash if stdin is not a tty (pipe) 2016-02-17 14:08:55 +08:00
Cheney 07485bbd8f update history interfaces. and support DisableAutoSaveHistory 2016-02-16 16:56:57 +08:00
Cheney 01cffb6cb2 support unique edit line 2016-02-15 10:03:41 +08:00
Ryan Hileman 05d3fbcc2a add stdin remapping support 2015-12-23 21:54:46 -08:00
Cheney 839c0013a8 example: update 2015-11-20 21:00:05 +08:00
Cheney 71e9536f4b add password support 2015-11-20 20:56:42 +08:00
Cheney db2e5eae91 fix bugs: reset buffer after trigger io.EOF/ErrInterrupt 2015-11-20 11:25:30 +08:00
Cheney 7a18498f5b treat `Ctrl+D` + EmptyLine = EOF, `Ctrl+C` = ErrInterrupt 2015-11-19 11:55:07 +08:00
Cheney 5ee706df9b only enter raw mode when calling Readline() 2015-11-09 11:20:26 +08:00
Cheney bfa8c1dfdb add history limitation 2015-10-04 15:23:00 +08:00
Cheney 4dc2ce7141 fixes crash in nil completer #8 2015-10-03 14:15:19 +08:00
Cheney 879224ddc9 refactor 2015-10-02 10:37:21 +08:00
Cheney 79d1bf27b4 add simple vim mode 2015-10-01 22:44:43 +08:00
Cheney 3ccecf626d add readpassword 2015-09-30 14:16:46 +08:00
Cheney 9edb463230 add windows api, ansi writer 2015-09-29 17:49:58 +08:00
Cheney d4826eb059 add ansi writer 2015-09-29 00:26:49 +08:00
Cheney 03d201ab65 add Ctrl+U 2015-09-28 11:13:39 +08:00
Cheney 7537bea372 add set prompt 2015-09-27 18:54:26 +08:00
Cheney 6a53e6406c remove test code 2015-09-27 10:22:53 +08:00
Cheney a81fb5db7a fixed not working in screen #3 2015-09-27 10:12:15 +08:00
Cheney d4ceb57901 let stdout/stderr io.Writer configurable 2015-09-27 09:04:50 +08:00
Cheney 75bbfa6d42 update demo 2015-09-26 01:01:20 +08:00
Cheney 04f86e9c53 add auto complete 2015-09-25 22:56:00 +08:00
Cheney 69871d9ae0 update readme 2015-09-25 12:59:36 +08:00
Cheney af66dc48f7 fix Ctrl+C in search mode do not send EOF 2015-09-25 00:49:55 +08:00
Cheney a904b314b8 kickoff ioloop only needs, solved #1 2015-09-25 00:16:49 +08:00