cronvel / terminal-kit

Terminal utilities for node.js
MIT License
3.09k stars 200 forks source link

.getCursorLocation() timed out #74

Open FranklinWaller opened 5 years ago

FranklinWaller commented 5 years ago

Executing term.inputField results in the following error:

    at Promise.resolveSafeTimeout.then (webpack:///./node_modules/terminal-kit/lib/Terminal.js?:1522:16)
    at Promise._execOneFulfillHandler (webpack:///./node_modules/seventh/lib/core.js?:163:19)
    at Promise._execFulfillHandlers (webpack:///./node_modules/seventh/lib/core.js?:152:9)
    at Promise._resolveValue (webpack:///./node_modules/seventh/lib/core.js?:108:8)
    at Promise.resolve (webpack:///./node_modules/seventh/lib/core.js?:101:14)
    at fn.result_ (webpack:///./node_modules/seventh/lib/core.js?:77:9)
    at Timeout.setTimeout [as _onTimeout] (webpack:///./node_modules/seventh/lib/misc.js?:90:23)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5) code: 'timeout' }```

Here is my code:

term.inputField(function (error: any, userInput: string) { if (error) { console.log('[Input] error -> ', error); } else { console.log(userInput) } });



I'm using Mac OS 10.14 Mojave and Nodejs v7.8.0
cronvel commented 5 years ago

@FranklinWaller What is your terminal application? It seems to not support requesting cursor location. The iTerm terminal has been reported as working fine.

FranklinWaller commented 5 years ago

@cronvel I’m using the default macOS terminal without any plugins

afturner commented 5 years ago

This is also occurring to me, it may have something to do with stdin/stdout handling. I have a ctrl+c handler that goes something like this:

  process.stdin.setRawMode(true);
  process.stdin.resume();
  process.stdin.setEncoding('utf8');
  process.stdin.on("data", (key) => {
      safeExit(key)
    } else {
      process.stdout.write(key)
    }
  });

Commenting this code out causes the issue to go away. Perhaps it's due to "setRawMode?"

EDIT: It definitely has something to do with setting the encoding to utf8.

EDIT 2: Okay, removing changing the encoding, and then doing let key = Buffer.from(raw).toString() to get the utf8 version from the stdin callback seems to fix the issue. Writing back out to stdout seems to be unnecessary now for some reason.

cronvel commented 5 years ago

@afturner Thanks for reporting. However, you may want want to use Terminal-kit for input handling, something like this:

var term = require( '../lib/termkit.js' ).terminal ;
term.grabInput() ;
term.on( 'key' , name => {
    if ( name === 'CTRL_C' ) {
        safeExit() ;
    }
    // ...
} ) ;

It's best not to interfere with process.stdin / process.stdout when using Terminal-kit (since the lib does things with those objects too).

Your-Name-Here commented 4 years ago

This is still happening when called from a child process due to using a process manager like nodemon or supervisor. @cronvel

cronvel commented 4 years ago

@Your-Name-Here That's strange... Does it happen if you use term = require('terminal-kit').realTerminal? (which is capable of escaping from pipe, reaching the TTY even if stdin/stdout is not a TTY).

Also it's a bit unusual to listen for key events inside a daemon, I'm curious to know why you are doing that.

Your-Name-Here commented 4 years ago

@Your-Name-Here That's strange... Does it happen if you use term = require('terminal-kit').realTerminal? (which is capable of escaping from pipe, reaching the TTY even if stdin/stdout is not a TTY).

When I tried that it returned {"errno":-4058,"syscall":"open","code":"ENOENT","path":"/dev/tty"} after crashing.

Also it's a bit unusual to listen for key events inside a daemon, I'm curious to know why you are doing that.

I'm not sure what you mean by daemon. Maybe I'm not understanding what a process manager does behind the scenes. The process that's utilizing terminal-kit is certainly not a daemon. Am I wrong to think that supervisor app.js [options] would not turn app.js into a child process of the supervisor process, watching for crashes in the child process and restarting the child process?

sylv256 commented 4 years ago

This is also happening to me. No idea why, but it does. It does this as soon as I use one the "term.inputField" method. I'm using nodemon too.

cronvel commented 4 years ago

@TehcJS Which OS/Terminal?

mkey commented 4 years ago

Hello @cronvel,

I'm seeing this issue as well. My code:

const term = require('terminal-kit').terminal;
term.inputField((error, input) => {
    console.log(error, input);
    term.green('Your input: %s', input);
});

Output:

C:\Users\user\Desktop\node\dbpinger\server>node terminal
Error: .getCursorLocation() timed out
    at C:\Users\user\Desktop\node\dbpinger\server\node_modules\terminal-kit\lib\Terminal.js:1441:16
    at Promise._execOneFulfillHandler (C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\core.js:185:20)
    at Promise._execFulfillHandlers (C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\core.js:171:9)
    at Promise._resolveValue (C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\core.js:123:62)
    at Promise.resolve.Promise.fulfill (C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\core.js:115:14)
    at C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\core.js:89:22
    at Timeout._onTimeout (C:\Users\user\Desktop\node\dbpinger\server\node_modules\seventh\lib\misc.js:90:24)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7) {
  code: 'timeout'
} undefined
Your input: (undefined)

My system windows 7 64bit. I tried using default cmd, Powershell and cmder, all with same results. terminal-kit version: 1.35.3

cronvel commented 4 years ago

@mkey As usual, windows has many issues with terminals. I'm afraid but as long as they don't support cursor location request, there is nothing I can do on my end. It's a windows issue, not a terminal kit one.

mkey commented 4 years ago

@cronvel thanks for the information. I'm assuming this situation can't be remedied by an alternative command interpreter under windows?

cronvel commented 4 years ago

@mkey I heard some positive feedbacks with git-bash and similar projects. I didn't run any Windows for years, so I can't really check by myself.

mkey commented 4 years ago

@cronvel good move, not running windows. I'm still on 7 and this is the end of the line for me, as far as MS is concerned. Regarding the issue at hand, I tried installing the latest git-bash and it's showing the same error, basically. I had an older version installed prior to upgrading it just now and that one seemed to give a bit more details on the error (said "terminal is not capable") but with the same end result. No worries, I'll make due with a menu. Thanks.

cronvel commented 4 years ago

@mkey @TehcJS @FranklinWaller @afturner @Your-Name-Here and other: Since this issue has been a pain in the a* for many years, and since I cannot make it work if the host terminal doesn't support cursor location request, I'm asking you if you think it would be a decent* fallback if the .inputField() (and other widgets) put itself on the last line.

I need to be sure where the widget is on the terminal, displaying it at the last line after creating a new line (instead of putting it on the current cursor location) does not erase any content. It just skips a bunch of line, which is certainly preferable over throwing an exception/crashing the app.

What do you think about it?

mkey commented 4 years ago

@cronvel I think that would be perfectly acceptable. Any functionality is preferable over none any day of the week. Could it be configured on which line one would like to have it placed?

cronvel commented 4 years ago

@mkey It has always been possible to specify the x,y coordinate of an inputField, however I just discovered that this feature was not documented, it's fixed now (doc).

Also now, as of v1.35.5, .inputField(), .progressBar() and all .*Menu() widget fallback to the last line position when requesting cursor location is not possible on the terminal (mainly a Windows problem).