package miaou-core

  1. Overview
  2. Docs
Miaou core/widgets (no drivers, no SDL)

Install

dune-project
 Dependency

Authors

Maintainers

Sources

v0.5.2.tar.gz
md5=60a3b9f181f24572a06a9492532bfdda
sha512=fcc35a275066be2900e6201782faf47503076fa4640f08cf78067835a6f447b74613009e55b2ac799adb7ca46f1bffa261fc5971753f2cc3c6bef327511c7ef6

doc/src/miaou-core.core/prompt.ml.html

Source file prompt.ml

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
(*****************************************************************************)
(*                                                                           *)
(* SPDX-License-Identifier: MIT                                              *)
(* Copyright (c) 2026 Nomadic Labs <contact@nomadic-labs.com>                *)
(*                                                                           *)
(*****************************************************************************)

(* Reusable prompt helpers. See prompt.mli for the public API. *)

(* {1 Pure result mapping} *)

let confirm_outcome = function `Commit -> true | `Cancel -> false

let input_result outcome ~text =
  match outcome with `Commit -> Some text | `Cancel -> None

let select_result outcome ~selected =
  match outcome with `Commit -> selected | `Cancel -> None

(* {1 Confirm modal page}

   A trivial page that renders a static message. Modal_manager's commit_on /
   cancel_on lists handle Enter and Esc — the page itself is a passive
   message box. *)

module Confirm_page (M : sig
  val message : string
end) : Tui_page.PAGE_SIG = struct
  type state = unit

  type pstate = state Navigation.t

  type msg = unit

  type key_binding = state Tui_page.key_binding_desc

  let init () = Navigation.make ()

  let update ps _ = ps

  let view _ ~focus:_ ~size:_ = M.message ^ "\n\n[Enter] yes   [Esc] no"

  let handle_key ps _ ~size:_ = ps

  let on_key ps _ ~size:_ = (ps, Miaou_interfaces.Key_event.Bubble)

  let on_modal_key ps _ ~size:_ = (ps, Miaou_interfaces.Key_event.Bubble)

  let key_hints (_ : pstate) = []

  let move ps _ = ps

  let refresh ps = ps

  let service_select ps _ = ps

  let service_cycle ps _ = ps

  let handle_modal_key ps _ ~size:_ = ps

  let keymap (_ : pstate) = []

  let handled_keys () = []

  let back ps = ps

  let has_modal _ = false
end

(* {1 Input (textbox) modal page} *)

module Input_page : sig
  include
    Tui_page.PAGE_SIG with type state = Miaou_widgets_input.Textbox_widget.t

  val make_init : ?placeholder:string -> ?initial:string -> unit -> pstate
end = struct
  type state = Miaou_widgets_input.Textbox_widget.t

  type pstate = state Navigation.t

  type msg = unit

  type key_binding = state Tui_page.key_binding_desc

  let make_init ?placeholder ?(initial = "") () =
    Navigation.make
      (Miaou_widgets_input.Textbox_widget.open_centered
         ~width:40
         ~initial
         ~placeholder
         ())

  let init () = make_init ()

  let update ps _ = ps

  let view ps ~focus:_ ~size:_ =
    Miaou_widgets_input.Textbox_widget.render ps.Navigation.s ~focus:true

  let handle_key ps key_str ~size:_ =
    Navigation.update
      (fun s -> Miaou_widgets_input.Textbox_widget.handle_key s ~key:key_str)
      ps

  let on_key ps key ~size =
    let key_str = Keys.to_string key in
    let ps' = handle_key ps key_str ~size in
    (ps', Miaou_interfaces.Key_event.Bubble)

  let on_modal_key ps key ~size = on_key ps key ~size

  let key_hints (_ : pstate) = []

  let move ps _ = ps

  let refresh ps = ps

  let service_select ps _ = ps

  let service_cycle ps _ = ps

  let handle_modal_key ps key ~size:_ =
    if Miaou_helpers.Mouse.is_mouse_event key then
      Navigation.update
        (fun s -> Miaou_widgets_input.Textbox_widget.handle_key s ~key)
        ps
    else ps

  let keymap (_ : pstate) = []

  let handled_keys () = []

  let back ps = ps

  let has_modal _ = false
end

(* {1 Select modal page} *)

module Select_page (Item : sig
  type t

  val items : t list

  val to_string : t -> string
end) : sig
  include
    Tui_page.PAGE_SIG
      with type state = Item.t Miaou_widgets_input.Select_widget.t

  val make_init : unit -> pstate

  val extract : pstate -> Item.t option
end = struct
  type state = Item.t Miaou_widgets_input.Select_widget.t

  type pstate = state Navigation.t

  type msg = unit

  type key_binding = state Tui_page.key_binding_desc

  let make_init () =
    Navigation.make
      (Miaou_widgets_input.Select_widget.open_centered
         ~cursor:0
         ~title:""
         ~items:Item.items
         ~to_string:Item.to_string
         ())

  let init () = make_init ()

  let update ps _ = ps

  let view ps ~focus ~size:_ =
    Miaou_widgets_input.Select_widget.render ps.Navigation.s ~focus

  let handle_key ps key_str ~size:_ =
    Navigation.update
      (fun s -> Miaou_widgets_input.Select_widget.handle_key s ~key:key_str)
      ps

  let on_key ps key ~size =
    let key_str = Keys.to_string key in
    let ps' = handle_key ps key_str ~size in
    (ps', Miaou_interfaces.Key_event.Bubble)

  let on_modal_key ps key ~size = on_key ps key ~size

  let key_hints (_ : pstate) = []

  let move ps _ = ps

  let refresh ps = ps

  let service_select ps _ = ps

  let service_cycle ps _ = ps

  let handle_modal_key ps key ~size =
    if Miaou_helpers.Mouse.is_mouse_event key then
      Navigation.update
        (fun s ->
          Miaou_widgets_input.Select_widget.handle_key_with_size s ~key ~size)
        ps
    else ps

  let keymap (_ : pstate) = []

  let handled_keys () = []

  let extract ps =
    Miaou_widgets_input.Select_widget.get_selection ps.Navigation.s

  let back ps = ps

  let has_modal _ = false
end

(* {1 Public helpers} *)

let confirm ~title ~message ~on_result () =
  let module C = Confirm_page (struct
    let message = message
  end) in
  Modal_manager.confirm
    (module C)
    ~init:(C.init ())
    ~title
    ~dim_background:true
    ~on_result
    ()

let input ?placeholder ?initial ~title ~on_result () =
  let init = Input_page.make_init ?placeholder ?initial () in
  Modal_manager.confirm_with_extract
    (module Input_page)
    ~init
    ~title
    ~dim_background:true
    ~extract:(fun ps ->
      Some (Miaou_widgets_input.Textbox_widget.get_text ps.Navigation.s))
    ~on_result
    ()

let select (type a) ~title ~items ~(to_string : a -> string) ~on_result () =
  let module S = Select_page (struct
    type t = a

    let items = items

    let to_string = to_string
  end) in
  Modal_manager.confirm_with_extract
    (module S)
    ~init:(S.make_init ())
    ~title
    ~dim_background:true
    ~extract:S.extract
    ~on_result
    ()