Commit Graph

256 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 586d8eebeb Fix simple race condition related to offset calculations introduced. 2023-02-28 11:09: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
Thomas O'Dowd 8e4bd417b9
Handle keypad mode cursor key escape sequences. (#203)
Normally the terminal uses CSI escape sequences when the UP, DOWN,
LEFT, RIGHT and HOME, END keys are pressed. These look like the
following ESC [ A etc, where ESC [ is the CSI sequence.

xterm and other terminals however can generate an alternative
escape sequence called SS3 if in the application keypad mode.
This sequence is ESC O A etc.

Bash readline understands both modes so nowadays you rarely
see OA being printed when you press the up arrow while the terminal
is using the keypad mode. readline currently does not understand
these sequences.

To test this fix, I used an xterm and put it in keypad mode
using the command "tput smkx". Then I started the readline-demo
and tried using arrow keys. Without this fix, OA is printed when
I press up. With this fix, readline fetches the previous command
as per regular mode. After testing you can escape back to
regular mode using "tput rmkx".
2022-05-20 21:29:21 +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
Derick Rethans c34436b973
Added 'os400' (#201)
As per https://github.com/chzyer/readline/pull/175#issuecomment-1100887727
2022-04-18 20:41:19 +08:00
Clément Chigot a5e9f81cc2
AIX support (#175)
This commit adds support for AIX operating system.

 - move term_solaris.go to term_nosyscall6.go. AIX like solaris doesn't
provide syscall.Syscall6 and must rely on x/sys/unix in order to perform
syscalls.

 - This patch won't work with versions prior to 1.13 because it needs
some constants added by https://go-review.googlesource.com/c/go/+/171339.
2022-04-17 16:50:25 +08:00
ChenYe a11d8f26cf add go.mod and remove unnecessary dep 2022-04-13 22:35:28 +08:00
Jim-wiselike 2972be24d4 Modify the display width for Chinese characters and so on (#145)
The display width will not be right if there have Chinese characters in the display. It will overflow the line, if the Chinese characters are at the end of a line. And makes "lines" value not the right number of line rows,  which makes "239: fmt.Fprintf" produce wrong output.
2018-06-03 21:26: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
François-Xavier Aguessy 40d6036c33 Fix panic 'integer divide by zero' when terminal width too low (#137) 2017-12-08 09:16:05 +08:00
Abiola Ibrahim a4d5111b61 Fix panic for ReadPassword (#133) 2017-11-03 21:19:23 +08:00
Eugene Apollonsky 6a4bc7b4fe operation: fix SetConfig races (#131) 2017-10-03 22:59:50 +08:00
mrsinham 9cc74fe5ad Prefill user input (#101)
* Using a fillable stdin reader

* Adding some documentation to the new features
2017-10-02 20:43:15 +08:00
mrsinham af545c8af6 enabling disabling history (#102) 2017-10-02 20:42:28 +08:00
mrsinham aee0fa669f fix: on linux multine move was not working (#103)
on linux, if you want to change line, \b are not enough. You need to change line
and move to the right.
2017-10-02 20:39:53 +08:00
Saeed Rasooli aa9ed7db49 NewEx: fix panic if cfg.Painter is not given (#129) 2017-10-02 14:46:29 +08:00
Jelmer Snoeck c6c3e8d906 Add support for bold text. (#106)
Currently, bold text isn't supported. This adds the support for bold
text formatting.
2017-10-01 22:59:06 -05: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
Edward Betts 045fff973b correct spelling mistake (#127) 2017-10-01 22:57:10 -05:00
Davor Kapsa 8d510b4136 travis: update go version (#128) 2017-10-01 22:55:11 -05:00
Jordan Lewis 01c4e90c35 Bugfix in rewriteHistory (#121)
Previously, rewriteHistory was incorrect - it did not preserve the
newlines between history lines, which corrupts the history file.
2017-10-01 22:53:35 -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
Gereon Frey 8a1389155f Solaris support (#110)
* Add support for solaris

* Change state to handle system dependent termios type.
* Move syscalls to get and set termios to functions in files only built
  for respective platforms.
* Create `term_unix.go` go file built on all supported unices except
  solaris with types and functions valid for all of them.
* Change `MakeRaw` to set VMIN and VTIME to default values.

Fixes #95.

* Fix error handling

Doing the string comparison could be improved, but at least we should
return an error, if it is not "errno 0".
2017-03-13 07:57:45 +08:00
Kenneth Shaw 784bd70fe0 Adding knq/usql to README.md (#107)
usql is a new project that is making extensive use of readline. usql is
roughly 3 days old, and already has over 1100 stars. This change adds
usql to the README.md and reorders projects listed in the "Repos using
readline" section.
2017-03-05 19:31:14 +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 eef24db1d5 fix terminal data race (#99) 2017-01-25 11:55:32 +08:00
Remi Reuvekamp c914be64f0 Fix panic: runtime error: slice bounds out of range (#94)
Reslicing line[10:] went wrong if only 'setprompt' was entered, without a space after.
2016-11-06 12:23:43 +08:00
chzyer 25c2772d5f fix deadlock in cancelable stdin (#89)
* fix deadlock in cancelable stdin

* fix notify back

* [cancelable stdin] fix c.notify
2016-10-06 12:35:07 +08:00
chzyer 94eaec69a7 add HistorySearchFold (#86)
* add HistorySearchFold

* [history] fix test
2016-10-03 14:51:04 +08:00
Ben Browning bc5e387904 Fix column padding calculation to prevent wrapping (#83)
The calculation to determine how many spaces to use when padding
columns wasn't taking into account the length of the 'same' portion of
the completions and was only using the length of the completion
itself. This frequently caused the printed completions to wrap, making
the completion list much harder to read.
2016-09-29 09:01:11 +08:00
chzyer 283f5429f7 Bugfix/datarace prompt (#81)
* fix data race in PromptLen

* add lock for all operation in RuneBuffer

* add race test

* update travis
2016-09-15 18:11:25 +08:00
chzyer 820d6f2766 fix data race in PromptLen (#80) 2016-09-10 16:03:59 +08:00
chzyer 31ab3eee0c remove unused field 2016-09-04 21:05:21 +08:00
chzyer 6cbf970b0b lazy init CancelableStdin() (#78) 2016-09-04 21:02:24 +08:00
chzyer edfa7c9dbf lazy fire ioloop (#77) 2016-09-04 20:49:14 +08:00
chzyer bc5c91eb5b remove unused files 2016-09-03 11:26:39 +08:00
chzyer f533ef1caa update readme 2016-09-02 22:37:16 +08:00
chzyer 31eb6be473 support insert tag char (#74) 2016-09-02 20:10:31 +08:00
chzyer 4ffff9f41c fix cancelablestdin 2016-09-01 20:01:12 +08:00
chzyer 6cbc078c57 let stdin cancelable (#72) 2016-09-01 18:13:06 +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
Mehrdad Arshad Rad 8159bd380c mylg added to README->Who is using Readline (#70) 2016-08-24 22:42:54 +08:00
Nathan VanBenschoten a193146c91 Fix deadlock on rewrite of opHistory when history limit is reached (#69)
It is possible for `opHistory.Rewrite` to be called from
`opHistory.historyUpdatePath`. This is problematic, because both methods
grab a lock, and Mutexes in go are not reentrant. This change pulls out
the logic in Rewrite into `opHistory.rewriteLocked`, and retains the
public facing method.
2016-08-12 10:11:21 +08:00
chzyer c144c8dde4 [readme] update who is using readline 2016-07-29 17:49:00 +08:00