WIP on handling relative navigation of selection regions

This commit is contained in:
Paul Chiusano 2014-09-17 16:56:04 -04:00
parent 8676c3830b
commit fba014de94
3 changed files with 68 additions and 7 deletions

View File

@ -16,6 +16,7 @@ import Unison.Node as N
import Graphics.Input(..)
import Graphics.Input.Field(..)
import Window
import Keyboard
import Mouse
import Text
@ -25,15 +26,21 @@ nums = let f x = E.Lit (E.Number (toFloat x))
expr = E.App (E.App (E.Ref "foo") nums) (E.App (E.Ref "baz") (E.Lit (E.Str "hello world!")))
scene : Int -> (Int,Int) -> Element
scene w (x,y) =
level : Signal Int
level =
let go {x,y} i = if | y == 1 -> i + 1
| y == -1 -> i - 1 `max` 0
| otherwise -> i
in Keyboard.arrows |> foldp go 0
scene : Int -> (Int,Int) -> Int -> Element
scene w (x,y) lvl =
let layout = E.layout expr { key = "bar", availableWidth = w - 50, metadata h = MD.anonymousTerm }
dummy = S.codeText "w00t"
paths = L.atRanked (Array.length . .path) layout (L.Region (L.Pt (x-48) (y-98)) 2 2)
isPrefix a b = a.hash == "bar" && Path.startsWith a.path b.path
region = case paths of
[] -> Nothing
_ -> L.selectableLub .selectable (L.region isPrefix layout (head (head paths)))
region = case drop (min (length paths - 1) lvl) paths of
(k :: _) :: _ -> L.selectableLub .selectable (L.region isPrefix layout k)
_ -> Nothing
selection = maybe Element.empty (S.selection layout) region
in flow down
[ spacer 50 1 `Element.beside` Element.height 100 (S.codeText ("paths: " ++ show paths))
@ -41,4 +48,4 @@ scene w (x,y) =
]
main : Signal Element
main = scene <~ Window.width ~ Mouse.position
main = scene <~ Window.width ~ Mouse.position ~ level

View File

@ -6,6 +6,8 @@ import Unison.Parser (Parser)
import Unison.Parser as P
import Unison.Jsonify as J
import Unison.Jsonify (Jsonify)
import Unison.Stream (Stream)
import Unison.Stream as Stream
data E
= Fn -- ^ Points at function in a function application
@ -18,9 +20,25 @@ type Path = Array E
push : Path -> E -> Path
push p e = A.push e p
pop : Path -> Maybe (Path, E)
pop p =
if A.length p == 0 then Nothing
else Just (A.slice 0 -1 p, A.getOrFail (A.length p - 1) p)
dropPop : Path -> Path
dropPop p = maybe p fst (pop p)
append : Path -> [E] -> Path
append p es = A.append p (A.fromList es)
next : Path -> Stream Path
next p = case pop p of
Nothing -> Stream.Empty
Just (init,last) -> case last of
Index i -> let tl _ = Stream.Empty
hd _ = push init (Index (i+1))
in Stream.Cons hd tl
-- Trim from the right of this path until hitting a `Body` path element.
-- This is used to normalize paths
trimToScope : Path -> Path

36
editor/Unison/Stream.elm Normal file
View File

@ -0,0 +1,36 @@
module Unison.Stream where
data Stream a = Empty | Cons (() -> a) (() -> Stream a)
fromList : [a] -> Stream a
fromList a = case a of
[] -> Empty
h :: t -> Cons (\_ -> h) (\_ -> fromList t)
unfold : (s -> (a,s)) -> s -> Stream a
unfold f s =
let (h,s') = f s
in Cons (\_ -> h) (\_ -> unfold f s')
uncons : Stream a -> Maybe (a, () -> Stream a)
uncons s = case s of
Empty -> Nothing
Cons h t -> Just (h (), t)
take : Int -> Stream a -> Stream a
take n s =
if n <= 0 then Empty
else case s of
Empty -> Empty
Cons h t -> Cons h (\_ -> take (n-1) (t ()))
maybeHead : Stream a -> Maybe a
maybeHead s = case s of
Empty -> Nothing
Cons h _ -> Just (h ())
append : Stream a -> Stream a -> Stream a
append l r = case l of
Empty -> r
Cons h t -> Cons h (\_ -> t () `append` r)