LINUX.ORG.RU

Цветная консоль для python


1

0

В документации к питону есть примеры того, как можно добавить автодополнение и сохранение истории команд к интерактивной консоли. В дополнение к этому решил ещё эту консоль и раскрасить. Использовал sys.displayhook и sys.excepthook (хотя, может быть, правильнее было бы использовать code.InteractiveConsole?), а также модули token и tokenize.

Рабочая машина. Debian Etch. KDE. Запуск всех необходимых приложений "повешен" на клавиатурные комбинации. Не видны yakuake и katapult.

P.S. На домашнем компьютере Debian Lenny. Пока отлаживал данный сценарий, узнал много нового о разнице между python 2.4 и 2.5.

>>> Просмотр (1680x1050, 350 Kb)



Проверено: hibou ()

Ответ на: комментарий от pento

А вот и скриптик. Написан на скорую руку, так что сильно не придирайтесь.
Пока некорректно отбражается позиция ошибки при форматировании символами табуляции.

import os
import sys
import readline
import atexit
import rlcompleter
import token
from tokenize import generate_tokens
from traceback import format_tb

colors = {
    "gray": "\x1b[01;30m",
    "brown": "\x1b[01;31m",
    "green": "\x1b[01;32m",
    "yellow": "\x1b[01;33m",
    "blue": "\x1b[01;34m",
    "magenta": "\x1b[01;35m",
    "cyan": "\x1b[01;36m",
    "white": "\x1b[01;37m",
    "red": "\x1b[01;38m",
    "bold": "\x1b[01;39m"
}

highlighting = {
    token.NAME: "cyan",
    token.NUMBER: "yellow",
    token.STRING: "green",
    token.INDENT: "white",
    token.DEDENT: "white",
    token.OP: "magenta",
    token.ERRORTOKEN: "white"
}

def colorize(s, hl, kw):
    r = []
    prev_line = 1
    prev_pos = 0
    for ttype, token, tstart, _, _ in generate_tokens(iter(s).next):
        if ttype:
            line, pos = tstart
            if line > prev_line:
                r.append("\n")
                prev_line = line
                prev_pos = 0
            space = " "*(pos - prev_pos)
            prev_pos = pos + len(token)
            if (ttype == 1) and (token not in kw):
                color = colors["white"]
            else:
                color = colors[hl.get(ttype, "magenta")]
            r.append(space + color + token)
    r.append(colors["white"])
    return "".join(r)

def displayhook(obj):
    if obj is not None:
        keywords = [
            "function", "at", "type", "instance", "class", "True",
            "False"
        ]
        print colorize([repr(obj)], highlighting, keywords)

def excepthook(extype, ex, tb):
    tbstr = map(lambda s: s[:-1], format_tb(tb))
    keywords = ["File", "line", "in"]
    tbstr = colorize(tbstr, highlighting, keywords)
    print "%(red)sTraceback %(magenta)s(%(yellow)smost recent call last%(magenta)s):" % colors
    print tbstr
    if isinstance(ex, SyntaxError):
        keywords = ["File", "line"]
        print colorize(
            ['  File "%s", line %d' % (ex.filename, ex.lineno)],
            highlighting,
            keywords
        )
        print ex.text[:ex.offset - 1] + \
            colors["red"] + \
            ex.text[ex.offset - 1] + \
            colors["white"] + \
            ex.text[ex.offset:-1]
        print " "*(ex.offset - 1) + colors["red"] + "^"
        exmsg = ex.msg
    else:
        if hasattr(ex, "message"):
            exmsg = ex.message
        else:
            if ex.args:
                exmsg = ex.args[0]
            else:
                exmsg = ""
    print colors["red"] + \
        extype.__name__ + ": " + \
        colors["yellow"] + exmsg + colors["white"]
    
sys.displayhook = displayhook
sys.excepthook = excepthook
sys.ps1 = "%(green)s>>> %(white)s" % colors
sys.ps2 = "%(yellow)s... %(white)s" % colors
histfile = os.path.join(os.environ["HOME"], ".pyhist")
try:
    readline.read_history_file(histfile)
except:
    pass
atexit.register(readline.write_history_file, histfile)
readline.parse_and_bind("tab: complete")
del os, sys, histfile

SSN
() автор топика
Ответ на: комментарий от Werehuman

Интереснее было бы добавить подсветку синтаксиса/ошибок в GNU readline. Многие интерпретаторы, например bash, python, используют эту библиотеку для вывода приглашения и ввода команд в интерактивном режиме(те строки, которые белого цвета на скрине). Так что если бы имелась возможность раскрашивать вывод readline, то мы автоматически получили бы, например, подсветку синтаксиса сразу во многих программах. Да, в ~/.inputrc можно задать макросы, заменяющие символы при вводе. Но задействовать в них управляющие последовательности символов (подобные \033[01;30m) мне не удалось. Наличие же в макросе символа, для которого уже назначен макрос, приводит к его вызову, в результате чего макросы вида "-": " -" входят в бесконечный цикл.

SSN
() автор топика

Велосипед. Причём с квадратными колёсами. Программы, читающие через pipe такой вывод, ожидает приятный сюрприз.

hbee ★★★★
()
Ответ на: комментарий от hbee

это сарказм. никакие не читают, это суто интерактивный режим работы, когда стдаут связан с терминалом

val-amart ★★★★★
()
Ответ на: комментарий от SSN

>> Мне кажется, ли вы написали IPython)?

>Спасибо. к сожалению, не знал об этой программе.

А про IDLE не слышали? :) Вообще-то в комплекте идет...

RaySlava
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.