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

Handling of escape codes ending in tilde #26

Closed
kennylevinsen opened this issue Apr 22, 2014 · 3 comments
Closed

Handling of escape codes ending in tilde #26

kennylevinsen opened this issue Apr 22, 2014 · 3 comments

Comments

@kennylevinsen
Copy link

Escape codes ending in tilde (delete, pageup/down, home, end, F-keys, ...) are incorrectly handled.

They end up dying in the final lines of _argument:

            ...
        else:
            self.dispatch(self.csi[char], *self.params)

where char is '~', which make no sense as a csi sequence. While I am not the strongest in the ancient arts of VT100 escape sequences, I believe that tilde-postfixed sequences should be interpretted as an argument-free CSI sequence.

            ...
        else if char == '~':
            char = self.params[0]
            self.dispatch(self.csi[char])
        else:
            self.dispatch(self.csi[char], *self.params)

... would be a possible quick hack.

I use the following snippet to obtain support for tilde-postfixed sequences in a very hacky fashion, as well as add a few keys (Plus addition of \x7f which I opened another issue for):

class ByteStream(ByteStream):
    def __init__(self):
        super(ByteStream, self).__init__()
        self.basic.update({
                          '\x7f': 'backspace'
                          })
        self.csi.update({
                        1: 'home',
                        2: 'insert',
                        3: 'delete',
                        4: 'end',
                        5: 'page_up',
                        6: 'page_down',
                        15: 'f5',
                        17: 'f6',
                        18: 'f7',
                        19: 'f8',
                        20: 'f9',
                        })

    def _arguments(self, char):
        try:
            super(ByteStream, self)._arguments(char)
        except KeyError:
            if char == '~':
                char = self.params[0]
                self.dispatch(self.csi[char])
            else:
                raise
@superbobry
Copy link
Collaborator

I was googling for a spec. for these ~ CSI codes and found a section in XTerm manual, which terms them "VT220-style Function Keys". AFAIK they aren't a part of VT220 spec., but I think it would be nice if pyte supported them.

Update: actually, you can achieve the functionality you need with a trivial modification of pyte.Stream.

import pyte
from pyte import ctrl


class CustomStream(pyte.Stream):
    csi = pyte.Stream.csi.copy()
    csi["~"] = "function_key"


class CustomScreen(pyte.Screen):
    def function_key(self, key_code):
        print(key_code)


if __name__ == "__main__":
    stream = CustomStream()
    screen = CustomScreen(80, 24)
    stream.attach(screen)
    stream.feed(ctrl.CSI + "25~")  # F13
    # ^ prints 25

If this works for you, feel free to close the issue :)

@kennylevinsen
Copy link
Author

It works as a hack. I might make a pull request one day when/if I remember to that adds them as real unique events, instead of just all function_key's, just to satisfy my OCD's.

Thanks for the help! I'll find something else to complain about. ;)

@superbobry
Copy link
Collaborator

Well, it's not really a hack, because ~ is a "command" with key code as argument. As for separate events, I'm not sure it's worth doing (in pyte code), because the default Screen doesn't know anything about function keys.

Anyway, feel free to reopen the issue if you have any troubles with this solution.

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

2 participants