Skip to content
This repository was archived by the owner on Jul 19, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"build": "npm run makeElmEnv; webpack --mode production --config webpack.prod.js",
"clean": "rm -rf dist",
"watch": "npm run makeElmEnv; webpack --mode development --watch --config webpack.dev.js",
"start": "npm run makeElmEnv; webpack serve --mode development --port 1234 --config webpack.dev.js",
"start": "npm run makeElmEnv; webpack serve --mode development --port 1234 --config webpack.dev.js",
"test": "elm-test",
"makeElmEnv": "node ./scripts/makeElmEnv.mjs"
},
Expand Down
140 changes: 123 additions & 17 deletions src/App.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import CodebaseTree
import Definition.Reference exposing (Reference(..))
import Finder
import HashQualified exposing (HashQualified(..))
import Html exposing (Html, a, aside, div, h1, header, nav, text)
import Html.Attributes exposing (href, id, target)
import Html exposing (Html, a, aside, div, h1, h3, header, nav, section, span, text)
import Html.Attributes exposing (class, href, id, target)
import Html.Events exposing (onClick)
import KeyboardShortcut
import KeyboardShortcut.Key exposing (Key(..))
import KeyboardShortcut.Key as Key exposing (Key(..))
import KeyboardShortcut.KeyboardEvent as KeyboardEvent exposing (KeyboardEvent)
import RelativeTo exposing (RelativeTo(..))
import RemoteData exposing (RemoteData(..))
import Route exposing (Route)
import System exposing (OperatingSystem(..), System)
import UI
import UI.Icon as Icon
import UI.Modal as Modal
import Url exposing (Url)
import Workspace

Expand All @@ -27,6 +30,7 @@ import Workspace
type Modal
= NoModal
| FinderModal Finder.Model
| HelpModal


type alias Model =
Expand All @@ -37,11 +41,16 @@ type alias Model =
, workspace : Workspace.Model
, modal : Modal
, keyboardShortcut : KeyboardShortcut.Model
, system : System
}


init : () -> Url -> Nav.Key -> ( Model, Cmd Msg )
init _ url navKey =
type alias Flags =
{ system : { operatingSystem : String } }


init : Flags -> Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url navKey =
let
route =
Route.fromUrl url
Expand All @@ -62,14 +71,18 @@ init _ url navKey =
relativeTo =
Maybe.withDefault Codebase (Route.relativeTo route)

system =
System.fromRecord flags.system

model =
{ navKey = navKey
, route = route
, relativeTo = relativeTo
, workspace = workspace
, codebaseTree = codebaseTree
, modal = NoModal
, keyboardShortcut = KeyboardShortcut.init
, keyboardShortcut = KeyboardShortcut.init system.operatingSystem
, system = system
}
in
( model
Expand All @@ -86,6 +99,8 @@ type Msg
| UrlChanged Url
| Keydown KeyboardEvent
| OpenDefinition Reference
| ShowHelpModal
| CloseModal
-- sub msgs
| FinderMsg Finder.Msg
| WorkspaceMsg Workspace.Msg
Expand All @@ -111,6 +126,13 @@ update msg model =
OpenDefinition ref ->
openDefinition model ref

ShowHelpModal ->
( { model | modal = HelpModal }, Cmd.none )

CloseModal ->
( { model | modal = NoModal }, Cmd.none )

-- Sub msgs
WorkspaceMsg wMsg ->
let
( workspace, wCmd, outMsg ) =
Expand Down Expand Up @@ -144,9 +166,6 @@ update msg model =

FinderMsg fMsg ->
case model.modal of
NoModal ->
( model, Cmd.none )

FinderModal fModel ->
let
( fm, fc, out ) =
Expand All @@ -162,6 +181,9 @@ update msg model =
Finder.OpenDefinition ref ->
openDefinition { model | modal = NoModal } ref

_ ->
( model, Cmd.none )

KeyboardShortcutMsg kMsg ->
let
( keyboardShortcut, cmd ) =
Expand Down Expand Up @@ -210,23 +232,45 @@ keydown model keyboardEvent =
let
shortcut =
KeyboardShortcut.fromKeyboardEvent model.keyboardShortcut keyboardEvent

noOp =
( model, Cmd.none )
in
case shortcut of
KeyboardShortcut.Chord Ctrl (K _) ->
showFinder model

KeyboardShortcut.Chord Meta (K _) ->
if model.system.operatingSystem == System.MacOS then
showFinder model

else
noOp

KeyboardShortcut.Sequence _ ForwardSlash ->
showFinder model

KeyboardShortcut.Chord Shift QuestionMark ->
( { model | modal = HelpModal }, Cmd.none )

KeyboardShortcut.Sequence _ Escape ->
if model.modal == HelpModal then
( { model | modal = NoModal }, Cmd.none )

else
noOp

_ ->
( model, Cmd.none )
noOp


showFinder : { m | modal : Modal } -> ( { m | modal : Modal }, Cmd Msg )
showFinder :
{ m | system : System, modal : Modal }
-> ( { m | system : System, modal : Modal }, Cmd Msg )
showFinder model =
let
( fm, fcmd ) =
Finder.init
Finder.init model.system
in
( { model | modal = FinderModal fm }, Cmd.map FinderMsg fcmd )

Expand All @@ -252,21 +296,83 @@ viewMainSidebar model =
, nav []
[ a [ href "https://unison-lang.org", target "_blank" ] [ Icon.view Icon.UnisonMark ]
, a [ href "https://unison-lang.org/docs", target "_blank" ] [ text "Docs" ]
, a [ href "https://unison-lang.org/community", target "_blank" ] [ text "Community" ]
, a [ href "https://unison-lang.org/docs/language-reference", target "_blank" ] [ text "Language Reference" ]
, a [ href "https://unison-lang.org/community", target "_blank" ] [ text "Community" ]
, a [ class "show-help", onClick ShowHelpModal ] [ text "Keyboard Shortcuts", KeyboardShortcut.view model.keyboardShortcut (KeyboardShortcut.single QuestionMark) ]
]
]


viewModal : Modal -> Html Msg
viewModal modal =
case modal of
viewHelpModal : OperatingSystem -> KeyboardShortcut.Model -> Html Msg
viewHelpModal os keyboardShortcut =
let
viewRow label instructions =
div
[ class "row" ]
[ label
, div [ class "instructions" ] instructions
]

viewInstructions label shortcuts =
viewRow label [ KeyboardShortcut.viewShortcuts keyboardShortcut shortcuts ]

openFinderInstructions =
case os of
MacOS ->
[ KeyboardShortcut.Chord Meta (K Key.Lower), KeyboardShortcut.Chord Ctrl (K Key.Lower), KeyboardShortcut.single ForwardSlash ]

_ ->
[ KeyboardShortcut.Chord Ctrl (K Key.Lower), KeyboardShortcut.single ForwardSlash ]

content =
Modal.Content
(section
[ class "shortcuts" ]
[ div [ class "shortcut-group" ]
[ h3 [] [ text "General" ]
, viewInstructions (span [] [ text "Keyboard shortcuts", UI.subtle " (this dialog)" ]) [ KeyboardShortcut.single QuestionMark ]
, viewInstructions (text "Open Finder") openFinderInstructions
, viewInstructions (text "Move focus up") [ KeyboardShortcut.single ArrowUp, KeyboardShortcut.single (K Key.Lower) ]
, viewInstructions (text "Move focus down") [ KeyboardShortcut.single ArrowDown, KeyboardShortcut.single (J Key.Lower) ]
, viewInstructions (text "Close focused definition") [ KeyboardShortcut.single (X Key.Lower) ]
]
, div [ class "shortcut-group" ]
[ h3 [] [ text "Finder" ]
, viewInstructions (text "Clear search query") [ KeyboardShortcut.single Escape ]
, viewInstructions (span [] [ text "Close", UI.subtle " (when search query is empty)" ]) [ KeyboardShortcut.single Escape ]
, viewInstructions (text "Move focus up") [ KeyboardShortcut.single ArrowUp ]
, viewInstructions (text "Move focus down") [ KeyboardShortcut.single ArrowDown ]
, viewInstructions (text "Open focused definition") [ KeyboardShortcut.single Enter ]
, viewRow (text "Open definition")
[ KeyboardShortcut.viewBase
[ KeyboardShortcut.viewKey os Semicolon False
, KeyboardShortcut.viewThen
, KeyboardShortcut.viewKeyBase "1-9" False
]
]
]
]
)
in
Modal.modal "help-modal" CloseModal content
|> Modal.withHeader "Keyboard shortcuts"
|> Modal.view


viewModal :
{ m | system : System, modal : Modal, keyboardShortcut : KeyboardShortcut.Model }
-> Html Msg
viewModal model =
case model.modal of
NoModal ->
UI.nothing

FinderModal m ->
Html.map FinderMsg (Finder.view m)

HelpModal ->
viewHelpModal model.system.operatingSystem model.keyboardShortcut


view : Model -> Browser.Document Msg
view model =
Expand All @@ -275,7 +381,7 @@ view model =
[ div [ id "app" ]
[ viewMainSidebar model
, Html.map WorkspaceMsg (Workspace.view model.workspace)
, viewModal model.modal
, viewModal model
]
]
}
63 changes: 35 additions & 28 deletions src/Finder.elm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import List.Nonempty as NEL
import RemoteData exposing (RemoteData(..), WebData)
import SearchResults exposing (SearchResults(..))
import Syntax
import System exposing (System)
import Task
import UI
import UI.Icon as Icon
Expand All @@ -69,11 +70,11 @@ type alias Model =
}


init : ( Model, Cmd Msg )
init =
init : System -> ( Model, Cmd Msg )
init system =
( { query = ""
, results = NotAsked
, keyboardShortcut = KeyboardShortcut.init
, keyboardShortcut = KeyboardShortcut.init system.operatingSystem
}
, focusSearchInput
)
Expand Down Expand Up @@ -320,15 +321,15 @@ viewMatch keyboardShortcut match isFocused shortcut =
let
shortcutIndicator =
if isFocused then
KeyboardShortcut.viewShortcut keyboardShortcut (Sequence Nothing Key.Enter)
KeyboardShortcut.view keyboardShortcut (Sequence Nothing Key.Enter)

else
case shortcut of
Nothing ->
UI.nothing

Just key ->
KeyboardShortcut.viewShortcut keyboardShortcut (Sequence (Just Key.Semicolon) key)
KeyboardShortcut.view keyboardShortcut (Sequence (Just Key.Semicolon) key)

viewMatch_ reference icon naming source =
tr
Expand All @@ -338,7 +339,7 @@ viewMatch keyboardShortcut match isFocused shortcut =
[ td [ class "category" ] [ Icon.view icon ]
, naming
, td [ class "source" ] [ source ]
, td [ class "shortcut" ] [ shortcutIndicator ]
, td [] [ div [ class "shortcut" ] [ shortcutIndicator ] ]
]
in
case match.item of
Expand Down Expand Up @@ -401,26 +402,32 @@ view model =

_ ->
UI.nothing

content =
Modal.CustomContent
(div
[]
[ header []
[ Icon.view Icon.Search
, input
[ type_ "text"
, id "search"
, autocomplete False
, spellcheck False
, placeholder "Search by name, namespace, and/or type"
, onInput UpdateQuery
, value model.query
]
[]
, a [ class "reset", onClick ResetOrClose ] [ Icon.view Icon.X ]
]
, results
]
)
in
-- We stopPropagation such that movement shortcuts, like J or K, for the
-- workspace aren't triggered when in the modal when the use is trying to
-- type those letters into the search field
Modal.view
Close
[ id "finder", KeyboardEvent.stopPropagationOn KeyboardEvent.Keydown Keydown ]
[ header []
[ Icon.view Icon.Search
, input
[ type_ "text"
, id "search"
, autocomplete False
, spellcheck False
, placeholder "Search by name, namespace, and/or type"
, onInput UpdateQuery
, value model.query
]
[]
, a [ class "reset", onClick ResetOrClose ] [ Icon.view Icon.X ]
]
, results
]
Modal.modal "finder" Close content
-- We stopPropagation such that movement shortcuts, like J or K, for the
-- workspace aren't triggered when in the modal when the use is trying to
-- type those letters into the search field
|> Modal.withAttributes [ KeyboardEvent.stopPropagationOn KeyboardEvent.Keydown Keydown ]
|> Modal.view
2 changes: 1 addition & 1 deletion src/Hub.elm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import App
import Browser


main : Program () App.Model App.Msg
main : Program App.Flags App.Model App.Msg
main =
Browser.application
{ init = App.init
Expand Down
Loading