question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

restoreCursor not working when current line is at bottom of terminal?

See original GitHub issue

I am trying to use a singleColumnMenu to display some options. The idea here is when the user selects an item, the app will:

  1. Clear the singleColumnMenu
  2. Replace it with a .inputField
  3. Gather the input
  4. Redisplay the singleColumnMenu where it was before

I tried some preliminary code to see if I could accomplish steps 1-2, but restoreCursor() is acting in a nondeterministic fashion. I’m on OSX in Terminal.app.

If I cmd-K my terminal to clear the screen, my app works perfectly. In fact I can execute the app a few times and it still works perfectly. However, when my terminal’s prompt get down near the bottom of my terminal screen and I execute my program, the menu is not erased and the input is placed after the menu items. If I cmd-K and run again, everything works fine again.

I’ve attached a gif that shows what’s happening.

Curson Restor Problem

Here is the code:

var term = require( 'terminal-kit' ).terminal ;

var items = [
  'Option 1.' ,
  'Option 2.' ,
  'Option 3.'
] ;

term.saveCursor();
start();

function start() {
  //display the menu
  term.singleColumnMenu( items , ( error , response ) => {
    //restore the cursor to where it was before the menu was displayed
    term.restoreCursor();
    //console.log(`origX=${origX}, origY=${origY}`);
    //term.moveTo(origX, origY);
    term.eraseDisplayBelow();
    //dsiplay the input field where the menu once was
    term(' Enter some text: ');
    term
      .inputField(function( error, input ) {
        term.restoreCursor();
        term.eraseDisplayBelow();
        term.singleColumnMenu( items, (error, response) => { process.exit(); } );
      });
  } ) ;
}

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
cronvelcommented, Nov 15, 2017

@ctataryn Hi, .saveCursor()/.restoreCursor() are deterministic, however you are suggesting it works on a coordinate system based upon the text flow, while in reality it works with the terminal coordinate system.

Let me explain what happened:

  • the cursor is at the bottom of the screen, you save its position
  • some text forces a scrolling of the terminal’s content
  • you restore the saved cursor position, but it has scrolled and the cursor doesn’t care about it: it is indeed restored at the bottom of the screen

But you want to move the cursor at the beginning of the single column menu. Sadly there is no easy way to do it, since terminals don’t track scrolling. They do not emit some magical terminal scrolling event that Terminal-kit would receive, so you are basically on your own because you alone know what your app is doing.

There are a lot of workaround for that, for example:

  • Workaround 1: don’t use .saveCursor()/.restoreCursor(), instead move the cursor up using the appropriate number of line (since you know how many options had been sent to .singleColumnMenu().
  • Workaround 2: before using .saveCursor()/.restoreCursor(), output some \n then call term.up(n) with n matching the number of newline characters: this way you prepare an area big enough to receive your .singleColumnMenu()
0reactions
ctataryncommented, Nov 17, 2017

Fair enough, I’ll change my approach back to the original way. Again, thank you for your attentive help.


From: Cedric Ronvel notifications@github.com Sent: Friday, November 17, 2017 7:36:28 AM To: cronvel/terminal-kit Cc: Craig Tataryn; Mention Subject: Re: [cronvel/terminal-kit] restoreCursor not working when current line is at bottom of terminal? (#59)

@ctatarynhttps://github.com/ctataryn Maybe it’s not well documented here, but when using continueOnSubmit, most keys stop doing anything unless the user cancel its choice with the backspace or delete key (key bindings are configurable).

To be honest, the menu was coded with one menu call per user input in mind.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/cronvel/terminal-kit/issues/59#issuecomment-345245467, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAamB_gig_np3Kd04k4eTmKfZWFTB2QXks5s3YvcgaJpZM4QeFi1.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Save cursor position and restore it in terminal
Are there any way to work with terminal cursor position to store and restore cursor position based on buffer position? You can assume...
Read more >
Refresh first N lines and reset cursor to the end of current line ...
3 Answers 3 ; Clear the screen, move to (0,0), \033[2J ; Erase to end of line, \033[K ; Save cursor position, \033[s...
Read more >
Control cursor position also at bottom of window
I have a slight problem controlling the cursor position in a Bash terminal window. I have a function ask a question and then...
Read more >
Is there a way to prevent the cursor from reaching the bottom ...
I want to find a way to control which row the cursor of the Ubuntu terminal sticks to once the previous rows have...
Read more >
6.2. Cursor Movement
This will NOT work on the terminal emulators that I mentioned that don't accept the save and restore cursor position codes. If you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found