WIP on upgrading to 0.15

This commit is contained in:
Paul Chiusano 2015-05-04 17:38:24 -04:00
parent 5e518c9c39
commit cf8abfd2a5
28 changed files with 293 additions and 422 deletions

View File

@ -1,6 +1,6 @@
{ {
"version": "1.0.0", "version": "1.0.0",
"summary": "w00t", "summary": "Front-end for the Unison editor",
"repository": "https://github.com/USER/PROJECT.git", "repository": "https://github.com/USER/PROJECT.git",
"license": "MIT", "license": "MIT",
"source-directories": [ "source-directories": [
@ -8,9 +8,9 @@
], ],
"exposed-modules": ["Messages"], "exposed-modules": ["Messages"],
"native-modules" : true, "native-modules" : true,
"elm-version" : "0.15.0 <= v < 0.16.0",
"dependencies": { "dependencies": {
"elm-lang/core" : "1.0.0 <= v < 2.0.0", "elm-lang/core" : "2.0.0 <= v < 3.0.0",
"Dandandan/Easing" : "1.0.1 <= v < 2.0.0", "evancz/elm-http" : "1.0.0 <= v < 2.0.0"
"Dandandan/parser" : "5.0.1 <= v < 6.0.0"
} }
} }

View File

@ -2,10 +2,10 @@ module Elmz.Json.Decoder where
import Dict as M import Dict as M
import Json.Decode as J import Json.Decode as J
import Json.Decode (Decoder, andThen) import Json.Decode exposing (Decoder, andThen)
import List import List
import Set import Set
import Set (Set) import Set exposing (Set)
import String as S import String as S
type alias Decoder a = J.Decoder a type alias Decoder a = J.Decoder a

View File

@ -1,27 +1,31 @@
module Elmz.Json.Request where module Elmz.Json.Request where
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Http import Http
import Maybe import Maybe
import Result import Result
import Signal import Signal
import Task exposing (Task)
import Time import Time
type alias Request a b = type alias Request a b =
{ encoder : a -> Http.Request String { encoder : a -> Out String
, decoder : Decoder b } , decoder : Decoder b }
type alias Out a = { verb : String, url : String, body : a }
type alias Host = String type alias Host = String
type alias Path = String type alias Path = String
type Status e = Inactive | Waiting | Failed e type Status e = Inactive | Waiting | Failed e
post : Host -> Path -> Encoder a -> Decoder b -> Request a b post : Host -> Path -> Encoder a -> Decoder b -> Request a b
post host path e d = Request (jsonPost e host path) d post host path e d =
let out a = Out "POST" (host ++ "/" ++ path) (Encoder.render e a)
in Request out d
contramap : (a0 -> a) -> Request a b -> Request a0 b contramap : (a0 -> a) -> Request a b -> Request a0 b
contramap f r = { r | encoder <- r.encoder << f } contramap f r = { r | encoder <- r.encoder << f }
@ -32,35 +36,7 @@ map f r = { r | decoder <- Decoder.map f r.decoder }
to : Request a b -> (b -> c) -> Request a c to : Request a b -> (b -> c) -> Request a c
to r f = map f r to r f = map f r
send : Request a b -> a -> Signal (Maybe a) -> Signal (Result (Status String) b) sendPost : Request a b -> a -> Task Http.Error b
send r az ma = sendPost r a =
let a = Signals.justs ma |> Signal.map (Maybe.withDefault az) let out = r.encoder a
waitings = Signal.map (always (Result.Err Waiting)) a in Http.post r.decoder out.url (Http.string out.body)
results = Http.send (Signal.map r.encoder a) |> Signal.map (decodeResponse r.decoder)
inactives = Signal.map (always (Result.Err Inactive)) (Time.delay 0 results)
in results `Signal.merge` inactives `Signal.merge` waitings
isWaiting : Signal (Result (Status String) a) -> Signal Bool
isWaiting results =
let f r = case r of
Result.Err Waiting -> True
_ -> False
in Signal.map f results
jsonGet : Encoder a -> Host -> String -> a -> Http.Request String
jsonGet = jsonRequest "GET"
jsonPost : Encoder a -> Host -> String -> a -> Http.Request String
jsonPost = jsonRequest "POST"
jsonRequest : String -> Encoder a -> Host -> String -> a -> Http.Request String
jsonRequest verb ja host path a =
Http.request verb (host ++ "/" ++ path) (Encoder.render ja a) [("Content-Type", "application/json")]
decodeResponse : Decoder a -> Http.Response String -> Result (Status String) a
decodeResponse p r = case r of
Http.Success body -> case Decoder.decodeString p body of
Result.Err e -> Result.Err (Failed e)
Result.Ok a -> Result.Ok a
Http.Waiting -> Result.Err Waiting
Http.Failure code body -> Result.Err <| Failed ("error " ++ toString code ++ "\n" ++ body)

View File

@ -1,12 +1,11 @@
module Elmz.Layout where module Elmz.Layout where
import Array (Array) import Array exposing (Array)
import Color import Color
import Color (Color) import Color exposing (Color)
import Graphics.Element (Direction, Element, Position) import Graphics.Element exposing (Direction, Element, Position)
import Graphics.Element as E import Graphics.Element as E
import List import List
import List ((::))
import Maybe import Maybe
type alias Pt = { x : Int, y: Int } type alias Pt = { x : Int, y: Int }
@ -147,7 +146,7 @@ fill c e = container (tag e) (widthOf e) (heightOf e) (Pt 0 0) e
row : List (Layout k) -> List (Layout k) row : List (Layout k) -> List (Layout k)
row ls = case ls of row ls = case ls of
[] -> [] [] -> []
_ -> let maxh = List.maximum (List.map heightOf ls) _ -> let maxh = Maybe.withDefault 0 (List.maximum (List.map heightOf ls))
cell e = let diff = maxh - heightOf e cell e = let diff = maxh - heightOf e
in if diff == 0 then e in if diff == 0 then e
else container (tag e) (widthOf e) maxh (Pt 0 (toFloat diff / 2 |> floor)) e else container (tag e) (widthOf e) maxh (Pt 0 (toFloat diff / 2 |> floor)) e
@ -156,7 +155,7 @@ row ls = case ls of
column : List (Layout k) -> List (Layout k) column : List (Layout k) -> List (Layout k)
column ls = case ls of column ls = case ls of
[] -> [] [] -> []
_ -> let maxw = List.maximum (List.map widthOf ls) _ -> let maxw = Maybe.withDefault 0 (List.maximum (List.map widthOf ls))
cell e = let diff = maxw - widthOf e cell e = let diff = maxw - widthOf e
in if diff == 0 then e in if diff == 0 then e
else container (tag e) maxw (heightOf e) (Pt (toFloat diff / 2 |> floor) 0) e else container (tag e) maxw (heightOf e) (Pt (toFloat diff / 2 |> floor) 0) e
@ -165,7 +164,7 @@ column ls = case ls of
leftAlignedColumn : List (Layout k) -> List (Layout k) leftAlignedColumn : List (Layout k) -> List (Layout k)
leftAlignedColumn ls = case ls of leftAlignedColumn ls = case ls of
[] -> [] [] -> []
_ -> let maxw = List.maximum (List.map widthOf ls) _ -> let maxw = Maybe.withDefault 0 (List.maximum (List.map widthOf ls))
cell e = let diff = maxw - widthOf e cell e = let diff = maxw - widthOf e
in if diff == 0 then e in if diff == 0 then e
else container (tag e) maxw (heightOf e) (Pt 0 0) e else container (tag e) maxw (heightOf e) (Pt 0 0) e

View File

@ -2,7 +2,7 @@ module Elmz.Matcher where
import Debug import Debug
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import List import List
import String import String
@ -39,7 +39,7 @@ model matches =
out = List.filter (matches q.string) (q.values ++ r.values) out = List.filter (matches q.string) (q.values ++ r.values)
-- tricky part is determining whether we need to do another search -- tricky part is determining whether we need to do another search
full = r.additionalResults <= 0 full = r.additionalResults <= 0
lastExamined = List.maximum (-1 :: r.positionsExamined) lastExamined = Maybe.withDefault (-1) (List.maximum r.positionsExamined)
ok = ok =
-- we already have results for this query -- we already have results for this query
r.query == q.string || r.query == q.string ||

View File

@ -1,8 +1,7 @@
module Elmz.Moore where module Elmz.Moore where
import Signal import Signal
import Signal ((<~), (~), foldp, Signal) import Signal exposing ((<~), (~), foldp, Signal)
import List ((::))
import Maybe import Maybe
type Moore i o = Moore o (i -> Maybe (Moore i o)) type Moore i o = Moore o (i -> Maybe (Moore i o))
@ -104,46 +103,5 @@ transform m i =
let s i m = feed i m let s i m = feed i m
in extract <~ foldp s m i in extract <~ foldp s m i
{-| Unlike `transform`, only emits events when the input transitions to a new state. -}
transitions : Moore i o -> Signal i -> Signal o
transitions m i =
let s i (m,_) = case step i m of
Nothing -> (m, False)
Just m2 -> (m2, True)
states = foldp s (m, True) i
changes = Signal.map snd states
in Signal.keepWhen changes (extract m) ((extract << fst) <~ states)
unit : o -> Moore i o unit : o -> Moore i o
unit o = Moore o (always Nothing) unit o = Moore o (always Nothing)
{-
withInput : i -> Moore i o -> Moore i (i,o)
withInput i0 m = map2 (,) (echo i0) m
dropRepeats : o -> Moore o o
dropRepeats prev = Moore ((==) prev) prev dropRepeats
foldResult : (a -> r) -> (b -> r) -> Result a b -> r
foldResult f1 f2 e = case e of
Err a -> f1 a
Ok b -> f2 b
either : Moore a (Result x y) -> Moore x b -> Moore y b -> Moore a b
either (Moore samei xy ki) left right =
let same a = samei a && foldResult (steady left) (steady right) xy
st a = case xy of
Err x -> either (ki a) (step left x) right
Ok y -> either (ki a) left (step right y)
o = case xy of
Err x -> extract left
Ok y -> extract right
in Moore same o st
{-| Run the first argument until it emits `Err s`, then switch permanently to `f s`. -}
bind : Moore a (Result s b) -> (s -> Moore a b) -> Moore a b
bind (Moore same sb k) f = case sb of
Err s -> f s
Ok b -> Moore same b (\a -> bind (k a) f)
-}

View File

@ -1,7 +1,7 @@
module Elmz.Movement where module Elmz.Movement where
import Keyboard import Keyboard
import Signal ((<~), (~), Signal) import Signal exposing ((<~), (~), Signal)
import Signal import Signal
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Time import Time

138
editor/src/Elmz/Parser.elm Normal file
View File

@ -0,0 +1,138 @@
module Elmz.Parser where
import String
import Regex
type alias Msg = List String
type alias Status = { message : Msg, committed : Bool }
type alias Parser a = { string : String, offset : Int } -> Result Status (a, Int)
parse : Parser a -> String -> Result String a
parse p s = case p { string = s, offset = 0 } of
Err e -> Err (String.join "\n" e.message)
Ok (a,_) -> Ok a
unit : a -> Parser a
unit a _ = Ok (a, 0)
fail : Parser a
fail s = Err { message = [], committed = False }
map : (a -> b) -> Parser a -> Parser b
map f p s = case p s of
Ok (a, consumed) -> Ok (f a, consumed)
Err e -> Err e
(<$>) : (a -> b) -> Parser a -> Parser b
(<$>) = map
-- note: implementation not stack safe
many : Parser a -> Parser (List a)
many a s = case a s of
Err e -> if e.committed then Err e else Ok ([],0)
Ok (hd,consumed) -> case many a { s | offset <- s.offset + consumed } of
Err e -> Err e
Ok (tl,consumedTl) -> Ok (hd :: tl, consumed + consumedTl)
some : Parser a -> Parser (List a)
some a = (::) <$> a <*> many a
andThen : Parser a -> (a -> Parser b) -> Parser b
andThen p f s = case p s of
Err e -> Err e
Ok (a, consumed) ->
(if consumed > 0 then commit else identity) (f a) { s | offset <- s.offset + consumed }
commit : Parser a -> Parser a
commit p s = case p s of
Err e -> Err { e | committed <- True }
r -> r
attempt : Parser a -> Parser a
attempt p s = case p s of
Err e -> Err { e | committed <- False }
Ok a -> Ok a
scope : String -> Parser a -> Parser a
scope lbl p s = case p s of
Err e -> Err { e | message <- lbl :: e.message }
Ok a -> Ok a
label : String -> Parser a -> Parser a
label lbl p s = case p s of
Err e -> Err { e | message <- [lbl] }
Ok a -> Ok a
or : Parser a -> Parser a -> Parser a
or p p2 s = case p s of
Ok a -> Ok a
Err e -> if e.committed then Err e else p2 s
choice : List (Parser a) -> Parser a
choice = List.foldr or fail
ap : Parser (a -> b) -> Parser a -> Parser b
ap f a = f `andThen` \f -> map f a
satisfy : (Char -> Bool) -> Parser String
satisfy f s =
let sub = String.slice s.offset ((String.length s.string) `max` (s.offset + 1)) s.string
in if String.all f sub then Ok (sub, 1) else Err { message = [], committed = False }
symbol : Char -> Parser String
symbol c = satisfy ((==) c)
token : String -> Parser String
token t s =
if String.startsWith t (String.dropLeft s.offset s.string)
then Ok (t, String.length t)
else Err { message = ["expected " ++ t], committed = False }
reset : { string : String, offset : Int } -> { string : String, offset : Int }
reset s = { string = String.dropLeft s.offset s.string, offset = 0 }
digits : Parser String
digits = regex "\\d+"
nonnegativeInt : Parser Int
nonnegativeInt = digits `andThen` \s -> case String.toInt s of
Err e -> label e fail
Ok n -> unit n
int : Parser Int
int = optional (symbol '-') `andThen` \sign -> case sign of
Nothing -> nonnegativeInt
Just _ -> map negate nonnegativeInt
float : Parser Float
float = regex "[+-]?\\d+\\.\\d+" `andThen` \s -> case String.toFloat s of
Err e -> label e fail
Ok n -> unit n
optional : Parser a -> Parser (Maybe a)
optional p = map Just p `or` unit Nothing
regex : String -> Parser String
regex r s = let compiled = Regex.regex r in case reset s of
s -> case List.map .match (Regex.find (Regex.AtMost 1) compiled s.string) of
[] -> Err { message = [], committed = False }
hd :: _ -> Ok (hd, String.length hd)
infixl 4 <*>
infixl 4 <*
infixl 4 *>
infixl 4 <$
infixl 4 <$>
(<*>) : Parser (a -> b) -> Parser a -> Parser b
(<*>) = ap
(<*) : Parser a -> Parser b -> Parser a
a <* b = unit always <*> a <*> b
(<$) : a -> Parser b -> Parser a
a <$ p = map (always a) p
(*>) : Parser a -> Parser b -> Parser b
a *> b = unit (\_ b -> b) <*> a <*> b

View File

@ -1,13 +1,13 @@
{-| One-dimensional selection model. -} {-| One-dimensional selection model. -}
module Elmz.Selection1D where module Elmz.Selection1D where
import Elmz.Layout (Containment, Layout, Region) import Elmz.Layout exposing (Containment, Layout, Region)
import Elmz.Layout as Layout import Elmz.Layout as Layout
import Elmz.Movement as Movement import Elmz.Movement as Movement
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import Graphics.Element as Element import Graphics.Element as Element
import Maybe import Maybe
import Result import Result

View File

@ -5,37 +5,20 @@ import Debug
import Elmz.Maybe import Elmz.Maybe
import Keyboard import Keyboard
import List import List
import List ((::))
import Maybe import Maybe
import Execute
import Mouse import Mouse
import Result import Result
import Set import Set exposing (Set)
import Signal (..) import Signal exposing (..)
import Text import Text
import Time import Time
import Time (Time) import Time exposing (Time)
{-| Accumulates into a list using `foldp` during regions where `cond` {-| Accumulates into a list using `foldp` during regions where `cond`
is `True`, otherwise emits the empty list. -} is `True`, otherwise emits the empty list. -}
accumulateWhen : Signal Bool -> Signal a -> Signal (List a) accumulateWhen : Signal Bool -> Signal a -> Signal (List a)
accumulateWhen cond a = foldpWhen cond (::) [] a |> map List.reverse accumulateWhen cond a = foldpWhen cond (::) [] a |> map List.reverse
asyncUpdate : (Signal req -> Signal (model -> (Maybe req, model)))
-> Signal (model -> (Maybe req, model))
-> req
-> model
-> Signal model
asyncUpdate responseActions actions req0 model0 =
let reqs = channel req0
mergedActions = merge actions (responseActions (subscribe reqs))
step action (_,model) =
let (req, model') = action model
in (Maybe.map (send reqs) req, model')
modelsWithMsgs = foldp step (Nothing,model0) mergedActions
msgs = Execute.schedule (map (Maybe.withDefault Execute.noop) (justs (map fst modelsWithMsgs)))
in during (map snd modelsWithMsgs) msgs
{-| Alternate sending `input` through `left` or `right` signal transforms, {-| Alternate sending `input` through `left` or `right` signal transforms,
merging their results. -} merging their results. -}
alternate : (Signal (Maybe a) -> Signal c) alternate : (Signal (Maybe a) -> Signal c)
@ -63,7 +46,7 @@ delay h s =
{-| Only emit when the input signal transitions from `True` to `False`. -} {-| Only emit when the input signal transitions from `True` to `False`. -}
downs : Signal Bool -> Signal Bool downs : Signal Bool -> Signal Bool
downs s = dropIf identity True s downs s = filter not True s
{-| Emits an event whenever there are two events that occur within `within` time of each other. -} {-| Emits an event whenever there are two events that occur within `within` time of each other. -}
doubleWithin : Time -> Signal s -> Signal () doubleWithin : Time -> Signal s -> Signal ()
@ -73,7 +56,7 @@ doubleWithin within s =
Nothing -> False Nothing -> False
Just t1 -> if t2 - t1 < within then True else False Just t1 -> if t2 - t1 < within then True else False
in map2 f (delay Nothing (map Just ts)) ts in map2 f (delay Nothing (map Just ts)) ts
|> keepIf identity False |> filter identity False
|> map (always ()) |> map (always ())
{-| Evaluate the second signal for its effects, but return the first signal. -} {-| Evaluate the second signal for its effects, but return the first signal. -}
@ -141,7 +124,7 @@ flattenMaybe s = fromMaybe (constant Nothing) s
{-| Ignore any events of `Nothing`. -} {-| Ignore any events of `Nothing`. -}
justs : Signal (Maybe a) -> Signal (Maybe a) justs : Signal (Maybe a) -> Signal (Maybe a)
justs s = keepIf (Maybe.map (always True) >> Maybe.withDefault False) Nothing s justs s = filter (Maybe.map (always True) >> Maybe.withDefault False) Nothing s
{-| Event which fires with the given `a` whenever the keycode is pressed down. -} {-| Event which fires with the given `a` whenever the keycode is pressed down. -}
keyEvent : a -> Int -> Signal a keyEvent : a -> Int -> Signal a
@ -151,20 +134,12 @@ keyEvent k code = map (always k) (ups (Keyboard.isDown code))
keyChordEvent : a -> List Keyboard.KeyCode -> Signal a keyChordEvent : a -> List Keyboard.KeyCode -> Signal a
keyChordEvent k codes = keyChordEvent k codes =
let let
hazTehCodez : List Keyboard.KeyCode -> Bool hazTehCodez : Set Keyboard.KeyCode -> Bool
hazTehCodez pressed = hazTehCodez pressed =
let pressed' = Set.fromList pressed List.all (\k -> Set.member k pressed) codes
in List.all (\k -> Set.member k pressed') codes
in in
map (always k) (ups (map hazTehCodez Keyboard.keysDown)) map (always k) (ups (map hazTehCodez Keyboard.keysDown))
loop : (Signal a -> Signal s -> Signal (b,s)) -> s -> Signal a -> Signal b
loop f s a =
let chan = channel s
bs = f a (sampleOn a (subscribe chan)) -- Signal (b,s)
in map2 always (map fst bs)
(Execute.complete (map (\(_,s) -> send chan s) bs))
map2r : (a -> b -> c) -> Signal a -> Signal b -> Signal c map2r : (a -> b -> c) -> Signal a -> Signal b -> Signal c
map2r f a b = sampleOn b (map2 f a b) map2r f a b = sampleOn b (map2 f a b)
@ -172,39 +147,6 @@ map2r f a b = sampleOn b (map2 f a b)
mask : Signal Bool -> Signal a -> Signal (Maybe a) mask : Signal Bool -> Signal a -> Signal (Maybe a)
mask = map2 (\b a -> if b then Just a else Nothing) mask = map2 (\b a -> if b then Just a else Nothing)
{-| Merge two signals, using the combining function if any events co-occcur. -}
mergeWith : (a -> a -> a) -> Signal a -> Signal a -> Signal a
mergeWith resolve left right =
let boolLeft = always True <~ left
boolRight = always False <~ right
bothUpdated = (/=) <~ merge boolLeft boolRight ~ merge boolRight boolLeft
exclusive = dropWhen bothUpdated Nothing (Just <~ merge left right)
overlap = keepWhen bothUpdated Nothing (Just <~ map2 resolve left right)
combine m1 m2 = case Maybe.oneOf [m1, m2] of
Just a -> a
Nothing -> List.head [] -- impossible
in combine <~ exclusive ~ overlap
{-| Merge two signals, composing the functions if any events co-occcur. -}
mergeWithBoth : Signal (a -> a) -> Signal (a -> a) -> Signal (a -> a)
mergeWithBoth = mergeWith (>>)
{-| Merge the two signals. If events co-occur, emits `(Just a, Just b)`,
otherwise emits `(Just a, Nothing)` or `(Nothing, Just b)`. -}
oneOrBoth : Signal a -> Signal b -> Signal (Maybe a, Maybe b)
oneOrBoth a b =
let combine a b = case a of
(Nothing,_) -> b
(Just a,_) -> case b of
(_, Nothing) -> (Just a, Nothing)
(_, Just b) -> (Just a, Just b)
in mergeWith combine (map (\a -> (Just a, Nothing)) a)
(map (\b -> (Nothing, Just b)) b)
{-| A signal which emits a single event after a specified time. -}
pulse : Time -> Signal ()
pulse time = Time.delay time start
{-| Replace the first occurence of the input signal with `a`. -} {-| Replace the first occurence of the input signal with `a`. -}
replaceFirst : a -> Signal a -> Signal a replaceFirst : a -> Signal a -> Signal a
replaceFirst a0 s = replaceFirst a0 s =
@ -212,37 +154,21 @@ replaceFirst a0 s =
f replace a = if replace then Debug.log ("replacing " ++ toString a) a0 else a f replace a = if replace then Debug.log ("replacing " ++ toString a) a0 else a
in map2 f first s in map2 f first s
{-| Emit updates to `s` only when it moves outside the current bin,
according to the function `within`. Otherwise emit no update but
take on the value `Nothing`. -}
quantize : (a -> r -> Bool) -> Signal r -> Signal a -> Signal (Maybe a)
quantize within bin s =
let f range a = if a `within` range then Nothing else Just a
in dropIf (Maybe.map (always False) >> Maybe.withDefault True) Nothing (f <~ bin ~ s)
{-| Repeat updates to a signal after it has remained steady for `t` {-| Repeat updates to a signal after it has remained steady for `t`
elapsed time, and only if the current value tests true against `f`. -} elapsed time, and only if the current value tests true against `f`. -}
repeatAfterIf : Time -> number -> (a -> Bool) -> Signal a -> Signal a repeatAfterIf : Time -> number -> (a -> Bool) -> Signal a -> Signal a
repeatAfterIf time fps f s = repeatAfterIf time fps f s =
let repeatable = map f s let repeatable = map f s
delayedRep = repeatable |> keepIf identity False |> Time.since time |> map not delayedRep = repeatable |> filter identity False |> Time.since time |> map not
resetDelay = merge (always False <~ s) delayedRep resetDelay = merge (always False <~ s) delayedRep
repeats = Time.fpsWhen fps ((&&) <~ repeatable ~ dropRepeats resetDelay) repeats = Time.fpsWhen fps ((&&) <~ repeatable ~ dropRepeats resetDelay)
in sampleOn repeats s in sampleOn repeats s
{-| A signal which emits a single event on or immediately after program start. -}
start : Signal ()
start =
let chan = channel ()
msg = send chan ()
in sampleOn (subscribe chan)
(map2 always (constant ()) (Execute.schedule (constant msg)))
{-| Only emit updates of `s` when it settles into a steady state with {-| Only emit updates of `s` when it settles into a steady state with
no updates within the period `t`. Useful to avoid propagating updates no updates within the period `t`. Useful to avoid propagating updates
when a value is changing too rapidly. -} when a value is changing too rapidly. -}
steady : Time -> Signal a -> Signal a steady : Time -> Signal a -> Signal a
steady t s = sampleOn (Time.since t s |> dropIf identity False) s steady t s = sampleOn (Time.since t s |> filter not False) s
{-| Like `sampleOn`, but the output signal refreshes whenever either signal updates. -} {-| Like `sampleOn`, but the output signal refreshes whenever either signal updates. -}
sampleOnMerge : Signal a -> Signal b -> Signal b sampleOnMerge : Signal a -> Signal b -> Signal b
@ -279,7 +205,7 @@ unchanged a = map not (changed a)
{-| Only emit when the input signal transitions from `False` to `True`. -} {-| Only emit when the input signal transitions from `False` to `True`. -}
ups : Signal Bool -> Signal Bool ups : Signal Bool -> Signal Bool
ups s = keepIf identity False s ups s = filter identity False s
zip : Signal a -> Signal b -> Signal (a,b) zip : Signal a -> Signal b -> Signal (a,b)
zip = map2 (,) zip = map2 (,)

View File

@ -1,38 +0,0 @@
module Execute where
{-| Execute scheduling and delivery of `Signal.Message` values. -}
import Native.Execute
import Signal (Signal, Message)
{-| The message which does nothing. -}
noop : Message
noop = Native.Execute.noop
{-| Combine two messages into one. The first argument will
be delivered before the second. -}
combine : Message -> Message -> Message
combine = Native.Execute.combine
{-| Schedule the input `Message` values for delivery.
The output signal has same event occurrences as the input signal,
and there is no guarantee that effects of message delivery will
be visible when the output `Signal ()` updates.
Implementation uses `setTimeout(.., 0)` in Javascript to schedule
delivery of the `Message`.
-}
schedule : Signal Message -> Signal ()
schedule = Native.Execute.schedule
{-| Schedule the input `Message` values for delivery and wait for
completion of each delivery. Unlike `schedule`, the output `Signal`
will refresh once per `Message` _after_ all effects of message
delivery have propagated through the signal graph. There will be
exactly one refresh of the output signal for each input `Message`,
but the implementation uses `setTimeout(.., 0)` in Javascript so
there aren't any guarantees about exact ordering of updates,
especially with regard to other events in the signal graph.
-}
complete : Signal Message -> Signal ()
complete = Native.Execute.complete

View File

@ -1,59 +0,0 @@
Elm.Native.Execute = {};
Elm.Native.Execute.make = function(localRuntime) {
localRuntime.Native = localRuntime.Native || {};
localRuntime.Native.Execute = localRuntime.Native.Execute || {};
if (localRuntime.Native.Execute.values) {
return localRuntime.Native.Execute.values;
}
var Signal = Elm.Signal.make(localRuntime);
function combine(thunk1, thunk2) {
return function() {
setTimeout(
function() {
thunk1();
setTimeout(thunk2, 0);
},
0);
}
}
// schedule : Signal Message -> Signal ()
function schedule(msgs) {
var tuple0 = { ctor: "_Tuple0" };
function scheduleForce(thunk) {
setTimeout(thunk, 0);
return tuple0;
}
return A2( Signal.map, scheduleForce, msgs );
}
// complete : Signal Message -> Signal ()
function complete(msgs) {
var tuple0 = { ctor: "_Tuple0" };
var output = Signal.constant(tuple0);
// need to nest the calls to `setTimeout` to ensure the output signal
// is refreshed *after* the message has been delivered
function scheduleForce(thunk) {
setTimeout(
function() {
thunk();
setTimeout(function() { localRuntime.notify(output.id, tuple0); }, 0)
}, 0);
return tuple0;
}
var forced = A2( Signal.map, scheduleForce, msgs );
function k(x) { return function(y) { return x; } }
// the sampleOn output is important, since the `map2` would otherwise
// emit an event when either a message comes in OR a message is delivered
return A2(Signal.sampleOn, output, A3( Signal.map2, k, output, forced));
}
return localRuntime.Native.Execute.values = {
schedule: schedule,
complete: complete,
combine: combine,
noop: function() {}
};
};

View File

@ -1,10 +1,10 @@
module Unison.Action where module Unison.Action where
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import Unison.Symbol (Symbol) import Unison.Symbol exposing (Symbol)
import Unison.Symbol as Symbol import Unison.Symbol as Symbol
type Action type Action

View File

@ -2,25 +2,25 @@ module Unison.EditableTerm where
import Debug import Debug
import Elmz.Layout as Layout import Elmz.Layout as Layout
import Elmz.Layout (Layout,Region) import Elmz.Layout exposing (Layout,Region)
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Movement as Movement import Elmz.Movement as Movement
import Elmz.Trie as Trie import Elmz.Trie as Trie
import Elmz.Trie (Trie) import Elmz.Trie exposing (Trie)
import Graphics.Element as Element import Graphics.Element as Element
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import List import List
import Maybe import Maybe
import Unison.Path as Path import Unison.Path as Path
import Unison.Path (Path) import Unison.Path exposing (Path)
import Unison.Reference (Reference) import Unison.Reference exposing (Reference)
import Unison.Metadata (Metadata) import Unison.Metadata exposing (Metadata)
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Scope as Scope import Unison.Scope as Scope
import Unison.Styles as Styles import Unison.Styles as Styles
import Unison.Term as Term import Unison.Term as Term
import Unison.Term (Term) import Unison.Term exposing (Term)
import Unison.View as View import Unison.View as View
import Unison.Node as Node import Unison.Node as Node

View File

@ -1,16 +1,15 @@
module Unison.Editor where module Unison.Editor where
import Debug import Debug
import Execute
import Elmz.Json.Request as JR import Elmz.Json.Request as JR
import Elmz.Layout (Containment(Inside,Outside), Layout, Pt, Region) import Elmz.Layout exposing (Containment(Inside,Outside), Layout, Pt, Region)
import Elmz.Layout as Layout import Elmz.Layout as Layout
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Movement as Movement import Elmz.Movement as Movement
import Elmz.Selection1D as Selection1D import Elmz.Selection1D as Selection1D
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import Graphics.Element as Element import Graphics.Element as Element
import Graphics.Input.Field as Field import Graphics.Input.Field as Field
import Maybe import Maybe
@ -21,21 +20,21 @@ import Signal
import Unison.Action as Action import Unison.Action as Action
import Unison.EditableTerm as EditableTerm import Unison.EditableTerm as EditableTerm
import Unison.SearchboxParser as SearchboxParser import Unison.SearchboxParser as SearchboxParser
import Unison.Hash (Hash) import Unison.Hash exposing (Hash)
import Unison.Metadata (Metadata) import Unison.Metadata exposing (Metadata)
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Node as Node import Unison.Node as Node
import Unison.Path (Path) import Unison.Path exposing (Path)
import Unison.Path as Path import Unison.Path as Path
import Unison.Reference (Reference) import Unison.Reference exposing (Reference)
import Unison.Reference as Reference import Unison.Reference as Reference
import Unison.Scope as Scope import Unison.Scope as Scope
import Unison.Styles as Styles import Unison.Styles as Styles
import Unison.Term (Term) import Unison.Term exposing (Term)
import Unison.Term as Term import Unison.Term as Term
import Unison.TermExplorer as TermExplorer import Unison.TermExplorer as TermExplorer
import Unison.Terms as Terms import Unison.Terms as Terms
import Unison.Type (Type) import Unison.Type exposing (Type)
import Unison.Type as Type import Unison.Type as Type
import Unison.View as View import Unison.View as View
import Window import Window
@ -205,7 +204,7 @@ model sink term0 =
ignoreUpDown : Signal Field.Content -> Signal Field.Content ignoreUpDown : Signal Field.Content -> Signal Field.Content
ignoreUpDown s = ignoreUpDown s =
let k = Signal.sampleOn (Signal.keepIf (\a -> a.y /= 0) {x = 0, y = 0} Keyboard.arrows) let k = Signal.sampleOn (Signal.filter (\a -> a.y /= 0) {x = 0, y = 0} Keyboard.arrows)
(Signals.delay Field.noContent s) (Signals.delay Field.noContent s)
in Signal.merge k s in Signal.merge k s

View File

@ -1,9 +1,9 @@
module Unison.Hash where module Unison.Hash where
import Json.Decode as Decode import Json.Decode as Decode
import Json.Decode (Decoder) import Json.Decode exposing (Decoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
type alias Hash = String type alias Hash = String

View File

@ -2,19 +2,19 @@ module Unison.Metadata where
import Array import Array
import Dict import Dict
import Elmz.Json.Decoder (Decoder, (#)) import Elmz.Json.Decoder exposing (Decoder, (#))
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import List import List
import Maybe import Maybe
import Unison.Hash as H import Unison.Hash as H
import Unison.Path (Path) import Unison.Path exposing (Path)
import Unison.Path as Path import Unison.Path as Path
import Unison.Reference as R import Unison.Reference as R
import Unison.Symbol (Symbol) import Unison.Symbol exposing (Symbol)
import Unison.Symbol as Symbol import Unison.Symbol as Symbol
type alias E = Path.E type alias E = Path.E
type alias Path = Path.Path -- to avoid conflict with Graphics.Collage.Path type alias Path = Path.Path -- to avoid conflict with Graphics.Collage.Path
@ -49,9 +49,7 @@ firstSymbol defaultName md = case md.names of
firstName : String -> Metadata -> String firstName : String -> Metadata -> String
firstName ifEmpty md = firstName ifEmpty md =
if List.isEmpty md.names Maybe.withDefault ifEmpty (Maybe.map .name (List.head md.names))
then ifEmpty
else (List.head md.names).name
type alias Names = List Symbol type alias Names = List Symbol

View File

@ -4,25 +4,25 @@ module Unison.Node where
import Dict as M import Dict as M
import Maybe import Maybe
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import Elmz.Json.Request (Request) import Elmz.Json.Request exposing (Request)
import Elmz.Json.Request as Request import Elmz.Json.Request as Request
import Set as S import Set as S
import Signal import Signal
import Signal ((<~),(~),Signal) import Signal exposing ((<~),(~),Signal)
import Unison.Action as A import Unison.Action as A
import Unison.Action (Action) import Unison.Action exposing (Action)
import Unison.Metadata as MD import Unison.Metadata as MD
import Unison.Metadata (Metadata, Query) import Unison.Metadata exposing (Metadata, Query)
import Unison.Term as E import Unison.Term as E
import Unison.Path as Path import Unison.Path as Path
import Unison.Reference as Reference import Unison.Reference as Reference
import Unison.Reference (Reference) import Unison.Reference exposing (Reference)
import Unison.Term (Term) import Unison.Term exposing (Term)
import Unison.Type as T import Unison.Type as T
import Unison.Type (Type) import Unison.Type exposing (Type)
type alias Path = Path.Path type alias Path = Path.Path
type alias Host = String type alias Host = String

View File

@ -1,14 +1,13 @@
module Unison.Path where module Unison.Path where
import Array (Array) import Array exposing (Array)
import Array as A import Array as A
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Json.Decode (Decoder) import Json.Decode exposing (Decoder)
import Json.Decode as Decode import Json.Decode as Decode
import List import List
import List ((::))
import String import String
type E type E

View File

@ -1,14 +1,14 @@
module Unison.Reference where module Unison.Reference where
import Dict (Dict) import Dict exposing (Dict)
import Dict import Dict
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import List import List
import String import String
import Unison.Hash (Hash) import Unison.Hash exposing (Hash)
import Unison.Hash as H import Unison.Hash as H
type Reference type Reference

View File

@ -1,19 +1,18 @@
module Unison.Scope where module Unison.Scope where
import Debug import Debug
import Elmz.Layout (Region, Layout) import Elmz.Layout exposing (Region, Layout)
import Elmz.Layout as Layout import Elmz.Layout as Layout
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Elmz.Movement as Movement import Elmz.Movement as Movement
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import Graphics.Element as Element import Graphics.Element as Element
import List import List
import List ((::))
import Maybe import Maybe
import Signal import Signal
import Unison.Path as Path import Unison.Path as Path
import Unison.Styles as Styles import Unison.Styles as Styles
import Unison.Term (Term) import Unison.Term exposing (Term)
import Unison.Term as Term import Unison.Term as Term
import Unison.View as View import Unison.View as View

View File

@ -2,20 +2,18 @@ module Unison.SearchboxParser where
import Debug import Debug
import Elmz.Distance as Distance import Elmz.Distance as Distance
import Elmz.Distance (Distance) import Elmz.Distance exposing (Distance)
import List import List
import Parser import Elmz.Parser as Parser
import Parser (Parser, (<*), (*>), (<*>), (<$>), (<$)) import Elmz.Parser exposing (Parser, (<*), (*>), (<*>), (<$>), (<$))
import Parser.Number
import Parser.Char
import Unison.Term as Term import Unison.Term as Term
import Unison.Term (Term) import Unison.Term exposing (Term)
import String import String
import Set import Set
parser : { literal : Term -> a parser : { literal : Term -> a
, query : String -> a , query : String -> a
, combine : a -> Char -> a } , combine : a -> String -> a }
-> Parser a -> Parser a
parser env = parser env =
let lit = Parser.map env.literal literal let lit = Parser.map env.literal literal
@ -32,14 +30,14 @@ space = Parser.satisfy ((==) ' ')
parse : parse :
{ literal : Term -> a { literal : Term -> a
, query : String -> a , query : String -> a
, combine : a -> Char -> a } , combine : a -> String -> a }
-> String -> Result String a -> String -> Result String a
parse env = Parser.parse (parser env) parse env = Parser.parse (parser env)
parseTerm : String -> Result String Term parseTerm : String -> Result String Term
parseTerm = Parser.parse literal parseTerm = Parser.parse literal
operator : Parser Char operator : Parser String
operator = operator =
let ops = Set.fromList (String.toList "!@#$%^&*-+|\\;.></`~") let ops = Set.fromList (String.toList "!@#$%^&*-+|\\;.></`~")
in Parser.satisfy (\c -> Set.member c ops) in Parser.satisfy (\c -> Set.member c ops)
@ -55,13 +53,13 @@ blank : Parser Term
blank = Parser.map (always Term.Blank) (Parser.symbol '_') blank = Parser.map (always Term.Blank) (Parser.symbol '_')
int : Parser Term int : Parser Term
int = Parser.map (Term.Lit << Term.Number << toFloat) Parser.Number.integer int = Parser.map (Term.Lit << Term.Number << toFloat) (Parser.attempt Parser.int)
float : Parser Term float : Parser Term
float = Parser.map (Term.Lit << Term.Number) Parser.Number.float float = Parser.map (Term.Lit << Term.Number) (Parser.attempt Parser.float)
string : Parser Term string : Parser Term
string = Parser.Char.between quote quote (until quote) string = (Parser.symbol quote *> (until quote) <* Parser.symbol quote)
|> Parser.map (Term.Lit << Term.Text) |> Parser.map (Term.Lit << Term.Text)
openString : Parser Term openString : Parser Term
@ -77,22 +75,20 @@ distance =
pixels : Parser Distance pixels : Parser Distance
pixels = pixels =
let f n = Distance.Scale (toFloat n) Distance.Pixel let f n = Distance.Scale (toFloat n) Distance.Pixel
in f <$> Parser.Number.natural <* Parser.token "px" in f <$> Parser.nonnegativeInt <* Parser.token "px"
fraction : Parser Distance fraction : Parser Distance
fraction = Parser.symbol '1' fraction = Parser.symbol '1'
*> Parser.symbol '/' *> Parser.symbol '/'
*> (Parser.Number.natural <* Parser.symbol 'd') *> (Parser.nonnegativeInt <* Parser.symbol 'd')
|> Parser.map (\denominator -> Distance.Fraction (1.0 / toFloat denominator)) |> Parser.map (\denominator -> Distance.Fraction (1.0 / toFloat denominator))
quote = '"' -- " quote = '"' -- "
until : Char -> Parser String until : Char -> Parser String
until c = until c =
Parser.map (String.concat << List.map String.fromChar) Parser.map String.concat (Parser.many (Parser.satisfy ((/=) c)))
(Parser.many (Parser.satisfy ((/=) c)))
until1 : Char -> Parser String until1 : Char -> Parser String
until1 c = until1 c =
Parser.map (String.concat << List.map String.fromChar) Parser.map String.concat (Parser.some (Parser.satisfy ((/=) c)))
(Parser.some (Parser.satisfy ((/=) c)))

View File

@ -1,20 +1,17 @@
module Unison.Styles where module Unison.Styles where
import Color import Color
import Color (Color) import Color exposing (Color)
import Easing (Easing)
import Easing
import Elmz.Signal as Signals import Elmz.Signal as Signals
import Elmz.Layout (Layout, Region) import Elmz.Layout exposing (Layout, Region)
import Elmz.Layout as L import Elmz.Layout as L
import Graphics.Input.Field as Field import Graphics.Input.Field as Field
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import Graphics.Element as E import Graphics.Element as E
import Graphics.Collage as C import Graphics.Collage as C
import List import List
import List ((::))
import Signal import Signal
import Text (Style) import Text exposing (Style)
import Text as T import Text as T
import Time import Time
@ -62,16 +59,16 @@ menuHeader =
, line = Nothing } , line = Nothing }
codeText : String -> Element codeText : String -> Element
codeText s = T.leftAligned (T.style code (T.fromString s)) codeText s = E.leftAligned (T.style code (T.fromString s))
boldCodeText : String -> Element boldCodeText : String -> Element
boldCodeText s = T.leftAligned (T.style { code | bold <- True } (T.fromString s)) boldCodeText s = E.leftAligned (T.style { code | bold <- True } (T.fromString s))
centeredCodeText : String -> Element centeredCodeText : String -> Element
centeredCodeText s = T.centered (T.style code (T.fromString s)) centeredCodeText s = E.centered (T.style code (T.fromString s))
menuHeaderText : String -> Element menuHeaderText : String -> Element
menuHeaderText s = T.leftAligned (T.style menuHeader (T.fromString s)) menuHeaderText s = E.leftAligned (T.style menuHeader (T.fromString s))
menuSeparator : Int -> Element menuSeparator : Int -> Element
menuSeparator width = menuSeparator width =
@ -111,10 +108,10 @@ currentSymbol : Element
currentSymbol = outline' okColor 6 16 16 currentSymbol = outline' okColor 6 16 16
numericLiteral : String -> Element numericLiteral : String -> Element
numericLiteral s = T.leftAligned (T.style { code | color <- belizeHole } (T.fromString s)) numericLiteral s = E.leftAligned (T.style { code | color <- belizeHole } (T.fromString s))
stringLiteral : String -> Element stringLiteral : String -> Element
stringLiteral s = T.leftAligned (T.style { code | color <- wisteria } (T.fromString s)) stringLiteral s = E.leftAligned (T.style { code | color <- wisteria } (T.fromString s))
cells : k -> Element -> List (Layout k) -> Layout k cells : k -> Element -> List (Layout k) -> Layout k
cells k ifEmpty ls = let cs = List.map (\l -> L.fill bg (L.pad 5 0 l)) (L.row ls) in case cs of cells k ifEmpty ls = let cs = List.map (\l -> L.fill bg (L.pad 5 0 l)) (L.row ls) in case cs of
@ -205,17 +202,6 @@ contain : Element -> Element
contain e = contain e =
E.container (E.widthOf e) (E.heightOf e) E.middle e E.container (E.widthOf e) (E.heightOf e) E.middle e
spinner : Signal Element
spinner =
let pct n = toFloat (n%60) / 60.0
t = Signal.map pct (Signals.count (Time.fps 60))
rect = E.color midnightBlue (E.spacer 5 10)
sep = E.spacer 1 1
render pct = E.flow E.right
[ rect, sep
, E.opacity (Easing.easeInOutExpo pct) rect ]
in Signal.map render t
blank : Element blank : Element
blank = codeText "_" blank = codeText "_"
@ -243,7 +229,3 @@ midnightBlue = Color.rgb 44 62 80
midnightBlueA alpha = Color.rgba 44 62 80 alpha midnightBlueA alpha = Color.rgba 44 62 80 alpha
concrete = Color.rgb 149 165 166 concrete = Color.rgb 149 165 166
asbestos = Color.rgb 127 140 141 asbestos = Color.rgb 127 140 141
main =
let scene e = E.flow E.down [ E.spacer 1 50, E.flow E.right [ E.spacer 50 1, e]]
in Signal.map scene spinner

View File

@ -1,9 +1,9 @@
module Unison.Symbol where module Unison.Symbol where
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
type Fixity = InfixL | InfixR | Infix | Prefix type Fixity = InfixL | InfixR | Infix | Prefix

View File

@ -1,33 +1,32 @@
module Unison.Term where module Unison.Term where
import Array import Array
import Array (Array) import Array exposing (Array)
import Debug import Debug
import Dict import Dict
import Dict (Dict) import Dict exposing (Dict)
import Elmz.Distance as Distance import Elmz.Distance as Distance
import Elmz.Maybe as EM import Elmz.Maybe as EM
import Elmz.Layout (Layout) import Elmz.Layout exposing (Layout)
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Trie (Trie) import Elmz.Trie exposing (Trie)
import Elmz.Trie as Trie import Elmz.Trie as Trie
import List import List
import List ((::))
import Maybe import Maybe
import Set import Set
import Set (Set) import Set exposing (Set)
import String import String
import Unison.Reference as R import Unison.Reference as R
import Unison.Hash (Hash) import Unison.Hash exposing (Hash)
import Unison.Hash as H import Unison.Hash as H
import Unison.Metadata (Metadata) import Unison.Metadata exposing (Metadata)
import Unison.Symbol (Symbol,Fixity) import Unison.Symbol exposing (Symbol,Fixity)
import Unison.Symbol as Symbol import Unison.Symbol as Symbol
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Path (..) import Unison.Path exposing (..)
import Unison.Path as Path import Unison.Path as Path
import Unison.Type as T import Unison.Type as T
type alias E = Path.E type alias E = Path.E

View File

@ -1,17 +1,17 @@
module Unison.TermExplorer where module Unison.TermExplorer where
import Debug import Debug
import Dict (Dict) import Dict exposing (Dict)
import Dict as Dict import Dict as Dict
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Layout as Layout import Elmz.Layout as Layout
import Elmz.Layout (Layout) import Elmz.Layout exposing (Layout)
import Elmz.Movement as Movement import Elmz.Movement as Movement
import Elmz.Selection1D as Selection1D import Elmz.Selection1D as Selection1D
import Elmz.Matcher as Matcher import Elmz.Matcher as Matcher
import Graphics.Element as Element import Graphics.Element as Element
import Graphics.Element (Element) import Graphics.Element exposing (Element)
import Graphics.Input.Field as Field import Graphics.Input.Field as Field
import List import List
import Maybe import Maybe
@ -19,18 +19,18 @@ import Result
import Signal import Signal
import String import String
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Metadata (Metadata,Query) import Unison.Metadata exposing (Metadata,Query)
import Unison.Node as Node import Unison.Node as Node
import Unison.Path as Path import Unison.Path as Path
import Unison.Path (Path) import Unison.Path exposing (Path)
import Unison.Reference as Reference import Unison.Reference as Reference
import Unison.Reference (Reference) import Unison.Reference exposing (Reference)
import Unison.SearchboxParser as SearchboxParser import Unison.SearchboxParser as SearchboxParser
import Unison.Styles as Styles import Unison.Styles as Styles
import Unison.Term as Term import Unison.Term as Term
import Unison.Term (Term) import Unison.Term exposing (Term)
import Unison.Type as Type import Unison.Type as Type
import Unison.Type (Type) import Unison.Type exposing (Type)
import Unison.View as View import Unison.View as View
type alias LocalFocus = type alias LocalFocus =

View File

@ -1,16 +1,16 @@
module Unison.Type where module Unison.Type where
import Elmz.Json.Decoder (Decoder) import Elmz.Json.Decoder exposing (Decoder)
import Elmz.Json.Decoder as Decoder import Elmz.Json.Decoder as Decoder
import Elmz.Json.Encoder (Encoder) import Elmz.Json.Encoder exposing (Encoder)
import Elmz.Json.Encoder as Encoder import Elmz.Json.Encoder as Encoder
import List import List
import String import String
import Unison.Metadata (Metadata) import Unison.Metadata exposing (Metadata)
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Reference (Reference) import Unison.Reference exposing (Reference)
import Unison.Reference as Reference import Unison.Reference as Reference
import Unison.Symbol (Symbol) import Unison.Symbol exposing (Symbol)
import Unison.Symbol as Symbol import Unison.Symbol as Symbol
type Literal type Literal

View File

@ -4,28 +4,27 @@ import Array
import Color import Color
import Debug import Debug
import Elmz.Distance as Distance import Elmz.Distance as Distance
import Elmz.Layout (Layout) import Elmz.Layout exposing (Layout)
import Elmz.Layout as L import Elmz.Layout as L
import Elmz.Moore (Moore(..)) import Elmz.Moore exposing (Moore(..))
import Elmz.Moore as Moore import Elmz.Moore as Moore
import Elmz.Trie as Trie import Elmz.Trie as Trie
import Elmz.Trie (Trie) import Elmz.Trie exposing (Trie)
import List import List
import List ((::))
import Graphics.Element as E import Graphics.Element as E
import Maybe import Maybe
import Unison.Reference as R import Unison.Reference as R
import Unison.Hash (Hash) import Unison.Hash exposing (Hash)
import Unison.Metadata (Metadata) import Unison.Metadata exposing (Metadata)
import Unison.Symbol (Fixity) import Unison.Symbol exposing (Fixity)
import Unison.Symbol as Symbol import Unison.Symbol as Symbol
import Unison.Metadata as Metadata import Unison.Metadata as Metadata
import Unison.Styles (codeText) import Unison.Styles exposing (codeText)
import Unison.Styles as Styles import Unison.Styles as Styles
import Unison.Term (..) import Unison.Term exposing (..)
import Unison.Term as Term import Unison.Term as Term
import Unison.Type as Type import Unison.Type as Type
import Unison.Path (..) import Unison.Path exposing (..)
import Unison.Path as Path import Unison.Path as Path
import String import String
import Text import Text
@ -322,16 +321,16 @@ builtins env allowBreak availableWidth ambientPrec cur =
in Just (L.embed t (E.spacer w' h')) in Just (L.embed t (E.spacer w' h'))
App (Ref (R.Builtin "View.text")) style -> case e of App (Ref (R.Builtin "View.text")) style -> case e of
-- todo, actually interpret style -- todo, actually interpret style
Lit (Text s) -> Just (L.embed t (Text.leftAligned (Text.style Text.defaultStyle (Text.fromString s)))) Lit (Text s) -> Just (L.embed t (E.leftAligned (Text.style Text.defaultStyle (Text.fromString s))))
App (App (App (Ref (R.Builtin "View.textbox")) (Ref (R.Builtin alignment))) (Lit (Term.Distance d))) style -> App (App (App (Ref (R.Builtin "View.textbox")) (Ref (R.Builtin alignment))) (Lit (Term.Distance d))) style ->
case e of case e of
Lit (Text s) -> Lit (Text s) ->
-- todo, actually interpret style -- todo, actually interpret style
let f = case alignment of let f = case alignment of
"Text.left" -> Text.leftAligned "Text.left" -> E.leftAligned
"Text.right" -> Text.rightAligned "Text.right" -> E.rightAligned
"Text.center" -> Text.centered "Text.center" -> E.centered
"Text.justify" -> Text.justified "Text.justify" -> E.justified
e = f (Text.style Text.defaultStyle (Text.fromString s)) e = f (Text.style Text.defaultStyle (Text.fromString s))
rem = availableWidth `max` floor (Distance.pixels d (toFloat availableWidth)) rem = availableWidth `max` floor (Distance.pixels d (toFloat availableWidth))
e' = if E.widthOf e > rem then E.width rem e else e e' = if E.widthOf e > rem then E.width rem e else e