颜色在乌尔维德或诅咒中传递

时间:2019-12-14 19:49:42

标签: python curses urwid

我想在git log周围写一个包装,有点像gitk,但在终端上。

我认为这应该很容易,因为git log已经格式化了输出,我要做的就是将其放在列表视图中,我可以选择一个提交。

但是,urwid和curses都弄乱了git log使用的颜色代码。 我尝试实现一个自定义的urwid小部件,希望它可以不使用颜色代码,但行为没有任何不同。

我考虑将输出的颜色从git log移到我的包装器中,但是使用--graph选项是不可能的。

颜色的直接传递适用于普通的打印语句,但是我不想重新发明窗口管理,输入处理,重新设置大小的识别,而且我不知道其他什么。

如何停止烦扰或诅咒触摸颜色代码?


所需的输出: enter image description here

实现的输出: enter image description here

MWE:

model.py

#!/usr/bin/env python

import subprocess

class LogModel():

    encoding = "utf-8"
    cmd = ["git", "log", "--color", "--graph", "--pretty=format:%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset", "--abbrev-commit"]

    def get_lines(self):
        p = subprocess.run(self.cmd, stdout=subprocess.PIPE, check=True, encoding=self.encoding)
        out = p.stdout

        return out.splitlines()

if __name__ == '__main__':
    log = LogModel()
    for ln in log.get_lines():
        print(ln)

(git日志格式的信用为here

main_urwid.py

#!/usr/bin/env python

import urwid
import model

class MyText(urwid.Widget):

    _sizing = frozenset(['flow'])

    def __init__(self, text):
        super().__init__()
        self.text = text.encode("utf-8")

    def render(self, size, focus=False):
        (maxcol,) = size
        return urwid.TextCanvas([self.text], maxcol=maxcol, check_width=False)

    def rows(self, size, focus=False):
        return 1

class LogView(urwid.ListBox):

    def __init__(self, log_model):
        widgets = [self.create_line_widget(ln) for ln in log_model.get_lines()]
        body = urwid.SimpleFocusListWalker(widgets)
        super().__init__(body)

    def create_line_widget(self, ln):
        #return urwid.Text(ln, wrap=urwid.CLIP)
        return MyText(ln)

class App():

    palette = []

    def __init__(self):
        self.view = LogView(model.LogModel())

    def run(self):
        self.loop = urwid.MainLoop(self.view, self.palette,
            unhandled_input=self.unhandled_input)
        self.loop.run()

    def unhandled_input(self, k):
        if k == "q":
            raise urwid.ExitMainLoop()

if __name__ == '__main__':
    a = App()
    a.run()

main_curses.py

#!/usr/bin/env python

import curses
import model

def main(stdscr):
    log_model = model.LogModel()

    curses.use_default_colors()
    stdscr.clear()

    col = 0
    for row, ln in enumerate(log_model.get_lines()):
        stdscr.addstr(row, col, ln)

    stdscr.refresh()
    stdscr.getkey()

if __name__ == '__main__':
    curses.wrapper(main)

0 个答案:

没有答案