Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizable keybindings #1979

Merged
merged 56 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
dc5b8dc
Refactor out a few abstract event handlers
xsebek Jun 23, 2024
829b4e3
Reformat
xsebek Jun 23, 2024
f6b8b76
Lot of shuffling just for updateUI
xsebek Jun 23, 2024
676f4d4
Restyle
xsebek Jun 23, 2024
d38770a
Refactor to use effect style
xsebek Jun 26, 2024
a9a12ff
Hide accessors
xsebek Jun 26, 2024
b9c921b
Fix lints
xsebek Jun 26, 2024
40e2ac3
Load keybindings from file and also print them
xsebek Jun 27, 2024
f2bad05
Swap markdown option
xsebek Jun 27, 2024
ebdcabf
Only use Throw for keybinding failures
xsebek Jun 29, 2024
7522fd2
Move pause and single tick to event handlers
xsebek Jun 29, 2024
66019d2
Refactor to use pattern matching in Event.hs
xsebek Jun 29, 2024
55404f0
Refactor to use pattern matching in event handlers
xsebek Jun 29, 2024
6fb883c
Move speed controls to new handler
xsebek Jun 29, 2024
f72d66d
Move set focus to new handler
xsebek Jun 29, 2024
9b3d3ba
Move Close modal to new event handler
xsebek Jun 29, 2024
2b25680
Move creative mode and world editor toggle to new event handler
xsebek Jun 29, 2024
00d6a98
Move collapse REPL to new event handler
xsebek Jun 29, 2024
c4f6f29
Move event handlers to a folder
xsebek Jun 29, 2024
28a899a
Move world panel events to new handler
xsebek Jun 29, 2024
4b2fef0
Move RobotPanel to new handler
xsebek Jun 29, 2024
8943f98
Fixup tests
xsebek Jun 29, 2024
a77ccd2
Restyled by fourmolu (#2001)
restyled-io[bot] Jun 29, 2024
850d528
Move back close modal
xsebek Jun 29, 2024
f828032
Add simple module docs
xsebek Jun 29, 2024
771e4b6
More module docs
xsebek Jun 29, 2024
b952e12
Add UpdateUI docs
xsebek Jun 29, 2024
35cfa03
Add module docs to Achievement helpers
xsebek Jun 29, 2024
fac6129
Add EventHandlers module and move createEventHandlers there
xsebek Jun 30, 2024
5394b80
Prepare for inter dispatcher collisions
xsebek Jun 30, 2024
e6991f5
Handle conflict between dispatchers
xsebek Jun 30, 2024
8cc493c
Add INI output
xsebek Jun 30, 2024
8c1d43f
Update dispatchers type name in Web
xsebek Jun 30, 2024
f5cceee
Show keybindings help in CLI
xsebek Jun 30, 2024
e5053db
Apply fixes by @byorgey
xsebek Jun 30, 2024
71fb876
Add init flag to keybindings CLI
xsebek Jun 30, 2024
7f5ee30
Add section comments to INI
xsebek Jun 30, 2024
d4c2fd4
Move lenses
xsebek Jun 30, 2024
5ee4b29
Use listEnums
xsebek Jun 30, 2024
8476bd1
Tweak spacing
xsebek Jun 30, 2024
75c883c
Address Map editor shortcut conflicts with move-to-end-of-line shortc…
xsebek Jul 5, 2024
31ebc3d
Show custom keybindings in key menus
xsebek Jul 5, 2024
e395dbc
Reformat
xsebek Jul 5, 2024
3b872f1
Show custom keybindings in Help modal dialog
xsebek Jul 5, 2024
5d7edf0
Use enumerate
xsebek Jul 5, 2024
3e39ed2
Add a note link
xsebek Jul 5, 2024
6d4cd74
Add TODOs for unfinished handlers
xsebek Jul 5, 2024
1eb14ec
Add more doc links
xsebek Jul 5, 2024
7f353a4
Add more docs and links
xsebek Jul 5, 2024
d7a008d
Apply tips from @kostmo
xsebek Jul 6, 2024
7eaed17
Use AbsoluteDir for MoveViewEvent
xsebek Jul 6, 2024
64f044a
Add doc for initialize INI switch
xsebek Jul 6, 2024
5b12b55
Fixup TPS event description - thanks @byorgey
xsebek Jul 6, 2024
56eb953
Allow brick 2.4
xsebek Jul 6, 2024
bac439d
Use enumerate
xsebek Jul 8, 2024
2741211
Merge branch 'main' into custom-keybindings
mergify[bot] Jul 8, 2024
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
34 changes: 34 additions & 0 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@
-- SPDX-License-Identifier: BSD-3-Clause
module Main where

import Control.Monad (when)
import Data.Foldable qualified
import Data.Text.IO qualified as T
import GitHash (GitInfo, giBranch, giHash, tGitInfoCwdTry)
import Options.Applicative
import Swarm.App (appMain)
import Swarm.Game.ResourceLoading (getSwarmConfigIniFile)
import Swarm.Language.Format
import Swarm.Language.LSP (lspMain)
import Swarm.Language.Parser.Core (LanguageVersion (..))
import Swarm.TUI.Model (AppOpts (..), ColorMode (..))
import Swarm.TUI.Model.KeyBindings (KeybindingPrint (..), showKeybindings)
import Swarm.TUI.Model.UI (defaultInitLgTicksPerSecond)
import Swarm.Version
import Swarm.Web (defaultPort)
Expand All @@ -30,6 +34,8 @@ commitInfo = case gitInfo of

data CLI
= Run AppOpts
| -- | Print list of bindings, optionally initializing the INI configuration file.
ListKeybinding Bool KeybindingPrint
| Format FormatConfig
| LSP
| Version
Expand All @@ -41,6 +47,7 @@ cliParser =
[ command "format" (info (Format <$> parseFormat) (progDesc "Format a file"))
, command "lsp" (info (pure LSP) (progDesc "Start the LSP"))
, command "version" (info (pure Version) (progDesc "Get current and upstream version."))
, command "keybindings" (info (ListKeybinding <$> initKeybindingConfig <*> printKeyMode <**> helper) (progDesc "List the keybindings"))
]
)
<|> Run
Expand Down Expand Up @@ -73,6 +80,15 @@ cliParser =
langVer :: Parser LanguageVersion
langVer = flag SwarmLangLatest SwarmLang0_5 (long "v0.5" <> help "Read (& convert) code from Swarm version 0.5")

printKeyMode :: Parser KeybindingPrint
printKeyMode =
flag' IniPrint (long "ini" <> help "Print in INI format")
<|> flag' MarkdownPrint (long "markdown" <> help "Print in Markdown table format")
<|> pure TextPrint

initKeybindingConfig :: Parser Bool
initKeybindingConfig = switch (short 'i' <> long "init" <> help "Initialise the keybindings configuration file")

parseFormat :: Parser FormatConfig
parseFormat = FormatConfig <$> input <*> output <*> optional widthOpt <*> langVer <**> helper

Expand Down Expand Up @@ -125,11 +141,29 @@ showVersion = do
up <- getNewerReleaseVersion gitInfo
either (hPrint stderr) (putStrLn . ("New upstream release: " <>)) up

printKeybindings :: Bool -> KeybindingPrint -> IO ()
printKeybindings initialize p = do
kb <- showKeybindings p
T.putStrLn kb
(iniExists, ini) <- getSwarmConfigIniFile
when initialize $ do
kbi <- showKeybindings IniPrint
T.writeFile ini kbi
let iniState
| iniExists && initialize = "has been updated"
| iniExists = "is"
| initialize = "has been created"
| otherwise = "can be created (--init)"
putStrLn $ replicate 80 '-'
putStrLn $ "The configuration file " <> iniState <> " at:"
putStrLn ini

main :: IO ()
main = do
cli <- execParser cliInfo
case cli of
Run opts -> appMain opts
ListKeybinding initialize p -> printKeybindings initialize p
Format cfg -> formatSwarmIO cfg
LSP -> lspMain
Version -> showVersion
10 changes: 1 addition & 9 deletions src/swarm-engine/Swarm/Game/Achievement/Persistence.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{-# LANGUAGE OverloadedStrings #-}

-- |
-- SPDX-License-Identifier: BSD-3-Clause
-- Description: Achievements load/save
Expand All @@ -18,17 +16,11 @@ import Data.Yaml qualified as Y
import Swarm.Game.Achievement.Attainment
import Swarm.Game.Achievement.Definitions
import Swarm.Game.Failure
import Swarm.Game.ResourceLoading (getSwarmXdgDataSubdir)
import Swarm.Game.ResourceLoading (getSwarmAchievementsPath)
import Swarm.Util.Effect (forMW)
import System.Directory (doesDirectoryExist, doesFileExist, listDirectory)
import System.FilePath ((</>))

-- | Get a path to the directory where achievement records are
-- stored. If the argument is set to @True@, create the directory if
-- it does not exist.
getSwarmAchievementsPath :: Bool -> IO FilePath
getSwarmAchievementsPath createDirs = getSwarmXdgDataSubdir createDirs "achievement"

-- | Load saved info about achievements from XDG data directory.
-- Returns a list of attained achievements.
loadAchievementsInfo ::
Expand Down
3 changes: 3 additions & 0 deletions src/swarm-scenario/Swarm/Constant.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import Data.Text (Text)
-- By convention, all URL constants include trailing slashes
-- when applicable.

swarmWebIRC :: Text
swarmWebIRC = "https://web.libera.chat/?channels=#swarm"

-- | The URL for the Swarm repository.
swarmRepoUrl :: Text
swarmRepoUrl = "https://github.com/swarm-game/swarm/"
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-scenario/Swarm/Game/Failure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ data AssetData = AppAsset | NameGeneration | Entities | Terrain | Recipes | Worl
deriving (Eq, Show)

-- | Overarching enumeration of various assets we can attempt to load.
data Asset = Achievement | Data AssetData | History | Save
data Asset = Achievement | Data AssetData | History | Keybindings | Save
deriving (Eq, Show)

-- | Enumeration type to distinguish between directories and files.
Expand Down
41 changes: 28 additions & 13 deletions src/swarm-scenario/Swarm/Game/ResourceLoading.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@
-- Description: Fetching game data
--
-- Various utilities related to loading game data files.
module Swarm.Game.ResourceLoading where
module Swarm.Game.ResourceLoading (
-- * Generic data access
getDataDirSafe,
getDataFileNameSafe,

-- * Concrete data access
getSwarmConfigIniFile,
getSwarmSavePath,
getSwarmHistoryPath,
getSwarmAchievementsPath,

-- ** Loading text files
readAppData,
NameGenerator (..),
initNameGenerator,
) where

import Control.Algebra (Has)
import Control.Effect.Lift (Lift, sendIO)
Expand All @@ -23,7 +38,7 @@ import Paths_swarm (getDataDir)
import Swarm.Game.Failure
import Swarm.Util
import System.Directory (
XdgDirectory (XdgData),
XdgDirectory (..),
createDirectoryIfMissing,
doesDirectoryExist,
doesFileExist,
Expand Down Expand Up @@ -83,17 +98,11 @@ getDataFileNameSafe asset name = do
then return fp
else throwError $ AssetNotLoaded (Data asset) fp $ DoesNotExist File

-- | Get a nice message suggesting to download @data@ directory to 'XdgData'.
dataNotFound :: FilePath -> IO LoadingFailure
xsebek marked this conversation as resolved.
Show resolved Hide resolved
dataNotFound f = do
d <- getSwarmXdgDataSubdir False ""
let squotes = squote . T.pack
return $
CustomMessage $
T.unlines
[ "Could not find the data: " <> squotes f
, "Try downloading the Swarm 'data' directory to: " <> squotes (d </> "data")
]
getSwarmConfigIniFile :: IO (Bool, FilePath)
getSwarmConfigIniFile = do
ini <- (</> "config.ini") <$> getXdgDirectory XdgConfig "swarm"
iniExists <- doesFileExist ini
return (iniExists, ini)

-- | Get path to swarm data, optionally creating necessary
-- directories. This could fail if user has bad permissions
Expand All @@ -120,6 +129,12 @@ getSwarmSavePath createDirs = getSwarmXdgDataSubdir createDirs "saves"
getSwarmHistoryPath :: Bool -> IO FilePath
getSwarmHistoryPath createDirs = getSwarmXdgDataFile createDirs "history"

-- | Get a path to the directory where achievement records are
-- stored. If the argument is set to @True@, create the directory if
-- it does not exist.
getSwarmAchievementsPath :: Bool -> IO FilePath
getSwarmAchievementsPath createDirs = getSwarmXdgDataSubdir createDirs "achievement"

-- | Read all the @.txt@ files in the @data/@ directory.
readAppData ::
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
Expand Down
Loading