hop-2012/server/thirdparty/lwt-2.3.2/src/text/lwt_read_line.mli

454 lines
14 KiB
OCaml

(* Lightweight thread library for Objective Caml
* http://www.ocsigen.org/lwt
* Module Lwt_read_line
* Copyright (C) 2009 Jérémie Dimino
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, with linking exceptions;
* either version 2.1 of the License, or (at your option) any later
* version. See COPYING file for details.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*)
(** Interactive line input *)
(** {6 Definitions} *)
exception Interrupt
(** Exception raised when the user press [Ctrl^D] *)
type edition_state = Text.t * Text.t
(** An edition state, it is a pair of two UTF-8 encoded strings:
- the input before the cursor
- the input after the cursor *)
type prompt = Lwt_term.styled_text
(** A prompt. It may contains colors. *)
type text_set = Set.Make(Text).t
(** {8 Completion} *)
(** Result of a completion function: *)
type completion_result = {
comp_state : edition_state;
(** The new edition state *)
comp_words : text_set;
(** A list of possibilities *)
}
type completion = edition_state -> completion_result Lwt.t
(** Type of a completion function. It takes as argument the
current edition state.
Note: the thread launched by the completion function is
cancelled using {!Lwt.cancel} if the user continue typing
text. *)
val lookup : Text.t -> text_set -> (Text.t * text_set)
(** [lookup word words] lookup for completion of [word] into
[words]. It returns [(prefix, possibilities)] where
[possibilities] are all words starting with [word] and [prefix]
is the longest common prefix of [possibilities]. *)
val complete : ?suffix : Text.t -> Text.t -> Text.t -> Text.t -> text_set -> completion_result
(** [complete ?suffix before word after words] basic completion
functions. [words] is a list of possible completions for
[word].
If completion succeed [suffix] is append to the resulting
text. It defaults to [" "]. *)
val print_words : Lwt_text.output_channel -> int -> string list -> unit Lwt.t
(** [print_words oc columns strs] pretty-prints a list of words. *)
(** {8 History} *)
type history = Text.t list
(** Type of an history *)
val add_entry : Text.t -> history -> history
(** [add_entry line history] returns the history [history] plus
[line] at the beginning. If [line] already appears at the
beginning or contains only spaces, it is discarded. *)
val save_history : string -> history -> unit Lwt.t
(** [save_history filename history] saves [history] to
[filename]. History is saved by separating lines with a null
character. *)
val load_history : string -> history Lwt.t
(** [load_history filename] loads history from [filename]. Returns
the empty history if the the file does not exit. *)
(** {8 Clipboards} *)
(** Type of a clipboard. *)
class clipboard : object
method set : Text.t -> unit
method contents : Text.t React.signal
end
val clipboard : clipboard
(** The global clipboard. All read-line instances which do not use a
specific clipboard use this one. *)
(** {6 High-level functions} *)
type completion_mode = [ `classic | `real_time | `none ]
(** The completion mode.
- [`classic] means that when the user hit [Tab] a list of
possible completions is proposed,
- [`real_time] means that possible completions are shown to
the user as he types, and he can navigate in them with
[Meta+left], [Meta+right]
- [`none] means no completion at all *)
val read_line :
?history : history ->
?complete : completion ->
?clipboard : clipboard ->
?mode : completion_mode ->
?prompt : prompt -> unit -> Text.t Lwt.t
(** [readline ?history ?complete ?mode ?prompt ()] inputs some text
from the user. If input is not a terminal, it defaults to
[Lwt_text.read_line Lwt_text.stdin].
If @param mode contains the current completion mode. It defaults
to [`real_time].
@param prompt defaults to [Lwt_term.Text "# "] *)
type password_style = [ `empty | `clear | `text of Text.t ]
(** Style which indicate how the password is echoed to the user:
- with [`empty] nothing is printed
- with [`clear] the password is displayed has it
- with [`text ch] all characters are replaced by [ch] *)
val read_password :
?clipboard : clipboard ->
?style : password_style ->
?prompt : prompt -> unit -> Text.t Lwt.t
(** [read_password ?clipboard ?clear ~prompt ()] inputs a password
from the user. This function fails if input is not a terminal.
@param style defaults to [`text "*"].
*)
val read_keyword :
?history : history ->
?case_sensitive : bool ->
?mode : completion_mode ->
?prompt : prompt ->
values : (Text.t * 'value) list -> unit -> 'value Lwt.t
(** [read_keyword ?history ?case_sensitive ?mode ~prompt ~keywords
()] reads one word which is a member of [words]. And returns
which keyword the user choosed.
[case_sensitive] default to [false]. *)
val read_yes_no : ?history : history -> ?mode : completion_mode -> ?prompt : prompt -> unit -> bool Lwt.t
(** [read_yes_no ?history ?dynamic prompt ()] is the same as:
{[
read_keyword ?history ?dynamic prompt [("yes", true); ("no", false)] ()
]}
*)
(** {6 Low-level interaction} *)
(** This part allow you to implements your own read-line function, or
just to use the readline engine in another context (message box,
...). *)
(** Readline commands *)
module Command : sig
(** Type of all read-line function: *)
type t =
| Nop
(** Command which do nothing. Unknown keys maps to this commands. *)
| Char of Text.t
(** Any printable character. *)
| Backward_delete_char
| Forward_delete_char
| Beginning_of_line
| End_of_line
| Complete
| Meta_complete
| Kill_line
| Backward_kill_line
| Accept_line
| Backward_delete_word
| Forward_delete_word
| History_next
| History_previous
| Break
| Clear_screen
| Insert
| Refresh
| Backward_char
| Forward_char
| Set_mark
| Paste
| Copy
| Cut
| Uppercase
| Lowercase
| Capitalize
| Backward_word
| Forward_word
| Backward_search
| Complete_left
| Complete_right
| Complete_up
| Complete_down
| Complete_first
| Complete_last
| Undo
| Delete_char_or_list
val to_string : t -> string
(** [to_string cmd] returns a string representation of a command *)
val of_string : string -> t
(** [of_string cld] tries to convert a command name to a
command. @raise Failure if it fails. *)
val names : (t * string) list
(** [names] is the list of all commands (except [Char ch]) with
their name. *)
val of_key : Lwt_term.key -> t
(** [of_key key] returns the command to which a key is mapped. *)
end
(** Engine *)
module Engine : sig
(** Note: this part know nothing about rendering or completion. *)
(** State when the user is doing selection: *)
type selection_state = {
sel_text : Text.t;
(** The whole input text on which the selection is working *)
sel_mark : Text.pointer;
(** Pointer to the mark *)
sel_cursor : Text.pointer;
(** Pointer to the cursor *)
}
(** State when searching in the history *)
type search_state = {
search_word : Text.t;
(** The word we are looking for *)
search_history : history;
(** Position in history. The first element is a sentence
containing the searched word *)
search_init_history : history;
(** The initial history, before searching for a word *)
}
(** The engine mode: *)
type mode =
| Edition of edition_state
(** The user is typing some text *)
| Selection of selection_state
(** The user is selecting some text *)
| Search of search_state
(** The user is searching the given word in the history *)
(** An engine state: *)
type state = {
mode : mode;
history : history * history;
(** Cursor to the history position. *)
}
val init : history -> state
(** [init history] return a initial state using the given
history *)
val reset : state -> state
(** [reset state] reset the given state, if the user was doing a
selection, it is canceled *)
val update : engine_state : state -> ?clipboard : clipboard -> command : Command.t -> unit -> state
(** [update ~state ?clipboard ~command ()] update an engine state by
processing the given command. It returns the new state, and
may have the side effect of changing the clipboard contents.
[clipboard] defaults to the global clipboard.
*)
val edition_state : state -> edition_state
(** Returns the edition state of a state, whatever its mode is. *)
val all_input : state -> Text.t
(** Returns the current complete user input. *)
end
(** Rendering to the terminal *)
module Terminal : sig
type state
(** State of rendering *)
val init : state
(** Initial state *)
(** The following functions are the one used by read-line functions
of this module. *)
(** Box for the completion: *)
type box =
| Box_none
(** No box at all *)
| Box_empty
(** An empty box *)
| Box_words of text_set * int
(** [BM_words(words, position)] is a box with the given list
of words. [position] is the position of the selected word
in the list.. *)
| Box_message of string
(** A box containing only the given message *)
val draw :
columns : int ->
?map_text : (Text.t -> Text.t) ->
?box : box ->
render_state : state ->
engine_state : Engine.state ->
prompt : prompt -> unit -> Lwt_term.styled_text * state
(** [draw ~column ?map_text ?bar ~render_state ~engine_state
prompt ()] returns [(text, state)] where [state] is the new
rendering state, and [text] is a text containing escape
sequences. When printed, it will update the displayed state.
@param map_text is a function used to map user input before
printing it, for example to hide passwords.
@param message is a message to display if completion is not
yet available.
@param box defaults to {!Box_none}. *)
val last_draw :
columns : int ->
?map_text : (Text.t -> Text.t) ->
render_state : state ->
engine_state : Engine.state ->
prompt : prompt -> unit -> Lwt_term.styled_text
(** Draw for the last time, i.e. the cursor is left after the text
and not at current position. *)
val erase : columns : int -> render_state : state -> unit -> Lwt_term.styled_text
(** [erase ~columns ~render_state ()] returns a text which will
erase everything (the prompt, user input, completion, ...).
After an erase, the rendering state is [init]. *)
end
(** {6 Advanced use} *)
(** Controlling a running read-line instance *)
module Control : sig
type 'a t
(** Type of a running read-line instance, returning a value of
type ['a] *)
(** {6 Control} *)
val result : 'a t -> 'a Lwt.t
(** Threads waiting for the read-line instance to terminates *)
val send_command : 'a t -> Command.t -> unit
(** [send_command instance command] sends the given command to the
read-line instance *)
val accept : 'a t -> unit
(** [accept instance = send_command instance Command.Accept_line] *)
val interrupt : 'a t -> unit
(** [accept instance = send_command instance Command.Break] *)
val hide : 'a t -> unit Lwt.t
(** Hides everything (prompt, user input, completion box) until
{!show} is called. *)
val show : 'a t -> unit Lwt.t
(** Un-hide everything *)
(** Note: in case the input is not a terminal, read-line instances
are not controllable. i.e. {!accept}, {!refresh}, ... have no
effect. *)
(** {6 Creation of read-line instances} *)
type prompt = Engine.state React.signal -> Lwt_term.styled_text React.signal
(** The prompt a signal which may depends on the engine state *)
type state
(** State of an instance *)
val engine_state : state -> Engine.state
(** Return the engine state of the given state *)
val render_state : state -> Terminal.state
(** Return the rendering state of the given state *)
val make :
?history : history ->
?complete : completion ->
?clipboard : clipboard ->
?mode : [ completion_mode | `none ] ->
?map_text : (Text.t -> Text.t) ->
?filter : (state -> Command.t -> Command.t Lwt.t) ->
map_result : (Text.t -> 'a Lwt.t) ->
?prompt : prompt -> unit -> 'a t
(** Creates a new read-line instance with the given
parameters. [filter] is called to handle commands. You can
return {!Command.Nop} to drop a command. *)
(** {6 Predefined instances} *)
val read_line :
?history : history ->
?complete : completion ->
?clipboard : clipboard ->
?mode : completion_mode ->
?prompt : prompt -> unit -> Text.t t Lwt.t
val read_password :
?clipboard : clipboard ->
?style : password_style ->
?prompt : prompt -> unit -> Text.t t Lwt.t
val read_keyword :
?history : history ->
?case_sensitive : bool ->
?mode : completion_mode ->
?prompt : prompt ->
values : (Text.t * 'value) list -> unit -> 'value t Lwt.t
val read_yes_no :
?history : history ->
?mode : completion_mode ->
?prompt : prompt -> unit -> bool t Lwt.t
end