(86 lines)
1 # An example program to pick a line of input from stdin4 _HELP := "5 A simple picker program6 "9 options:[Text],11 query="",14 )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 else22 size := get_size()23 height := (self.max_height or size.y) _min_ size.y24 shown_options := live_options.to(height-1)25 for opt in shown_options27 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 key36 clear(Right)37 clear(Below)38 disable()39 exit(code=1)40 is "Enter"42 clear(Right)43 clear(Below)44 disable()45 if chosen := self.chosen()46 say(chosen)47 exit(code=0)48 else49 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 -= 156 is "Down", "Tab"57 self.offset += 158 else if key.length == 159 self.query ++= key61 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 > 067 return live_options[(1 + self.offset) mod1 live_options.length]68 else69 return none71 func main(choices:Path=(/dev/stdin), prompt|p=">", query|q="", max_height|H:Int?=20)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,79 )80 set_mode(Normal)81 hide_cursor()82 picker.draw()83 repeat84 picker.draw()85 picker.update()86 disable()