chzyer / readline

Readline is a pure go(golang) implementation for GNU-Readline kind library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Autocomplete CharBackspace behaviour question

tpodowd opened this issue · comments

Hi @chzyer it's me again :-)

I've noticed the following behaviour in Readline which is undesirable.

Steps to repeat:

  1. Make your terminal about 16 columns wide
  2. run readline-demo.go
  3. press return many times so that prompt is last line on the terminal.
  4. press 's' key at the prompt.
  5. press 'TAB' key at the prompt.
  6. you will get a list of 4 choices. on width 17, the prompt will be displayed 6 lines from bottom of terminal and 4 choices in separate lines below.
  7. press 'backspace' key at the prompt (to remove the 's' character).

At this point, the prompt appears to jump up the screen to perhaps 11 lines above the bottom of the terminal. This is the undesirable behaviour.

The reason this happens is that "OnComplete" is called and writes out a full list of completion options based on the zero length buffer. This effectively takes up the 11 lines. It then however exits completemode and the choices end up being cleared so it simply looks like the prompt jumps up. In the demo program we have to make the screen narrow to replicate this behaviour but in a different program where you have lots of choices, the jump happens even on a normal sized terminal.

My question is what should the behavour be:
a) when you hit backspace, it simply exits complete mode
b) when you hit backspace, it offers a potentially larger list of choices

If you press 's' 'TAB' 'e' 'backspace', it does a). Ie. it displays 'say', 'setprompt', 'setpassword', 'sleep' after you press tab, and then it displays 'setprompt' and 'setpassword' after you press 'e' but then if you press backspace to delete the 'e' it exits completion mode rather than reshowing you the 4 choices based on just 's'.

I'm not sure which behaviour you wanted a) or b) but currently it is implementing a) except that it writes out the longer list and can end up jumping the prompt.

To fix for behavour a) without the jump.

diff --git a/operation.go b/operation.go
index b673118..e14658d 100644
--- a/operation.go
+++ b/operation.go
@@ -223,9 +223,6 @@ func (o *Operation) ioloop() {
                                break
                        }
                        o.buf.Backspace()
-                       if o.IsInCompleteMode() {
-                               o.OnComplete()
-                       }
                case CharCtrlZ:
                        o.buf.Clean()
                        o.t.SleepToResume()

To fix for behaviour b) and offer the bigger list.

diff --git a/operation.go b/operation.go
index b673118..880935f 100644
--- a/operation.go
+++ b/operation.go
@@ -225,6 +225,7 @@ func (o *Operation) ioloop() {
                        o.buf.Backspace()
                        if o.IsInCompleteMode() {
                                o.OnComplete()
+                               keepInCompleteMode = true
                        }
                case CharCtrlZ:
                        o.buf.Clean()

I can submit a PR if you like but I wanted to know which behaviour you were aiming for before doing so. Personally, I prefer a).

I'm closing this issue as I have fixed it in a pull request.
#207