Sys.stdin'i eş zamanlı olarak renklendirmek

>>> import readline
>>> import rlcompleter
>>> 
>>> readline.parse_and_bind('tab: complete')
>>> 
>>> readline.
readline._READLINE_RUNTIME_VERSION             readline.get_begidx(
readline._READLINE_VERSION                     readline.get_completer(
readline.__class__(                            readline.get_completer_delims(
readline.__delattr__(                          readline.get_completion_type(
readline.__dict__                              readline.get_current_history_length(
readline.__doc__                               readline.get_endidx(
readline.__file__                              readline.get_history_item(
readline.__format__(                           readline.get_history_length(
readline.__getattribute__(                     readline.get_line_buffer(
readline.__hash__(                             readline.insert_text(
readline.__init__(                             readline.parse_and_bind(
readline.__name__                              readline.read_history_file(
readline.__new__(                              readline.read_init_file(
readline.__package__                           readline.redisplay(
readline.__reduce__(                           readline.remove_history_item(
readline.__reduce_ex__(                        readline.replace_history_item(
readline.__repr__(                             readline.set_completer(
readline.__setattr__(                          readline.set_completer_delims(
readline.__sizeof__(                           readline.set_completion_display_matches_hook(
readline.__str__(                              readline.set_history_length(
readline.__subclasshook__(                     readline.set_pre_input_hook(
readline.add_history(                          readline.set_startup_hook(
readline.clear_history(                        readline.write_history_file(
>>> readline.

Sizin işinize yarayacak olan örnek :smiley:

Bu arada, bpython için yazılmış curties modülünü inceleyebilirsiniz.

Evet, dün readline modülüne çalışmaya başladım, rlcompleter ile benzer bir işlem yapıyor. Curties’e de uygun bir zamanda bakarım, teşekkür ederim.

Merhabalar,
Bir öneriye ihtiyacım var:
Pygments’de de yeniyim.
Pygments ve readline ile birlikte çalışmaya çalışıyorum.
readline ile tab-completion’a keyword tokenlerini veya builtinleri sorunsuz bir şekilde ekleyebiliyorum.
pygments’in highlight fonksiyonunu kullanarak, print(“hello world”) ifadesini de tokenlerine göre renklendirebiliyorum.
Ancak input()'un içini readline ve pygments’i birlikte kullanarak renklendirmeye çalışırken galiba hata yapıyorum, henüz öğrenmediğim bir konu olsa gerek.

Mesela aşağıdaki kodları çalıştırdığım zaman aldığım ekran görüntüsü:

TAB’a 2 kez basınca keyword’leri görebiliyoruz. Program çalıştırılır çalıştırılmaz ekrana tokenlerine göre pygments ile ayrıştırılmış bir print(“hello world”) yazısı çıkıyor. Sonra kullanıcının yazı girişi yapacağı bir prompt var ancak pygments’i prompttaki yazılara nasıl uyarlayacağımı öğrenemedim.

import readline
from pygments.token import Token
from pygments.style import Style
from pygments.lexers import Python3Lexer
from pygments import highlight
from pygments.formatters import Terminal256Formatter
import keyword


class Completer:
    def __init__(self, words):
        self.words = words
        self.prefix = None
        self.match = None

    def complete(self, prefix, index):
        if prefix != self.prefix:
            self.match = [i for i in self.words if i.startswith(prefix)]
            self.prefix = prefix
        try:
            return self.match[index]
        except IndexError:
            return None


class MyStyle(Style):
    styles = {
        Token.String: '#ansiwhite',
        Token.Number: '#ansired',
        Token.Keyword: '#ansiyellow',
        Token.Operator: '#ansiyellow',
        Token.Name.Builtin: '#ansiblue',
        Token.Literal.String.Single: '#ansired',
        Token.Punctuation: '#ansiwhite'
    }


if __name__ == "__main__":
    code = highlight("print('hello world')", Python3Lexer(), Terminal256Formatter(style=MyStyle))
    readline.parse_and_bind('tab: complete')
    readline.set_completer(Completer(keyword.kwlist).complete)
    print(code)
    while True:
        _input = input(">>> ")
        if _input == "quit":
            break
        else:
            print(_input)

Readline’ın tamamlayacağı keyword listesinin öğelerini renklendirmeyi denedim bu sefer de aşağıdaki gibi bir çıktı alıyorum:

Bu çıktıyı verdiren kodlar:

import readline
from pygments.token import Token
from pygments.style import Style
from pygments.lexers import Python3Lexer
from pygments import highlight
from pygments.formatters import Terminal256Formatter
import keyword


class Completer:
    def __init__(self, words):
        self.words = words
        self.prefix = None
        self.match = None

    def complete(self, prefix, index):
        if prefix != self.prefix:
            self.match = [i for i in self.words if i.startswith(prefix)]
            self.prefix = prefix
        try:
            return self.match[index]
        except IndexError:
            return None


class MyStyle(Style):
    styles = {
        Token.String: '#ansiwhite',
        Token.Number: '#ansired',
        Token.Keyword: '#ansiyellow',
        Token.Operator: '#ansiyellow',
        Token.Name.Builtin: '#ansiblue',
        Token.Literal.String.Single: '#ansired',
        Token.Punctuation: '#ansiwhite'
    }


if __name__ == "__main__":
    CODE = [highlight(i, Python3Lexer(), Terminal256Formatter(style=MyStyle)) for i in keyword.kwlist]
    readline.parse_and_bind('tab: complete')
    readline.set_completer(Completer(CODE).complete)

    while True:
        _input = input(">>> ")
        if _input == "quit":
            break
        else:
            print(_input)

Muhtemelen eksik birşeyler yapıyorum mesela son örnekteki CODE’un keyword elemanları şöyle gözüküyor:

'\x1b[33;01mFalse\x1b[39;00m\n'  # Bu mesela False için.

Tamamlama işlemini ilk harften itibaren yaptığına göre, 2 kez tab’a basınca son ekran görüntüsünde gözüken garip çıktının sebebi anlaşılıyor. Önerisi olan arkadaşların önerilerini paylaşmasını isterim. Teşekkür ederim.

python-prompt-toolkit ve pygments ile sonunda oldu.

Kodlar:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
from sys import stdout, stderr
from keyword import kwlist
import builtins
from colorama import *
from pygments.lexers import Python3Lexer
from prompt_toolkit.shortcuts import prompt
from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.layout.lexers import PygmentsLexer
from prompt_toolkit.contrib.completers import WordCompleter

CODE, SIZE, TAB, KWLIST, BUILTINS = "", 0, " " * 4, kwlist, dir(builtins)
KWLIST.extend(BUILTINS)
KWLIST.append("clear")
completer = WordCompleter(KWLIST)
init(autoreset=False)
history = InMemoryHistory()

while True:
    if SIZE >= 1:
        LINE = prompt(
                "... {}".format(TAB * SIZE),
                lexer=PygmentsLexer(Python3Lexer),
                completer=completer,
                history=history,
                vi_mode=True)
        CODE += "{}{}\n".format(TAB * SIZE, LINE)
        if LINE == '':
            if SIZE == 0:
                try:
                    stdout.write(Fore.WHITE)
                    exec(CODE)
                except BaseException as ERR:
                    stderr.write("{}{}\n".format(Fore.YELLOW, ERR))
                    stdout.write(Fore.WHITE)
                CODE = ""
            else:
                SIZE -= 1
        elif LINE.endswith(":"):
            SIZE += 1
        else:
            continue
    else:
        LINE = prompt(
                ">>> {}".format(TAB * SIZE),
                lexer=PygmentsLexer(Python3Lexer),
                completer=completer,
                history=history,
                vi_mode=True)
        CODE += "{}{}\n".format(TAB * SIZE, LINE)
        if not LINE.endswith(":"):
            if LINE == "exit" or LINE == "quit" or LINE == "exit()" or LINE == "quit()":
                exit()
            elif LINE == "clear":
                os.system("cls" if os.name == "nt" else "clear")
                CODE = ""
            try:
                stdout.write(Fore.WHITE)
                exec(CODE)
            except BaseException as ERR:
                stderr.write("{}{}\n".format(Fore.YELLOW, ERR))
                stdout.write(Fore.WHITE)
            CODE = ""
        else:
            SIZE += 1
3 Beğeni

Sanırım bu modül readline modülünün özelleştirilmiş ve geliştirilmiş bir hali.

Bu arada bu konudan bir “Nasıl yapılır?” kılavuzu çıkar. @dildeolupbiten, ne dersin? =)

1 Beğeni

Evet, o modülle hem de konuyla ilgili söylediklerinize katılıyorum. Ayrıca desteğiniz için size ve diğer arkadaşlara da çok teşekkür ederim. Bu arada bir önceki mesajdaki kodları güncelledim, programa python_history eklendi. Yani daha önce yazdığımız bir satır, hafızaya alınıyor, tekrar kullanmak istediğimizde, aşağı ok tuşuna basarak kullanabiliriz.

Edit: vi mode eklendi.

3 Beğeni