code / tomo-btui

Lines1.1K C700 Tomo305 Markdown95
(86 lines)
1 # An example program to pick a line of input from stdin
2 use ../btui.tm
4 _HELP := "
5 A simple picker program
6 "
8 struct Picker(
9 options:[Text],
10 prompt=">",
11 query="",
12 offset:Int=0,
13 max_height:Int?=20,
15 func draw(self:Picker)
16 live_options := self.live_options()
17 if chosen := self.chosen()
18 write("\r\033[33;1m$(self.prompt)\033[m \033[2m$(chosen.replace(self.query, "\033[0;1m$(self.query)\033[0;2m"))\033[m\033[K")
19 else
20 write("\r\033[33;1m$(self.prompt)\033[m \033[31m$(self.query)\033[m\033[K")
22 size := get_size()
23 height := (self.max_height or size.y) _min_ size.y
24 shown_options := live_options.to(height-1)
25 for opt in shown_options
26 write("\r\n\033[K$opt")
27 clear(Below)
28 move_cursor(ScreenVec2(0, -shown_options.length), relative=yes)
29 flush()
31 func update(self:&Picker)
32 key := get_key()
33 when key
34 is "Ctrl-c"
35 write("\r")
36 clear(Right)
37 clear(Below)
38 disable()
39 exit(code=1)
40 is "Enter"
41 write("\r")
42 clear(Right)
43 clear(Below)
44 disable()
45 if chosen := self.chosen()
46 say(chosen)
47 exit(code=0)
48 else
49 exit(code=1)
50 is "Backspace"
51 self.query = self.query.to(-2)
52 is "Space"
53 self.query ++= " "
54 is "Up", "Shift-Tab"
55 self.offset -= 1
56 is "Down", "Tab"
57 self.offset += 1
58 else if key.length == 1
59 self.query ++= key
61 func live_options(self:Picker -> [Text])
62 return [o for o in self.options if o.has(self.query)]
64 func chosen(self:Picker -> Text?)
65 live_options := self.live_options()
66 if live_options.length > 0
67 return live_options[(1 + self.offset) mod1 live_options.length]
68 else
69 return none
71 func main(choices:Path=(/dev/stdin), prompt|p=">", query|q="", max_height|H:Int?=20)
72 lines := choices.lines() or fail("No such file: $choices")
73 lines = [line for line in lines if line.length > 0]
74 picker := Picker(
75 options=lines,
76 prompt=prompt,
77 query=query,
78 max_height=max_height,
80 set_mode(Normal)
81 hide_cursor()
82 picker.draw()
83 repeat
84 picker.draw()
85 picker.update()
86 disable()