From 91fb5ea5a3bfa801d36a5737012e92193e72ffc1 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 27 Oct 2017 08:52:48 -0400 Subject: [PATCH] tweaked scrollmap implementation. Behavior is still buggy but it can scroll down smoothly for long lines --- edit.ml | 8 ++++---- lib/buf.ml | 9 ++------- lib/buf.mli | 12 +++++++++++- lib/draw.ml | 4 ++-- lib/rope.ml | 6 ++---- lib/scrollmap.ml | 24 ++++++++++++++++++------ lib/x11_prims.c | 8 ++++---- 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/edit.ml b/edit.ml index 0e13580..b6f3ff0 100644 --- a/edit.ml +++ b/edit.ml @@ -17,7 +17,6 @@ module View = struct let draw view csr = let view = (resize view (Draw.Cursor.max_width csr)) in - (*Draw.dark_bkg (csr.width - csr.x) (csr.height - csr.y) csr;*) Draw.buffer csr view.buf (Scrollmap.first view.map); view @@ -35,15 +34,16 @@ let edit_view = ref (View.empty 640 480) ******************************************************************************) let onfocus focused = () -let onkeypress mods rune = () +let onkeypress mods rune = + edit_view := View.scroll_dn !edit_view let onmousebtn mods btn x y pressed = match btn with | 1 -> () | 2 -> () | 3 -> () - | 4 -> (if pressed then edit_view := View.scroll_up !edit_view) - | 5 -> (if pressed then edit_view := View.scroll_dn !edit_view) + | 4 -> (edit_view := View.scroll_up !edit_view) + | 5 -> (edit_view := View.scroll_dn !edit_view) | _ -> () let onmousemove mods x y = () diff --git a/lib/buf.ml b/lib/buf.ml index 10ca997..acade5f 100644 --- a/lib/buf.ml +++ b/lib/buf.ml @@ -1,21 +1,17 @@ type t = { - start : int; path : string; rope : Rope.t } let empty = - { start = 0; path = ""; rope = Rope.empty } + { path = ""; rope = Rope.empty } let load path = - { start = 0; path = path; rope = Rope.from_string (Misc.load_file path) } + { path = path; rope = Rope.from_string (Misc.load_file path) } let rope buf = buf.rope -let start buf = - buf.start - let iter_from fn buf i = Rope.iter_from fn buf.rope i @@ -27,4 +23,3 @@ let iteri_from fn buf i = let run_unit_tests () = let open Test in () - diff --git a/lib/buf.mli b/lib/buf.mli index 37720f1..fae0030 100644 --- a/lib/buf.mli +++ b/lib/buf.mli @@ -1,7 +1,17 @@ +(* +module Cursor : sig + type t + val to_offset : t -> int + val next_rune : t -> t + val prev_rune : t -> t + val next_line : t -> t + val prev_line : t -> t +end +*) + type t val empty : t val load : string -> t val rope : t -> Rope.t -val start : t -> int val iter_from : (int -> bool) -> t -> int -> unit val iteri_from : (int -> int -> bool) -> t -> int -> unit diff --git a/lib/draw.ml b/lib/draw.ml index 8be4d7c..44c9e8b 100644 --- a/lib/draw.ml +++ b/lib/draw.ml @@ -112,6 +112,6 @@ let scroll csr = csr.x <- csr.x + 14; vrule csr.height csr -let edit csr buf off = +let edit csr buf = dark_bkg (csr.width - csr.x) (csr.height - csr.y) csr; - buffer csr buf off + buffer csr buf diff --git a/lib/rope.ml b/lib/rope.ml index e7facc4..9c6f076 100644 --- a/lib/rope.ml +++ b/lib/rope.ml @@ -67,8 +67,7 @@ let is_bol rope pos = let is_eol rope pos = if pos >= (last rope) then true - else let c = (getc rope (pos+1)) in - (c == 0x0A || c == 0x0D) + else ((getc rope (pos+1)) == 0x0A) let is_bow rope pos = false @@ -267,7 +266,7 @@ let run_unit_tests () = ); test "is_eol : should return true if pos is last char of line with \r\n ending" (fun () -> let rope = Leaf("abc\r\n", 0, 5) in - assert( is_eol rope 2 ); + assert( is_eol rope 3 ); ); test "is_eol : should return false if pos is not last char of line" (fun () -> let rope = Leaf("abcd\n", 0, 5) in @@ -279,7 +278,6 @@ let run_unit_tests () = let rope = Leaf("\nabc\n", 0, 5) in assert( (to_bol rope 2) == 1 ); ); - () (* diff --git a/lib/scrollmap.ml b/lib/scrollmap.ml index 8951c52..b180ae8 100644 --- a/lib/scrollmap.ml +++ b/lib/scrollmap.ml @@ -4,27 +4,40 @@ type t = { lines : int array } +let rec find_line lines off idx = + if idx > 0 && lines.(idx) > off then + find_line lines off (idx - 1) + else + idx + let make buf width off = let csr = Draw.Cursor.make (width, 0) 0 0 in let bol = (Rope.to_bol (Buf.rope buf) off) in let lines = ref [bol] in + let csr = Draw.Cursor.make (width, 0) 0 0 in let process_glyph i c = if (Draw.Cursor.next_glyph csr c) then lines := i :: !lines; - ((Rope.is_eol (Buf.rope buf) i) == false) + ((Rope.is_eol (Buf.rope buf) i) == false) in Buf.iteri_from process_glyph buf off; - { width = width; index = 0; lines = (Array.of_list (List.rev !lines)) } + let lines = (Array.of_list (List.rev !lines)) in + let index = (find_line lines off ((Array.length lines) - 1)) in + { width = width; lines = lines; index = index } let first map = + (* + Printf.printf "%d: %d" map.index map.lines.(map.index); + print_endline ""; + *) map.lines.(map.index) let bopl buf off = - let next = ((Rope.to_bol (Buf.rope buf) off) - 1) in + let next = ((Rope.to_bol (Buf.rope buf) off) - 2) in Rope.limit_index (Buf.rope buf) next let bonl buf off = - let next = ((Rope.to_eol (Buf.rope buf) off) + 1) in + let next = ((Rope.to_eol (Buf.rope buf) off) + 2) in Rope.limit_index (Buf.rope buf) next let scroll_up map buf = @@ -32,8 +45,7 @@ let scroll_up map buf = if (next >= 0) then { map with index = next } else - let map = make buf map.width (bopl buf map.lines.(0)) in - { map with index = (Array.length map.lines) - 1 } + make buf map.width (bopl buf map.lines.(0)) let scroll_dn map buf = let next = map.index + 1 in diff --git a/lib/x11_prims.c b/lib/x11_prims.c index 3126ccf..c43193e 100644 --- a/lib/x11_prims.c +++ b/lib/x11_prims.c @@ -126,15 +126,15 @@ CAMLprim value x11_event_loop(value ms, value cbfn) { uint64_t t = getmillis(); while (XPending(X.display)) { XNextEvent(X.display, &e); - //printf("%d ", e.type); + printf("%d ", e.type); if (!XFilterEvent(&e, None) && EventHandlers[e.type]) { event = EventHandlers[e.type](&e); if (event != Val_int(TNone)) caml_callback(cbfn, event); } } - //puts(""); - //printf("time 1 %lu ", getmillis()-t); + puts(""); + printf("time 1 %lu ", getmillis()-t); t = getmillis(); if (X.running) { caml_callback(cbfn, mkvariant(TUpdate, 2, Val_int(X.width), Val_int(X.height))); @@ -148,7 +148,7 @@ CAMLprim value x11_event_loop(value ms, value cbfn) { } XCopyArea(X.display, X.pixmap, X.self, X.gc, 0, 0, X.width, X.height, 0, 0); } - //printf("\ntime 2 %lu\n", getmillis()-t); + printf("\ntime 2 %lu\n", getmillis()-t); XFlush(X.display); } CAMLreturn(Val_unit); -- 2.52.0