From 2c0f6e026acb2ecfc1c39d617f47d024e404bb9d Mon Sep 17 00:00:00 2001 From: Marc Coquand Date: Thu, 30 May 2024 08:45:22 -0500 Subject: Input Prompt: Implement left and right arrow --- lib/done.ml | 6 ++++-- lib/headlines.ml | 9 ++++++--- lib/input_prompt.ml | 38 ++++++++++++++++++++++++++++++-------- lib/stitched_article.ml | 9 ++++++--- lib/todos.ml | 6 ++++-- 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/lib/done.ml b/lib/done.ml index 810ef90..18e7b89 100644 --- a/lib/done.ml +++ b/lib/done.ml @@ -108,7 +108,8 @@ let rec render | `Key (`ASCII 's', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "REGEXP" ; on_enter = (fun tag -> @@ -152,7 +153,8 @@ let rec render let selected_file = Grep.execution_directory ^ "/" ^ selected_file in let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "COMMAND" ; on_enter = (fun command -> diff --git a/lib/headlines.ml b/lib/headlines.ml index 3c94f12..b8303c0 100644 --- a/lib/headlines.ml +++ b/lib/headlines.ml @@ -115,7 +115,8 @@ let rec render | `Key (`ASCII 'o', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "EXPORT TO" ; on_enter = (fun path -> @@ -164,7 +165,8 @@ let rec render | `Key (`ASCII 's', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_post = "" + ; user_input_pre = "" ; prompt = "REGEXP" ; on_enter = (fun tag -> @@ -199,7 +201,8 @@ let rec render let selected_file = Grep.execution_directory ^ "/" ^ selected_file in let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_post = "" + ; user_input_pre = "" ; prompt = "COMMAND" ; on_enter = (fun command -> 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 diff --git a/lib/stitched_article.ml b/lib/stitched_article.ml index d333747..9548e11 100644 --- a/lib/stitched_article.ml +++ b/lib/stitched_article.ml @@ -96,7 +96,8 @@ let rec render | `Key (`ASCII 'o', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "EXPORT TO" ; on_enter = (fun path -> @@ -128,7 +129,8 @@ let rec render let selected_file = Grep.execution_directory ^ "/" ^ selected_file in let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "COMMAND" ; on_enter = (fun command -> @@ -174,7 +176,8 @@ let rec render | `Key (`ASCII 's', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "REGEXP" ; on_enter = (fun tag -> diff --git a/lib/todos.ml b/lib/todos.ml index 83a497b..f2e461d 100644 --- a/lib/todos.ml +++ b/lib/todos.ml @@ -127,7 +127,8 @@ let rec render | `Key (`ASCII 's', []) -> let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_pre = "" + ; user_input_post = "" ; prompt = "REGEXP" ; on_enter = (fun tag -> @@ -155,7 +156,8 @@ let rec render let selected_file = Grep.execution_directory ^ "/" ^ selected_file in let (input_state : Input_prompt.state) = { screen = img - ; user_input = "" + ; user_input_post = "" + ; user_input_pre = "" ; prompt = "COMMAND" ; on_enter = (fun command -> -- cgit v1.2.3