aboutsummaryrefslogtreecommitdiff
path: root/screen.ml
diff options
context:
space:
mode:
Diffstat (limited to 'screen.ml')
-rwxr-xr-xscreen.ml112
1 files changed, 61 insertions, 51 deletions
diff --git a/screen.ml b/screen.ml
index d48381a..a8e2d0c 100755
--- a/screen.ml
+++ b/screen.ml
@@ -4,13 +4,13 @@ module Color = Curses.Color
module T2 = Tools.Tuple2
+module Option = Tools.Option
+
let cell_size = 10
let u = UTF8.from_utf8string
-type t = Sheet.t
-
-type screen = {
+type t = {
window: Curses.window; (* the main window *)
sheet: Curses.window; (* the spreadsheet *)
input: Curses.window; (* the input window *)
@@ -52,15 +52,16 @@ end
let status screen msg = begin
let height, width = screen.size in
- let encoded = UTF8.encode msg in
- let status = Bytes.make (width -1) ' ' in
- Bytes.blit encoded 0 status 0 (String.length encoded);
- Curses.werase screen.status;
- if not (
- Curses.mvwaddstr screen.status 0 0 encoded
- && Curses.wrefresh screen.status
- ) then
+ UTF8.encode msg |> Option.iter (fun encoded ->
+ let status = Bytes.make (width -1) ' ' in
+ Bytes.blit encoded 0 status 0 (String.length encoded);
+ Curses.werase screen.status;
+ if not (
+ Curses.mvwaddstr screen.status 0 0 encoded
+ && Curses.wrefresh screen.status
+ ) then
raise (Failure "Status update")
+ )
end
(** Draw the spreadsheet *)
@@ -99,10 +100,13 @@ let draw data screen = begin
else
Curses.wattrset screen.sheet (Attrs.color_pair 1 )
end;
+
ignore
@@ Curses.mvwaddstr screen.sheet 0 (x * cell_size + screen.left_margin)
- @@ Printf.sprintf "%-*s" cell_size (UTF8.encode @@ Cell.to_hname pos_x);
+ @@ Printf.sprintf "%-*s" cell_size (UTF8.raw_encode @@ Cell.to_hname pos_x);
+
Curses.wattrset screen.sheet Attrs.normal;
+
for y = 1 to (height-2) do
let pos_y = y + (snd screen.start) - 1 in
@@ -118,22 +122,25 @@ let draw data screen = begin
Curses.wattrset screen.sheet Attrs.normal;
end;
+
+ (* Get the content from the cell *)
let content = Sheet.Raw.get_value (pos_x, pos_y) data.Sheet.data
- |> ScTypes.Result.show
- |> UTF8.split ~sep:(u"\n") in
-
- let value = UTF8.encode content
- and length = UTF8.length content in
- let strlength = String.length value in
- let blank = cell_size - length in
- let padding = if blank > 0
- then String.make blank ' '
- else "" in
-
- ignore
- @@ Curses.mvwaddnstr screen.sheet y (x * cell_size + screen.left_margin)
- (Printf.sprintf "%s%s" value padding)
- 0 (blank + strlength)
+ |> Option.map (fun x -> UTF8.split ~sep:(u"\n") (ScTypes.Result.show x))
+ |> Option.default UTF8.empty in
+
+ (* If the content is defined, try to encode it and print it*)
+ UTF8.encode content |> Tools.Option.iter (fun value ->
+ let length = UTF8.length content in
+ let strlength = String.length value in
+ let blank = cell_size - length in
+ let padding = if blank > 0
+ then String.make blank ' '
+ else "" in
+ ignore
+ @@ Curses.mvwaddnstr screen.sheet y (x * cell_size + screen.left_margin)
+ (Printf.sprintf "%s%s" value padding)
+ 0 (blank + strlength)
+ )
done
done;
ignore @@ Curses.wrefresh screen.sheet;
@@ -190,20 +197,23 @@ let draw_input t screen = begin
let expr = Sheet.Raw.get_expr (Selection.extract t.Sheet.selected) t.Sheet.data
|> Expression.show in
- (* Compute the difference between number of bytes in the string, and the
- number of character printed : Printf.sprintf format use the bytes number
- in the string, while Curses print the characters in the user encoding *)
let result = Sheet.Raw.get_value (Selection.extract t.Sheet.selected) t.Sheet.data
- |> ScTypes.Result.show in
- let encoded_result = UTF8.encode result in
- let result_length_delta = (UTF8.length result) - (String.length encoded_result) in
+ |> Option.map ScTypes.Result.show
+ |> Option.default UTF8.empty in
- ignore (
- encoded_result
- |> Printf.sprintf "%-*s" (width - 11 - result_length_delta)
- |> Curses.mvwaddstr screen.input 0 10
+ UTF8.encode result |> Option.iter (fun encoded_result ->
+ (* Compute the difference between number of bytes in the string, and the
+ number of character printed : Printf.sprintf format use the bytes number
+ in the string, while Curses print the characters in the user encoding *)
+ let result_length_delta = (UTF8.length result) - (String.length encoded_result) in
+
+ ignore (
+ encoded_result
+ |> Printf.sprintf "%-*s" (width - 11 - result_length_delta)
+ |> Curses.mvwaddstr screen.input 0 10
- && Curses.wrefresh screen.input);
+ && Curses.wrefresh screen.input)
+ );
status screen expr;
screen
end
@@ -248,8 +258,8 @@ let resize data t = begin
end
let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin
- let encodedPrefix = UTF8.encode prefix
- and encodedInit = UTF8.encode init in
+ let encodedPrefix = UTF8.raw_encode prefix
+ and encodedInit = UTF8.raw_encode init in
let with_refs, position = match position with
| None -> false, (1, 1)
| Some x -> true, x in
@@ -262,7 +272,7 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin
| [] -> ()
| elems -> ( (* Rewrite each char after the cursor *)
let y, x = Curses.getyx t.status in
- List.iter (fun x -> ignore @@ Curses.waddstr t.status (UTF8.encode x)) elems;
+ List.iter (fun x -> ignore @@ Curses.waddstr t.status (UTF8.raw_encode x)) elems;
ignore @@ Curses.wmove t.status y x )
end
@@ -285,6 +295,10 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin
| "\027" -> (* Escape, cancel the modifications *)
None
| "\010" -> (* Enter, validate the input *)
+
+ (* We concatenate all the characters. This can create an invalid string in
+ * the current locale (if there are copy/paste, or other events).
+ *)
Some (UTF8.implode @@ (UTF8.rev_implode before)::after)
| "\001\004" -> (* Left *)
@@ -414,7 +428,7 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin
and insert_cell_name position name before after = begin
let cell_name = Cell.to_string @@ (position, (false, false)) in
ignore @@ delete_previous name;
- ignore @@ Curses.waddstr t.status (UTF8.encode cell_name);
+ ignore @@ Curses.waddstr t.status (UTF8.raw_encode cell_name);
rewrite_after after;
ignore @@ Curses.wrefresh t.status;
select_content position cell_name before after @@ read_key t
@@ -438,12 +452,8 @@ let search screen = begin
end
end
-(*
-let read_input position screen = begin
- let result = editor ~position ~init:(u"=") screen in
- begin match result with
- | Some content -> content
- | None -> UTF8.empty
- end
-end
-*)
+let run f =
+ let window = init () in
+ Tools.try_finally
+ (fun () -> f window)
+ (fun () -> ignore @@ close window )