Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get the input character #1100

Closed
smalltimoo opened this issue Oct 31, 2017 · 12 comments
Closed

How to get the input character #1100

smalltimoo opened this issue Oct 31, 2017 · 12 comments

Comments

@smalltimoo
Copy link

Details

  • Browser and browser version: latest
  • OS version: windows
  • xterm.js version: latest

Steps to reproduce

  1. I enter characters on the interface, for example: pwd
  2. When I press the Enter key, how do I get the text you just entered the ‘pwd’ ?
@parisk
Copy link
Contributor

parisk commented Oct 31, 2017

I think what you need is utilizing the following xterm events (or a combination of these two):

  • key (Emitted when the terminal handles a keydown or keypress event.)
  • lineFeed (Emitted when the terminal gets a line feed or new line character)

@parisk
Copy link
Contributor

parisk commented Oct 31, 2017

Since there doesn't seem to be anything we have to implement code-wise for these, I move forward with closing this issue.

For discussions on using xterm.js, you can also use the following channels:

Cheers 😄.

@parisk parisk closed this as completed Oct 31, 2017
@smalltimoo
Copy link
Author

smalltimoo commented Nov 1, 2017

e.target.value get the last charset 'd',but i want get the 'pwd',what should I do

@smalltimoo
Copy link
Author

C:\Users\wuyql\Desktop\xterm>pwd
i want get 'pwd' and not want before this

@parisk
Copy link
Contributor

parisk commented Nov 1, 2017

@smalltimoo you can keep "keys" captured via the key event in a buffer, and get the content of that buffer on lineFeed.

If you still need some help with this, feel free to reach out at https://gitter.im/sourcelair/xterm.js 😄.

Example

let myBuffer = [];

// This is an xterm.js instance
term.on('key', function(key, e) {
  myBuffer.push(key);
});

term.on('lineFeed', function() {
  let keysEntered = myBuffer.join('');  // Or something like that
  myBuffer = [];  // Empty buffer
});

@mofux
Copy link
Contributor

mofux commented Nov 1, 2017

I'd love to see a plugin that can extract the command from the input line and emit an event once the command is submitted. Unfortunately it is not easy to get right. The solution above works great to capture a sequence of input keys, but imagine the user mistyped something, deletes some characters, jumps to a character using the arrow keys and then adds something in the middle of a word... uff. The user could also press the arrow up key in the middle of typing, which in most prompts will replace the current input line content with the last command from the history...

I think the only way to tackle this is to wait for the lineFeed event, then check if the terminal is in normal buffer, then make sure that the cursor is in the last printed line, then try to get the last line of input, then try to resolve which part of that line belongs to the prompt, and then extract the command...

@parisk
Copy link
Contributor

parisk commented Nov 1, 2017

Yep, this would need some heuristics.

The data event could be of help as well.

@mofux
Copy link
Contributor

mofux commented Nov 1, 2017

It would be very easy if the end of the prompt (PS1) would be marked with a special control character, but afaik there is no such thing...

@jerch
Copy link
Member

jerch commented Nov 1, 2017

I'd love to see a plugin that can extract the command from the input line and emit an event once the command is submitted.

Imho this is more a feature request for a shell extension than for a terminal emulator. The emulator has no knowledge of the foreground process nor the input handling, it just pumps input data and displays some (potentially total different) response (imagine the line end is not marked by NL for some reason which is totally legal). The shell on the other hand knows the foreground process (if it has job control) and is the first candidate to be asked "What command did I just enter" ...

@Tyriar
Copy link
Member

Tyriar commented Nov 1, 2017

Related:

@mofux
Copy link
Contributor

mofux commented Nov 1, 2017

@Tyriar Thanks for the references, very useful!
@jerch Thanks for your thoughts, I agree this would be the most reliable way, but as the baking shell would have to support it, there's almost no chance this will ever be widely supported 😢

While reading through #576 I came up with another hack that could potentially work:

Image with every lineFeed event (and after making sure that we are in the normal buffer, and the cursor is in the last line of the screen), we would send an invisible, self-defined escape sequence right after it. When doing so, this escape sequence should get echoed back to us in the next line, and in theory it should mark the very first cell right after the prompt. From that point it should be easy to parse the command...

@Tyriar
Copy link
Member

Tyriar commented Nov 1, 2017

@mofux that's basically the idea behind #576, the problem though is that each shell needs to be explicitly supported and I'm not sure cmd or PS can support it as $PS1 doesn't exist there. There are a bunch of reasons why a generic solution won't work using lineFeed:

  • The cursor is pretty much always on the end of the line when a LF happens, regardless of whether it's the prompt or not
  • winpty hides the cursor before sending the LF (I think this happens all the time)
  • Multi-line prompts exist
  • zsh powerline prompt have text on the right of the cursor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants