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

Using Blessed instead of blessings #57

Open
thomasballinger opened this issue Nov 25, 2014 · 8 comments
Open

Using Blessed instead of blessings #57

thomasballinger opened this issue Nov 25, 2014 · 8 comments
Labels

Comments

@thomasballinger
Copy link
Member

This would allow a lot of code to be removed:

  • context managers for cbreak etc.
  • way better key naming scheme! Need to make sure it covers as much ground, or is extensible
@jquast
Copy link

jquast commented Nov 25, 2014

I've thought about adding something like term.ctrl('a') and term.meta('a') which returns '\x03' and '\x1ba' programmatically for comparison, so one could do a statement like if term.inkey() == term.ctrl('a')

@thomasballinger
Copy link
Member Author

That would be cool.

A big stumbling block I had was wanting to separate output and input, but cursor queries requiring both, and needing to communicate across the two in case a cursor query read reads too many / the wrong bytes and they need to be shuttled over to key detection. I just looked at using Blessed for this and because of this current separation I have it doesn't look easy - but it might be worth giving up on keeping the two separated, or at least passing the same blessed.Terminal object in to both of them.

@thomasballinger
Copy link
Member Author

I haven't made code progress, but I've written up what I want to change. @jquast Let me know if you'd prefer to be mentioned as someone other than "jquast" on http://ballingt.com/2014/11/29/key-detection-code.html

@jquast
Copy link

jquast commented Dec 1, 2014

'jquast' is just fine. I have some feedback for your open-ended questions I'll share after work.

And thank you for being so kind :)

@jquast
Copy link

jquast commented Dec 2, 2014

doy also advised me not to worry about meta keys - they’re terrible, why would you want to support them?

I have to agree with him. The problem is, meta can be the same as alt, and three different things can happen with alt/meta+i depending on how the client's terminal emulator and keymap is configured.

  • metaSendsEscape: \x1b u is received.
  • eightBitMeta: \xf5 is received.
  • Internationalization: ¨ (underlined) is printed locally, the user then may press 'o' to insert ö, such as firefox is doing for me right now, iTerm also does this, and I think this is most correct -- it allows the swedish folk to write in their natural language.

And what if the user just pressed escape? then nothing happens, so they press the letter 'i'? Is this to be interpreted as ALT + i ?

Instructing the user to re-configure their terminal emulator to be compatible with your program is not recommend. I recommend instead to use the with term.raw() context manager and use only control keys instead.

Pity the emacs user for going through the trouble: http://www.emacswiki.org/emacs/MetaKeyProblems

Curtsies tries to read as much as possible and utilizes this information about what came in on the same read - for example, to tell the difference between plain escape key and escape-prepended other key.

It's perfectly acceptable to get only the \x1b[ of the sequence \x1b[A if using read(1024) when a user presses an arrow key. Telnet, ssh, sockets, protocols, buffers, etc. You can try my bbs at telnet://1984.ws and see blessed being (ab)used, where receiving only portions of a multibyte sequence (MBS) is common. I was getting reports of some keys sometimes not working. It wasn't going to work without timing.

I don’t like having to do a timed delay to detect the escape key, but it sounds like it’s necessary.

I try manually typing "[A" or "OA" in many interfaces at different rates -- on my desktop now: bash and irssi waits forever, doesn't care how slow I type it -- whereas vim emits a bell after 1 second. Anyway that's what the esc_delay parameter for inkey is for.

Many developers struggle with it. Best recommendation is not to present the user with the option of pressing escape. This avoids any noticeable delay.

add escape key-prepended sequences to Blessed

I'm a bit on the fence about supporting these in blessed at all. I'll chew on the idea some more. I have a todo item in the code about it:

        # TODO(jquast): "meta sends escape", where alt+1 would send '\x1b1',
        #               what do we do with that? Surely, something useful.
        #               comparator to term.KEY_meta('x') ?
        # TODO(jquast): Ctrl characters, KEY_CTRL_[A-Z], and the rest;
        #               KEY_CTRL_\, KEY_CTRL_{, etc. are not legitimate
        #               attributes. comparator to term.KEY_ctrl('z') ?

add support in Blessings for currently supported features in Curtsies like distinguishing ctrl-left and ctrl-right from normal forms

Ah yes, I never noticed. These could definitely be added. These keys have meaning for desktop controls on my machine, so it never reaches my emulator unless I disable them.

@thomasballinger
Copy link
Member Author

Thanks so much for reading and feedback. https://github.com/jquast/x84 is pretty sweet.

It'd be a pity to lose readline keys like meta-f and meta-b for folks for whom those work in bash, but if they're correctly identified as sequences this should be fine. For my own reference, master bpython-curtsies currently uses a lot of these: meta-left/right, meta-backspace, meta-f, meta-b, meta-., meta-r, meta-s, meta-d, meta-y, meta-t, meta-u, meta-c.

Needing the delay makes sense because of the buffering issues you mention, but to clarify the current state of Curtsies:

And what if the user just pressed escape? then nothing happens, so they press the letter 'i'? Is this to be interpreted as ALT + i ?

It's perfectly acceptable to get only the \x1b[ of the sequence \x1b[A if using read(1024) when a user presses an arrow key. Telnet, ssh, sockets, protocols, buffers, etc

since \x1b[ isn't a valid MBS, it wouldn't be reported, instead read would be called again - a state machine is still used, whether things came in on the same read is only used to choose the shorter to two MBSs when one starts with the other. (escape key alone instead of\x1b[A, or \xc3 (eightBitMeta+C) and \xc3\x9f. However this is a problem if it's acceptable to get only the \x1b part of \x1b[A in a single read, and obviously is a problem with eightBitMeta. Plan (were it not to switch to Blessed) would be to kill eightBitMeta and to special case escape, so the whole looking-for-sequences-that-are-prefixes-of-other-sequences-and-using-whether-bytes-were-read-together-as-a-tiebreaker thing isn't necessary because this way except for escape, no MBS is the prefix of another.

I'm not sure I can use terminal.raw instead of cbreak, there are pros and cons. I definitely want to stop using a context manager for the duration of the program and start using it with each call to inkey() unless there are timing or buffer issues with this. If jumping in and out of `these modes takes time, then it has to be cbreak.

@thomasballinger
Copy link
Member Author

Proposal for quite a rewrite:

  • escape sequence parsing should use Blessed code
  • Back FmtStr with Blessed strings FmtStr class knows nothing about about how to output escape sequences - it uses Blessed for this. The only functionality unique to Curtsies is the array-based compositing. FmtStr class uses wcwidth to guess at width, ideally through Blessed
  • Outsource keypress handling to Blessed
  • Keep a Curtsies name lookup table, but do everything in terms of the keypresses given by Blessed.

@thomasballinger
Copy link
Member Author

see https://github.com/thomasballinger/curtsies/tree/switch-to-blessed for removal on keypress handling

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

No branches or pull requests

2 participants