Sys.stdin'i eş zamanlı olarak renklendirmek

Hımm. Yanlış anlamıyorsam kullanıcı stdin’e yazı yazarken aslında dosyaya yazı yazılacak, dosyadaki veri de sonradan okunacak ve uygun karakterler renklendirilerek tekrar sys.stin’e aktarılacak (aslında en sıkıntılı kısım bu, sys.stdin’e renk kodu nasıl aktarılacak). Tabi bu arada kullanıcının bundan haberi olmayacak ve yazma işlemi sekteye uğramayacak, yavaşlama olmayacak, böyle bir ihtimalden mi bahsediyorsunuz? Akşam oturup hem çalışmaya hem de araştırmaya başlayacağım.

Hayır, bunu demek istemedim. Kullanıcının klavye girişini taklit edebilir miyiz demek istedim. Kullanıcı ile aynı anda stdin’e veri yazmak için başka yol aklıma gelmiyor.

Sanırım buldum: https://docs.python.org/3/howto/curses.html Bu modül terminal üzerinde kontrol sağlayabilmemizi sağlıyor.

1 Beğeni

Bilmiyorum, nasıl yapılacağını öğrenmek lazım.

Hımm. bu modülü de incelememiştim. Bunu da bir inceleyeyim. Sağolun.

Daha önce paylaştığım bpython da curses’i kullanıyor sanırım. Kaynak koduna bakıp bunu nasıl yaptığını anlayabiliriz.

1 Beğeni

Tamam, bpython ve curses modülünü bir inceleyelim. Yalnız birazdan dışarı çıkacağım. Akşam, oturup göz atacağım sırayla. Tekrar teşekkür ederim İsmail Bey.

Rica ederim, sayenizde yeni şeyler öğreniyorum ben de. =)

1 Beğeni

Bilmukabele. :slight_smile: Şu curses modülüne çalışmaya başlayayım.

1 Beğeni

Merhabalar,

Güzel bir proje olacak gibi gözüküyor. Curses + Pygments ile yapabilirsiniz diye düşünüyorum. Syntax highlighting olayı için textbox kullanarak yaptığım bir proje vardı. Aynı mantığı Curses’e ayarlayabilirseniz, istediğinizi yapabilirsiniz bence.

https://github.com/blackvkng/Cedit/blob/master/cedit.py#L121

1 Beğeni

Merhaba, katılımınız için teşekkür ederim. Paylaştığınız linki inceleyeceğim. Daha önce curses ile ilgilendiyseniz, bana bir konuda yardım edebilir misiniz? Az önce curses konusuna çalışmaya devam ederken, yazı rengini değiştirmeye çalışıyordum ama sanırım addstr yazarak yanlış bir komut veriyorum, rica etsem aşağıdaki kodu bir inceleyebilir misiniz?

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

import curses

stdscr = curses.initscr()
curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
stdscr.nodelay(1)

q = 1
x = set()
y = 0

while q != ord("q"):
    if len(x) == 3:
        stdscr.addstr(y, 0, "def", curses.color_pair(1))
        x.clear()
        y += 1
    if q == ord("d"):
        x.add("d")
    elif q == ord("e"):
        x.add("e")
    elif q == ord("f"):
        x.add("f")
    q = stdscr.getch()

stdscr.getch()
curses.endwin()

Az önce yazdığınız programı çalıştırırken bir hata aldım. Hatayı düzeltmem için ne yapmam gerekiyor?

Hata çıktısı şu:

Traceback (most recent call last):
  File "yeni.py", line 235, in <module>
    cedit = Cedit()
  File "yeni.py", line 32, in __init__
    self.confApp()
  File "yeni.py", line 81, in confApp
    defaultConf = open(os.sep.join([self.currpath, "source", "config", "default-config.json"])).read().strip()
IOError: [Errno 2] No such file or directory: '/home/tanberk/source/config/default-config.json'

Maalesef, Curses ile çalışmadım daha önce. Ama böyle bir şey değil de, bir text widget ile yaparsanız daha iyi olacağını düşünüyorum. Attığım kodu incelerseniz, ne demek istediğimi daha iyi anlayabilirsiniz.

#!/usr/bin/env python

import curses
import curses.textpad as textpad

try:
    mainwindow = curses.initscr()
    curses.cbreak(); mainwindow.keypad(1); curses.noecho()
    textpad.Textbox(mainwindow).edit()
finally:
    curses.nocbreak(); mainwindow.keypad(0); curses.echo()
    curses.endwin()```
1 Beğeni

Hımm, evet. Ben de daha ilk defa dün curses çalışmaya başladım, acemisiyim doğal olarak. Bu text widgetini inceleyeyim. Çok teşekkür ederim. Bu arada paylaştığınız linkteki kodlar bir hata verdi. O hata neyden kaynaklanıyor biliyor musunuz?

Sanırım ana dizine sadece kodları çekmişsiniz, direk repoyu klonlamalısınız, varsayılan ayarları farklı bir dosyada tutuyordum.(bkz: https://github.com/blackvkng/Cedit/blob/master/source/config/default-config.json)

1 Beğeni

Evet şimdi çalıştı, sağolun. Dediğiniz gibi stringler ayrı bir renkte, integerler ayrı bir renkte, normal yazılar, karakterler ayrı bir renkte gözüküyorlar. Güzel bir text editörü olmuş, elinize sağlık. Programı inceleyip, yeni şeyler öğrenmeye çalışırım. :slight_smile:

Sanırım bu biraz daha iyi oldu. d ler anlık olarak mavi renge burunuyor. Türkçe karakterlerle ilgili bir sorun var suan, backspace tuşu disinda silme tuşu ve diğer tuşlar da tanitilmadi. mesela enter’a basıp alt satıra geçemiyoruz, mesela program ekran kucukken acildi diyelim, ekranı buyutursek, program hata veriyor, bunların hepsinin tanitilmasi gerekiyor galiba. :slight_smile:

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

import curses

stdscr = curses.initscr()
stdscr.keypad(1)
curses.start_color() # Renklendirmeden önce renklendirici çalıştırılmalı.
# Renk çifti bilgileri oluşturulur.
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.noecho()

stdscr_size = stdscr.getmaxyx() # ekranın max enlem ve boylamı
y, x = 0, 0 # imlecin başlangıç enlem ve boylamı
q = 0 # özel bir karakter olarak tanımlanacak.
      # q'ya basarak programdan çıkacağız.

while q != ord("q"):
    q = stdscr.getch() # q artık bütün karakterleri temsil ediyor.
    stdscr.addstr(y, x, chr(q), curses.color_pair(1))
    x += 1 # karakter eklemeye devam etmek için bir yandaki hücreye geçiyoruz.
    if x == stdscr_size[1] - 1: # karakterleri ekrana yerlestirirken             
        y += 1 # imleci ve ekran boyutunu hesaba katmamız gerekiyor.
        x = 0 # yoksa yeni karakterler alt satira inemez.
    if q == ord("d"):      
        x -= 1 # d bir önceki x değerinde kaldığı için oraya geri dönüyoruz.
        stdscr.addstr(y, x, chr(q), curses.color_pair(2))
        x += 1 # düzgün yazabilmek için tekrar eski haline getiriyoruz.

# q'ya bastıktan sonra normal terminal ekranına geri dönüyoruz.
curses.endwin()

Bir önceki örnekteki enlem boylam hesabını yapmaya gerek yokmuş. :slight_smile:

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

import curses

stdscr = curses.initscr()
stdscr.keypad(1)
curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.raw()
curses.noecho()

q = -1
k = set()

while q != ord("q"):
    q = stdscr.getch()
    stdscr.addstr(chr(q), curses.color_pair(1))
    if q == ord("d"):
        k.add("d")
    elif q == ord("e"):
        k.add("e")
    elif q == ord("f"):
        k.add("f")
        stdscr.addstr("\b\b\bdef", curses.color_pair(2))
    else:
        k = set()

curses.endwin()

Bu biraz daha iyi oldu. Ama yine olması gerektiği gibi değil.

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

import re
import curses
import keyword

stdscr = curses.initscr()
stdscr.keypad(1)
curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.raw()
curses.noecho()

q = -1
KWLIST = keyword.kwlist
strings = ""

while q != ord("q"):
    q = stdscr.getch()
    stdscr.addstr(chr(q), curses.color_pair(1))
    strings += chr(q)
    for kw in KWLIST:
        regex1 = re.search("[^'\"]\s{}\s$".format(kw), strings)
        regex2 = re.search("^{}\s$".format(kw), strings)
        if regex1 or regex2:
            stdscr.addstr("{}{}".format("\b" * (len(kw) + 1), "{} ".format(kw), curses.color_pair(2))
            strings = ""

curses.endwin()

Birisi bana IPython gibi bir şey yapmak istiyorsanız, curses yerine readline modülünü kullanın dedi. IPython readline modülünü kullanıyormuş. Ve işler sanırım sandığımdan daha karışık.

The readline module defines a number of functions to facilitate completion and reading/writing of history files from the Python interpreter. This module can be used directly, or via the rlcompleter module, which supports completion of Python identifiers at the interactive prompt. Settings made using this module affect the behaviour of both the interpreter’s interactive prompt and the prompts offered by the built-in input() function.

https://ipython.org/ipython-doc/3/development/how_ipython_works.html

Read–eval–print loop

1 Beğeni

Readline() da ilginç bir modülmüş. Belirlenen bazı kelimeler ilk harflerinin yazılmasından sonra tab tuşuna basınca tamamlanabiliyor.

Örnek:

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


import readline
from colorama import *

init(autoreset=False)
print(Fore.WHITE)


class KelimeTamamlayicisi:
    def __init__(self, kelimeler):
        self.kelimeler = kelimeler
        self.harf = None
        self.eslesim = None

    def complete(self, harf, sira):
        if harf != self.harf:
            self.eslesim = [i for i in self.kelimeler if i.startswith(harf)]
            self.harf = harf
        try:
            return self.eslesim[sira]
        except IndexError:
            return None


def tamamlanabilir_kelimeler(kelimeler):
    completer = KelimeTamamlayicisi(kelimeler)
    readline.parse_and_bind("tab: complete")
    readline.set_completer(completer.complete)


liste = tuple()
tamamlanabilir_kelimeler(kelimeler=liste)

while True:
    STDIN = input(">>> ")
    if STDIN == "durdur":
        break
    else:
        print(Fore.BLUE + STDIN + Fore.WHITE)
        liste += STDIN,
        tamamlanabilir_kelimeler(kelimeler=liste)