blob: a4077419a954d7ac526b91bfa8fb9b0ea64c93c0 (
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
|
module Grep = Grep
module Common = Common
open Notty
type state =
{ (* Pre = before the cursor, post = after the cursor *)
user_input_pre : string
; user_input_post : string
; on_enter : string -> unit
; on_cancel : unit -> unit
; prompt : string
; screen : I.t
}
let rec render
t
({ user_input_pre; user_input_post; on_enter; on_cancel; prompt; screen } as state)
=
let size_x, size_y = Common.Term.size t in
Common.Term.cursor
t
(Some (String.length user_input_pre + String.length prompt + 3, size_y));
let img =
let open I in
I.strf " %s " ~attr:(A.st A.reverse) prompt
<|> I.strf " %s%s%s" user_input_pre user_input_post (String.make size_x ' ')
|> I.pad ~l:0 ~t:(size_y - 1)
</> screen
in
Common.Term.image t img;
match Common.Term.event t with
| `End | `Key (`Escape, []) | `Key (`ASCII 'G', [ `Ctrl ]) | `Key (`ASCII 'C', [ `Ctrl ])
-> on_cancel ()
| `Key (`Enter, []) -> on_enter (user_input_pre ^ user_input_post)
| `Key (`Backspace, []) ->
if String.equal "" (user_input_pre ^ user_input_post)
then on_cancel ()
else (
let state =
{ state with
user_input_pre =
String.sub user_input_pre 0 (max (String.length user_input_pre - 1) 0)
}
in
render t state)
| `Resize _ -> render t state
| `Key (`Arrow `Left, []) ->
if user_input_pre = ""
then render t state
else (
let char_to_move = Str.last_chars user_input_pre 1
and new_pre = Str.string_before user_input_pre (String.length user_input_pre - 1) in
let new_post = char_to_move ^ user_input_post in
render t { state with user_input_pre = new_pre; user_input_post = new_post })
| `Key (`Arrow `Right, []) ->
if user_input_post = ""
then render t state
else (
let char_to_move = Str.first_chars user_input_post 1
and new_post = Str.string_after user_input_post 1 in
let new_pre = user_input_pre ^ char_to_move in
render t { state with user_input_pre = new_pre; user_input_post = new_post })
| `Key (`ASCII c, []) ->
let state = { state with user_input_pre = user_input_pre ^ String.make 1 c } in
render t state
| _ -> render t state
|