aboutsummaryrefslogtreecommitdiff
path: root/wikijscmd/tui.py
blob: 16232bb9b7f3991ecc072e8075be00615203e8ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python3

import curses
from curses import wrapper

from wikijscmd import util, commands

def pager(stdscr, lst):
    '''
    Runs a pager for each string item in lst
    '''
    cols = stdscr.getmaxyx()[1]
    rows = stdscr.getmaxyx()[0]
    offset = 0
    selected = 0
    while True:
        stdscr.clear()
        for i in range(min(rows-1, len(lst))):
            x = lst[i+offset]
            if i+offset == selected:
                stdscr.addstr(i, 0, x[:cols], curses.A_UNDERLINE)
            else:
                stdscr.addstr(i, 0, x[:cols])
        if offset == 0:
            stdscr.addstr(rows-1, 0, "--top--", curses.A_REVERSE)
        elif offset + rows <= len(lst):
            stdscr.addstr(rows-1, 0, "--more--", curses.A_REVERSE)
        else:
            stdscr.addstr(rows-1, 0, "--end--", curses.A_REVERSE)
        k = stdscr.getch()
        if k == curses.KEY_DOWN or k == ord('j'):
            selected = min(len(lst), selected+1)
            if (selected - offset) > (2 * rows / 3):
                offset = min(len(lst)-rows+1, offset+1)
        elif k == curses.KEY_UP or k == ord('k'):
            selected = max(0, selected-1)
            if (selected - offset) < (rows / 3):
                offset = max(0, offset-1)
        elif k == curses.KEY_NPAGE:
            offset = min(len(lst)-rows+1, offset+rows-2)
            selected = min(len(lst)-rows+1, selected+rows-2)
        elif k == curses.KEY_PPAGE:
            offset = max(0, offset-rows+2)
            selected = max(0, selected-rows+2)
        elif k == curses.KEY_HOME:
            offset = 0
            selected = 0
        elif k == curses.KEY_END:
            offset = len(lst)-rows+1
            selected = len(lst)-1
        elif k == curses.KEY_ENTER or k == 10:
            return {"index": selected, "action": "select"}
        elif k == ord('q'):
            return {"index": selected, "action": "quit"}
        elif k == ord('e'):
            return {"index": selected, "action": "edit"}
        elif k == ord('c'):
            return {"index": selected, "action": "create"}
        elif k == ord('t'):
            return {"index": selected, "action": "today"}
        stdscr.refresh()

def enter_value(stdscr, prefix, row):
    """
    Creates a prompt to enter a value on the given row
    """
    title = ""
    stdscr.addstr(row,0, prefix + title)
    k = stdscr.getch()
    while k != 10 and k != curses.KEY_ENTER:
        if k in (curses.KEY_BACKSPACE, '\b', '\x7f'):
            if len(title) > 0:
                title = title[:-1]
        else:
            title += chr(k)
        stdscr.deleteln()
        stdscr.addstr(row,0, prefix + title)
        k = stdscr.getch()
    return title

def m(stdscr):
    """
    The main method for the ncurses wrapper
    """
    items = util.get_tree("")
    while True:
        ret = pager(stdscr, [x["path"] + "\t" + x["title"] for x in items])
        if ret["action"] == "select":
            selected = items[ret["index"]]
            ret = pager(stdscr, util.get_single_page(selected["path"])["content"].split("\n"))
        elif ret["action"] == "edit":
            selected = items[ret["index"]]
            commands.edit(selected["path"], True)
        elif ret["action"] == "create":
            stdscr.clear()
            title = enter_value(stdscr, "Enter title: ", 0)
            path = enter_value(stdscr, "Enter path: ", 1)
            commands.create(path, title)
        elif ret["action"] == "today":
            commands.today()
        else:
            break

def tui():
    try:
        wrapper(m)
    except Exception as e:
        raise e