Coder Social home page Coder Social logo

jquast / blessed Goto Github PK

View Code? Open in Web Editor NEW

This project forked from erikrose/blessings

1.1K 1.1K 70.0 7.51 MB

Blessed is an easy, practical library for making python terminal apps

Home Page: http://pypi.python.org/pypi/blessed

License: MIT License

Python 100.00%
cli curses terminal

blessed's People

Contributors

avylove avatar croepha avatar dflock avatar dlax avatar elmiko avatar erikrose avatar fishermans-friend avatar jquast avatar jwezel avatar liquiddandruff avatar lowks avatar maybetree avatar msabramo avatar mwchase avatar neob91 avatar numerlor avatar olen avatar pyfisch avatar sbraz avatar stefanholek avatar thomasballinger avatar vegarsti avatar vitek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blessed's Issues

Location() context manager doesn't seem to work on Mac OSX Terminal

I'm not sure wether this is a bug or I'm missing something, but location() context manager doesn't work on the OS X Terminal. E.g.:

term = Terminal()
with term.location(0, term.height - 1):
    print('Here is the bottom.')
print('This is back where I came from.')

the cursor position doesn't go back to its previous position upon exit, so that this is back where I came from is actually printed after the line here is the bottom.

Great library anyway, thanks!

terminal without or with invalid locale raises exception

output of locale(1):

LANG="en_US"
LC_COLLATE="en_US"
LC_CTYPE="en_US"
LC_MESSAGES="en_US"
LC_MONETARY="en_US"
LC_NUMERIC="en_US"
LC_TIME="en_US"
LC_ALL=

raises an exception,

>>> blessed.Terminal()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "blessed/terminal.py", line 195, in __init__
    self._keyboard_decoder = codecs.getincrementaldecoder(self._encoding)()
  File "lib/python2.7/codecs.py", line 971, in getincrementaldecoder
    decoder = lookup(encoding).incrementaldecoder
LookupError: unknown encoding:

Fails with PYTHONOPTIMIZE=2

Works:

$ python
Python 3.5.0 (default, Sep 23 2015, 04:42:00)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import blessed
>>>

Doesn't work:

$ PYTHONOPTIMIZE=2 python
Python 3.5.0 (default, Sep 23 2015, 04:42:00)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import blessed
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/davidbutler/projects/misc/blessed/blessed/__init__.py", line 10, in <module>
    from blessed.terminal import Terminal
  File "/Users/davidbutler/projects/misc/blessed/blessed/terminal.py", line 63, in <module>
    from .sequences import (SequenceTextWrapper,
  File "/Users/davidbutler/projects/misc/blessed/blessed/sequences.py", line 244, in <module>
    class Sequence(six.text_type):
  File "/Users/davidbutler/projects/misc/blessed/blessed/sequences.py", line 341, in Sequence
    """)
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str'
>>>

Terminal.length('\x1b[m') returns wrong length of 2.

>>> from blessed import Terminal
>>> term = Terminal()
>>> text = u'\x1b[1m\x1b[30m13:55\x1b[m \x1b[1m\x1b[30m-\x1b[m\x1b[m\x1b[37m*\x1b[m\x1b[m\x1b[1m\x1b[30m-\x1b[m\x1b[m Use \x1b[1m/QUIT\x1b[m\x1b[m to quit. Other commands: \x1b[1m/HELP\x1b[m\x1b[m\x1b[37m, \x1b[m\x1b[m\x1b[1m/ME\x1b[m\x1b[m\x1b[37m, \x1b[m\x1b[m\x1b[1m/TOPIC\x1b[m\x1b[m\x1b[37m, \x1b[m\x1b[m\x1b[1m/NAMES\x1b[m\x1b[m\x1b[m'
>>> term.wrap(text, 46)
[u'\x1b[1m\x1b[30m13:55\x1b[m \x1b[1m\x1b[30m-\x1b[m\x1b[m\x1b[37m*\x1b[m\x1b[m\x1b[1m\x1b[30m-\x1b[m\x1b[m Use \x1b[1m/QUIT\x1b[m\x1b[m to quit.',
u'Other commands: \x1b[1m/HELP\x1b[m\x1b[m\x1b[37m, \x1b[m\x1b[m\x1b[1m/ME\x1b[m\x1b[m\x1b[37m,',
u'\x1b[m\x1b[m\x1b[1m/TOPIC\x1b[m\x1b[m\x1b[37m, \x1b[m\x1b[m\x1b[1m/NAMES\x1b[m\x1b[m\x1b[m']

I added line breaks for clarity in the output of term.wrap(). Here's what it winds up wrapping to:

13:55 -*- Use /QUIT to quit.
Other commands: /HELP, /ME,
/TOPIC, /NAMES

The first line is 28 characters. Even by adding ' Other', it would only be 34 characters--well within the limit of 46 that I'm using in the example. The second line is 27 characters. By adding ' /TOPIC,', it would only be 32 characters--again, within the limit of 46.

I'm wondering if this is because the output is messy and has a lot of repeated \x1b[1m sequences...

bin/worms.py example doesn't work with xterm, Blue Screens

When I start bin/worms.py in xterm (Linux, X11) it blue screens my terminal with a single green highlighted 1. It does not respond to any input except q. After about 10 seconds, during which no input is supplied, it exits on it's own and displays a score of 100:

$ time bin/worms.py
score: 100
bin/worms.py  0.11s user 0.01s system 1% cpu 6.681 total

The problem does not occur in urxvt or the virtual terminal.

When I checkout ca63df7ec4 the game plays like clone of snake and works fine in xterm. When I checkout 11e5c49 I get the behaviour described above.

If there is anything you would like me to try out I would be happy to do so and find the cause of this strange incompatibility.

FormattingString is not picklable

>>> from multiprocessing import Pipe
>>> from blessed import Terminal
>>> r, w = Pipe()
>>> val = Terminal().move(1, 1)
>>> type(val)
<class 'blessed.formatters.FormattingString'>
>>> w.send(val)
>>> r.recv()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __new__() takes exactly 3 arguments (2 given)

256 color and 24-bit true color support

This backports upstream issue erikrose#67
Some background: https://gist.github.com/XVilka/8346728
See also erikrose#30 (comment)

In brief: if number_of_colors is 256, we can pretty safely assume to support emitting 256 colors, and this is currently possible with term.color(196) or some such. However, as a "formatting name" it is deplorable. It would require using a reference guide to map colors-by-number. I actually spent some time trying to find a mapping and came up pretty short, I guess you would run a script that emits all 256, pick the one you like, and note it down.

As an API, supporting {t.bold_color196} is very much against the "easy to write, easy to read" philosophy that Blessings encourages. What follows is my draft proposal.

rgb method

@property
def rgb(self, red, green, blue)
   """
   Return a callable accepting arguments ``(red, green, blue)``, which emit a sequence approximated to the colorspace of the terminal bound by :attr:`number_of_colors`. The values of each color are 0-255.
   (...)
   """

This would be exactly like the existing color(n), except if given rgb(255, 50, 100) on a terminal where number_of_colors is 16, this would be "coerced" (or downsampled) as though you called rgb(255, 85, 85) which is exactly the expected color in the CGA palette, emitting the exact same sequence of term.bright_red or color(12).

true_colorspace context manager

@contextmanager.contextlib
def true_colorspace():
   """
   Context manager that enables mapping of compound color names and :attr:`rgb` values
   to a True color (24-bit, 16,777,216 colors) colorspace.
   """

This is necessary as a context manager: we cannot determine whether the given terminal emulator supports true colors: There is no xterm-16777216color terminal name, or anything like it. There is no situation that I know of where the terminal capability database for number_of_colors could return 16,777,216. A terminal emulator that supports it provides no method to query whether or not it supports it. For those who know their intended audience/emulator, they may rightly go ahead and use them, or provide configuration to enable it through the use of such context manager.

Compound Formatters as X11 color names

Use the official X11 color names, http://en.wikipedia.org/wiki/X11_color_names as compound formatters. These are mapped by their hexidecimal values to rgb() to emit the appropriate sequence. This allows one to use "deep_pink", which is (255, 20, 147), but on a 16-color terminal it would be mapped to the same sequence as term.bright_red.

terminal.wrap acts strangely when string includes '\n'

I am unsure if this is a bug, but it seems as if the wrap function does not work as intended when working with strings including carriage returns, as demonstrated by the following snippet.

The latter example works, but since the standard .split() is not sequence aware, the end result has it's sequence information deleted, defeating the purpose of using the terminal.wrap function.

import blessed

terminal = blessed.Terminal()

string = '''
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'''

print("Multiple instances of output when string includes carriage returns")
for s in terminal.wrap(string, width=30):
    print(s)

print()
print("When carriage returns are removed, works as expected")
for s in string.split('\n'):
    for s2 in terminal.wrap(s, width=30):
        print(s2)

Output:

python test5.py 
Multiple instances of output when string includes carriage returns

 AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAA BBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCC
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAA BBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCC
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAA BBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCC

When carriage returns are removed, works as expected
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCC

move_up/down/left/right uses 'cu{}1', so it is not possible to move_right(3)

should be possible to emit \x1b[10C by syntatic sugar, but currently requires accessing term.cuf(10) directly :(

A design bug, the "sugar" for move_* calls is wrong, see terminfo 5

cursor_right             cuf1              nd               non-destructive
                                                            space (move right
                                                            one space)
parm_right_cursor        cuf               RI               move #1 characters
                                                            to the right (P*)

We always unconditionally use 'cuf1', instead of 'cuf' with numeric argument as we should, see

move_right='cuf1',

This is backported issue from upstream erikrose#97

with putty with linux, select and find are home and end

06:53 < Mercyful> i also noticed in putty with linux,, select and find are home and end..
06:53 < Mercyful> '\x1b[1~': code=362 name='KEY_FIND' -- Home
06:53 < Mercyful> '\x1b[4~': code=385 name='KEY_SELECT' -- End

In [1]: from blessed import Terminal

In [2]: term = Terminal('putty')

In [3]: term.inkey(esc_delay=10.0)
^[[1~
Out[3]: KEY_FIND

Related to #43 in that the solution might require some complexity, currently we unconditionally add many standard input patterns in addition to those found in termcap, which is necessary for many keystrokes -- however, we need to conditionally chose which terminal type entries should be augmented -- and by which values.

All such code is made in blessed/keyboard.py around the DEFAULT_SEQUENCE_MIXIN variable.

Terminal width and height reversed

Hi,

I was looking through some of my options in regards to libraries for abstracting the terminal for a console game and blessings seems the way to go as far as handling output to the terminal is concerned and this project seems to go a long way towards adding handling of input.

So I would be very interested in using blessed for my clone of 2048 and, if you appreciate any help, to also further develop blessed as a nice API abstracting the terminal.

On to my issue:
Terminal.width returns height and Terminal.height returns width.

Fix:
switch line with line

API Change: Terminal.move (y, x) => (x, y).

This issue duplicates upstream issue, erikrose#58

Problem

Terminal.location is (x, y) but Terminal.move is (y, x).

This causes issues with composability of positional (y, x) parameters. Also causes programmer mistakes.

Solution

Terminal.move to positional ordering, (y, x) => (x, y).

Create tests that assert multiple "with" statements of of cbreak and raw are OK.

Test case 1:

  • enter cbreak.
  • assert cbreak is set using tcgetattr.
  • exit cbreak.
  • assert cbreak is not set using tcgetattr.

Test case 2:

  • enter cbreak
  • enter raw
  • assert raw mode is set using tcgetattr.
  • enter cbreak
  • assert cbreak is set using tcgetattr.
  • exit cbreak
  • assert raw mode is set using tcgetattr.
  • exit raw
  • assert cbreak is set using tcgetattr.
  • exit cbreak
  • assert cbreak is no longer set using tcgetattr.

very low priority.

remove documentation about speciality of setupterm's descriptor, use os.devnull

It's actually perfectly fine to call curses.setupterm(kind, open(os.devnull).fileno()).

More importantly, this removes a chunk of documentation and comments, such as:

            Terminal initialization sequences will be sent to ``stream`` if it
            has a file descriptor and to ``sys.__stdout__`` otherwise. (``setupterm()`` demands to send them
            somewhere, and stdout is probably where the output is ultimately
            headed. If not, stderr is probably bound to the same terminal.)

and

            # (...) Explicit args make setupterm()
            # work even when -s is passed to nosetests. Lean toward sending
            # init sequences to the stream if it has a file descriptor, and
            # send them to stdout as a fallback, since they have to go
            # somewhere.

This issue backports upstream erikrose#95

Hint at correct use of term.clear() in the README

I'm creating a fullscreen GUI, this is my basic code:

from blessed import Terminal

term = Terminal()
def main():
  while True:
    term.clear()
    term.move(0, 0)
    print("----")
    print("-##-")
    print("----")

    key = term.inkey()
    if key in ("q", "Q"):
      break

with term.cbreak():
  with term.fullscreen():
    main()

but this doesn't work, it keeps writing below the last thing it printed instead of clearing the screen.

Split __init__.py to separate modules

Split the Terminal class to a separate file and only use init.py for importing labels that should be accessible by library users.

This makes it clear from just looking at filenames in the blessed directory and in the init.py file what is exposed as API ,just like your telnet library.

Also, ipython uses all these exposed labels for completion:

In [31]: from blessed.
blessed.Terminal     blessed.contextlib   blessed.locale       blessed.sequences    blessed.time         
blessed.blessed      blessed.curses       blessed.os           blessed.struct       blessed.tty          
blessed.codecs       blessed.fcntl        blessed.platform     blessed.sys          blessed.warnings     
blessed.collections  blessed.keyboard     blessed.select       blessed.termios 

sphinx docfix: strange API docstring descriptions for constants

See example, http://blessed.readthedocs.org/en/latest/api.html#blessed.formatters.COMPOUNDABLES

which reads:


COMPOUNDABLES = {'bright_magenta', 'standout', 'bright_red', 'on_bright_magenta', 'bright_blue', 'magenta', 'bold', 'superscript', 'bright_white', 'on_bright_black', 'on_black', 'on_green', 'on_magenta', 'on_cyan', 'on_bright_yellow', 'green', 'on_white', 'on_bright_cyan', 'underline', 'italic', 'on_bright_blue', 'on_blue', 'dim', 'bright_black', 'bright_cyan', 'on_bright_red', 'blink', 'blue', 'yellow', 'bright_yellow', 'shadow', 'on_bright_green', 'on_red', 'black', 'subscript', 'white', 'on_yellow', 'red', 'on_bright_white', 'reverse', 'bright_green', 'cyan'}

    set() -> new empty set object set(iterable) -> new set object

    Build an unordered collection of unique elements.

We would rather describe the meaning of the data than the use of a set instance !

TypeError when using colors

Today I did a git pull from 19a9434 to 563da12, and my code started spitting errors.

Here is the simplest case (straight from the README) to reproduce:
ipython:

In [1]: from blessed import Terminal

In [2]: term = Terminal()

In [3]: term.red_on_green('Red on green? Ick!')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-e6d4739b5182> in <module>()
----> 1 term.red_on_green('Red on green? Ick!')

/usr/lib/python3.3/site-packages/blessed-1.7-py3.3.egg/blessed/formatters.py in __call__(self, *args)
     50                     'A native or nonexistent capability template received '
     51                     '%r when it was expecting ints. You probably misspelled a '
---> 52                     'formatting call like bright_red_on_white(...).' % (args,))
     53             # Somebody passed a non-string; I don't feel confident
     54             # guessing what they were trying to do.

TypeError: A native or nonexistent capability template received ('Red on green? Ick!',) when it was expecting ints. You probably misspelled a formatting call like bright_red_on_white(...).

Underline does work:

In [4]: term.underline('Red on green? Ick!')
Out[4]: '\x1b[4mRed on green? Ick!\x1b(B\x1b[m'

Features from Curtsies that could belong in Blessed

I work on a library that currently duplicates functionality from Blessed. I'd like to use Blessed for a lot of things instead of having my own implementations, but am curious about whether you'd want any of these features in Blessed. Would any of the following belong in Blessed?

  • Colored strings that don't format themselves until they're finally rendered (see http://curtsies.readthedocs.org/en/latest/index.html#fmtstr-rationale)
  • A 2d array of styled characters for rendering to the screen
  • A caching screen renderer (renders only portions of the screen necessary assuming no other writes to stdout have occurred)
  • Querying cursor position (I'm confused about whether #19 is talking about this or something else)
  • Changes to the keypress detector: using a reactor for scheduling events while reading on stdin, being interruptible by signals and messages from other threads

I imagine these don't belong in Blessed, but wanted to see what you thought.

Request Terminal.clear() write directly to output instead of returning a sequence like other functions.

I realize this behaviour originates in blessings and keeping API compatibility might be important, but to me having clear() as a function would indicate that calling it clears the screen.

You might already have made a choice about API compatibility, but you could for example also make clear a property with a call attribute. This means accessing a Terminal's instance's clear property returns the escape sequence and calling that same property clears the screen.

Disregard esc_delay in inkey if sequence is not a prefix of any known sequences

To make inkey() not delay on "meta-sends-escape" keypresses, would be nice to check if Escape plus the characters after it could possibly resolve to something and not delay if there is no possible "partial resolution" of these characters. I did this in Curtsies by building a prefix table. In a comment at https://github.com/jquast/blessed/blob/master/blessed/terminal.py#L740 it says \x1b[,\x1bO, and \x1b? are the three to worry about - if there's a character following esc and it's not one of these three could inkey return immediately?

Support comparators for matching keyboard input to meta and ctrl keys

Problem

Ctrl keys, such as ^C are not considered sequences and must be matched by their raw escape codes. We propose a change:

- if term.inkey() == '\x03':
+ if term.inkey() == term.KEY_control('c')

Furthermore, the legacy (and not recommended for modern applications, IMO) to support alt or meta by escape,

        # 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') ?

as well as erikrose#27 (comment)
and erikrose#44

Note: this backported from upstream erikrose#98

How would we support the advanced ctrl, shift, and alt combinators of #73 ?

First Proposal

New methods KEY_control(ucs) and KEY_meta(ucs), returning a Sequence instance(?), \x03 for Ctrl-C and \x1b[c for Alt-C, that can be compared for equality for a given sequence (by their equivalent raw string value). As Unicode-derived class Sequence, this should work without supporting stub code for both left and right-hand side operations. The code value should remain its numeric ascii value for control. For meta characters, code should be value None.

Second Proposal

Further decorate the Keystroke class to provide new methods:

control (or ctrl or both)
alt (or meta or both)
shift (may not support... difficult)

Which accepts an optional 1-unicode-character input in range of ascii (a-zA-Z, punctuations, etc.).

So that, with ctrl-c, the unicode string is u'\x03' and its method .ctrl() returns True, .ctrl('c') returns True, and .ctrl('z') returns False.

Similarly, with alt+x, the unicode string is u'\x1bx' and its method .alt() returns True, .alt('x') returns True, and .alt('p') returns False.

Third Proposal

Support .is_compound_format_testing() tester, somewhat like blessings project, example:

if term.inkey().is_alt_shift('z'):
    # fancy way of saying alt+Z was pressed.
if term.inkey().is_ctrl_shift('c'):
    # may never test true, dragons be here
inp = term.inkey()

This would for example support testing key combinations such as

#define SHIFT_ALT_CTRL_PF7_KEY           "\033[18;8~" 

shift is difficult. In '\x03' (^C), we would test that shift is not pressed. But it could just as easily be pressed, and we wouldn't know. We would chose false unless it tested against upper().

Styling support on win32 platforms using ecma ansi

Introduction

Currently PDCurses builds of python does work with blessed, thanks to help from @M-griffin, but there is no termcap database.

This means an empty string ("") is always returned for bold, colors, etc. This is directly related to erikrose#21

Acceptance Criteria

All basic capabilities supported by https://github.com/tehmaze/ansi are supported on Windows. That is, Terminal().bold_red("Hello") should emit the correct ECMA-48 ANSI escape sequences on the windows platform. Although not included in scope, it is assumed that by exporting ANSI escape sequences, that it should be possible to combine with https://pypi.python.org/pypi/colorama

Furthermore

The root of the problem is that PDCurses, a BSD licensed curses implementation, does not provide a terminal database parser, nor a terminal database records file, on the windows platform. The true solution is to simply implement it, but this is actually quite difficult as reported by @tehmaze who has investigated writing a from-scratch termcap parser.

In the future, it is viable that the blessed project does not import curses at all -- and parses termcap in pure python. There isn't any reason why it can't, it simply re-uses and links with C Curses libraries to prevent code duplication. However, a pure-python implementation of tigetstr(3x) and friends would allow blessed to be portable, independent of the availability of the curses module !

Numpad input not recognised

Hi. Have been using this to write a roguelike. Today when implementing diagonal movement, I found that I couldn't get term.KEY_LL and the such from the numpad. The upper right key is recognised as KEY_PGUP. It thinks that the 7 is KEY_ESC and seems to fail to read it as a sequence, producing multiple inputs. According to this http://stackoverflow.com/questions/16975367/ncurses-reading-numpad-keys-and-escaping, crawl hacks around it. Is there a way blessed can do similar? I had a go at monkey patching but it didn't go well.

iter_parse method

Acceptance Criteria

A method, term.iter_parse(), that can be used in the following manner:

>>> for part in Terminal().iter_parse('\x1b[10Cblahblah\x1b[0m'):
...    print((ucs, ucs.is_sequence, ucs.capname, ucs.params))
...
('\x1b[10C', True, 'cuf', ('10',))
('blahblah', False, None, None))
('\x1b[0m', True, 'sgr', ('0',))

There are several places in the codebase where sequences are "iterated", these sections of code should be replaced by the new iter_parse(term, ucs) function added to blessings/sequences.py, and proxying stub method added to the Terminal class.

Details

One thing blessed does right now is simply emit or strip sequences, but it doesn't "comprehend" them in the way curtsies might be able to.

The value yielded should be a namedtuple() instance, values .ucs(str), .is_sequence(bool), .capname(str), .params(tuple(str))

This can be achieved by modifying the regex parse builders in blessed/sequences.py to include (?P<name>...) in the expressions compiled.

remove RuntimeError exception, formally NoKeyboard, or change to filter?

Upstream EK proposed a custom NoKeyboard exception, erikrose@327e315 which was backmerged in 1af188b. My own design preference is never to create custom exceptions, as the built-ins are almost always suitable when exceptions must be raised.

Downstream, we derive Terminal to serve over telnet, ssh, rlogin, and others. This sort of rejection of parameter combinations appears unpythonic, in that it then requires "patching" to ensure such exception is not raised:

    """ A thin wrapper over :class:`blessed.Terminal`. """

    _session = None

    def __init__(self, kind, stream, rows, columns):
        """ Class initializer. """
        self._rows = rows
        self._columns = columns
        BlessedTerminal.__init__(self, kind, stream)
        # *PATCH* against 'is None' check in method Terminal.inkey()
        # that raises RuntimeError to "prevent indefinite blocking
        # timeout without a keyboard attached" -- which is often our
        # intention.
        self._keyboard_fd = 'defunc'
        if sys.platform.lower().startswith('win32'):
            self._normal = '\x1b[m'

But this is an unpythonic toggling of the former NoKeyboard exception on call to inkey(). Instead, if such item is necessary, the warnings module should be used so that it may be appropriately filtered away when derived and modified.

prefer key.name for unicode value in Keystroke

Currently:

In [83]: from blessed import keyboard

In [84]: left = keyboard.Keystroke(name='KEY_LEFT')

In [85]: right = keyboard.Keystroke(name='KEY_RIGHT')

In [86]: left == right
Out[86]: True

Keystroke.eq should probably check if unicode's eq believes the objects are equal. If unicode believes the objects to be equal check if other is also a Keystroke. If other is a Keystroke compare the name attribute of both objects (maybe also code).

Also I would like to be able to use Keystrokes as keys for dicts, but currently only unicode's hash is used:

In [87]: {left: 1, right: 2}
Out[87]: {KEY_LEFT: 2}

Keystroke's hash should probably look something like:

def __hash__(self):
    if self._name or self._code:
        return hash((self, self._name, self._code))
    return super(Keystroke, self).__hash__()

SyncTerm's F5 key is mistaken for KEY_KP_4.

Low Priority. Here's the real story -- SyncTerm piggybacks, but deviates from, the standard "ansi" terminal capability database. It should use its own "syncterm" terminal kind, and submit terminal entries upstream (curses/terminfo/dickey et. al)

This problem may not even be solvable given the conditions. If SyncTerm's keystroke sequences are uncommon and unique, and conflict with existing common vt220/xterm sequences, then we should honor the later, not the former.

TypeError in kbhit() when a terminal resize happens while blocking on inkey()

I did a git pull today: 5e2bdb9..51932dd master -> origin/master, and I receive the following backtrace when I resize the terminal:

Traceback (most recent call last):
  File "./macht.py", line 6, in <module>
    exit(main())
  File "/home/rolf/workspace/python/macht/macht/term/main.py", line 112, in main
    key = term.inkey()
  File "build/bdist.linux-x86_64/egg/blessed/terminal.py", line 662, in inkey
  File "build/bdist.linux-x86_64/egg/blessed/terminal.py", line 537, in kbhit
TypeError: unsupported operand type(s) for -=: 'NoneType' and 'float'

This is with a SIGWINCH handler installed.

Also the code for the 2048 clone is now up on github: macht. It is lacking animations and documentation, but supports multiple simultaneous grids.

The terminal (read blessed) specific code is in the macht/term directory. Setting of the signal handler and input handling is in macht/term/main.py.

mouse support

this was already done once before in a rejected blessings patch last year,

https://asciinema.org/a/2871 <- scroll wheel
https://asciinema.org/a/2866 <- click detection

https://gist.github.com/jquast/7018509#file-__init__-py-L511-L536

Not so sure about the given solution, I need to be persuaded about the context manager names and possible keyword argument/values.

Furthermore, the "Keystroke" class type returned by Terminal.inkey() can now return MouseEvent as well -- they now need to derive from the same base class, providing the same .code and .is_sequence() methods. I think I would further like attribute "kind" of values "MouseEvent" or "keystroke".

Mouse input provides (x,y) attributes, but even bounding box attributes etc., a class needs to be made to support all such decoding, example of decoding and game is done here ("drawing boxes" demo)

https://gist.github.com/jquast/7018509#file-test_mouse-py-L259-L356

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.