diff options
Diffstat (limited to '')
-rw-r--r-- | lib/input_prompt.ml | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/lib/input_prompt.ml b/lib/input_prompt.ml index aec6021..a407741 100644 --- a/lib/input_prompt.ml +++ b/lib/input_prompt.ml @@ -3,22 +3,27 @@ module Common = Common open Notty type state = - { user_input : string + { (* 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; on_enter; on_cancel; prompt; screen } as state) = +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 + String.length prompt + 3, size_y)); + (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" user_input (String.make size_x ' ') + <|> 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 @@ -26,19 +31,36 @@ let rec render t ({ user_input; on_enter; on_cancel; prompt; screen } as state) 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 + | `Key (`Enter, []) -> on_enter (user_input_pre ^ user_input_post) | `Key (`Backspace, []) -> - if String.equal "" user_input + if String.equal "" (user_input_pre ^ user_input_post) then on_cancel () else ( let state = { state with - user_input = String.sub user_input 0 (max (String.length user_input - 1) 0) + 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 = user_input ^ String.make 1 c } in + let state = { state with user_input_pre = user_input_pre ^ String.make 1 c } in render t state | _ -> render t state |