Skip to content

Commit

Permalink
Merge branch 'feature/theme-ini'
Browse files Browse the repository at this point in the history
  • Loading branch information
someodd committed Aug 25, 2020
2 parents 7f44281 + 07e3a2c commit d1b5157
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 5 deletions.
2 changes: 2 additions & 0 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import BrickApp
import Config
import Config.ConfigOpen
import Config.Bookmarks
import Config.Theme

handleArgs :: [String] -> IO ()
handleArgs [] = uiMain Nothing
Expand All @@ -21,6 +22,7 @@ main = do
setupConfigDirectory
setupDefaultOpenConfig
setupDefaultBookmarks
setupDefaultTheme
-- Now run!
args <- getArgs
handleArgs args
114 changes: 114 additions & 0 deletions data/theme.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Waffle theme
#
# Please see:
# https://hackage.haskell.org/package/brick-0.55/docs/Brick-Themes.html
#
# COLOR SPECIFICATION
#
# A color specification can be any of the strings black, red, green, yellow,
# blue, magenta, cyan, white, brightBlack, brightRed, brightGreen,
# brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, or default.
#
# We also support color specifications in the common hex format #RRGGBB, but
# note that this specification is lossy: terminals can only display 256 colors,
# but hex codes can specify 256^3 = 16777216 colors.
#
# STYLE SPECIFICATION
#
# A style specification can be either one of the following values (without
# quotes) or a comma-delimited list of one or more of the following values
# (e.g. "[bold,underline]") indicating that all of the specified styles be
# used. Valid styles are standout, underline, reverseVideo, blink, dim, italic,
# and bold.

[default]
# A color spec
default.fg = white
# another color spec
default.bg = black
# a style spec
#default.style=""

# The other section specifies for each attribute name in the theme the same fg,
# bg, and style settings as for the default attribute. Furthermore, if an
# attribute name has multiple components, the fields in the INI file should use
# periods as delimiters. For example, if a theme has an attribute name ("foo"
# <> "bar"), then the file may specify three fields:
#
# foo.bar.fg - a color specification
# foo.bar.bg - a color specification
# foo.bar.style - a style specification
#
# Any color or style specifications omitted from the file mean that those
# attribute or style settings will use the theme's default value instead.
#
# Attribute names with multiple components (e.g. attr1 <> attr2) can be
# referenced in customization files by separating the names with a dot. For
# example, the attribute name "list" <> "selected" can be referenced by using
# the string "list.selected".
[other]
# for the input dialog popup i guess? FIXME
inputDialogAttr.fg=#FFFF00
inputDialogAttr.bg=#000000
# For the directory line descriptor in menu mode
directoryAttr.fg=#FF0000
# for the file line descriptor in menu mode
fileAttr.fg=cyan
# for the index search line descriptor in menu mode
indexSearchServerAttr.fg=magenta
# for uh... i forgot honestly FIXME
linkAttr.fg=#1C98FF
# for info lines in menu mode, i think
textAttr.fg=#FFFF00
# for all other line descriptors (catchall)
genericTypeAttr.fg=green
# for the numbers that prefix links you can follow in menu mode
numberPrefixAttr.fg=#FC28FE
# i have no idea, what a horrible name FIXME
customAttr.style=bold
customAttr.fg=white
# i have no idea FIXME
custom2Attr.fg=yellow
# The title bar label
titleAttr.style=[reverseVideo,bold]
titleAttr.fg=white
# the input dialog... title label? FIXME
inputDialogLabelAttr.style=[reverseVideo,bold]
inputDialogLabelAttr.fg=yellow
# i have no idea FIXME
asteriskAttr.fg=white
# For uh... regular list... items? in menu mode? FIXME
listAttr.fg=yellow
listAttr.bg=#000000
# for the selected item in menu mode
listSelectedAttr.style=bold
listSelectedAttr.fg=white
# for... editor field default style? FIXME
editAttr.fg=white
editAttr.bg=brightBlack
# for an editor field selected focus maybe? FIXME
editFocusedAttr.fg=white
editFocusedAttr.bg=brightBlack
# for the file browser's current directory
fileBrowserCurrentDirectoryAttr.fg=white
fileBrowserCurrentDirectoryAttr.bg=blue
# for the uh... selection... info...? FIXME
fileBrowserSelectionInfoAttr.fg=white
fileBrowserSelectionInfoAttr.bg=blue
# File browser directory style
fileBrowserDirectoryAttr.fg=blue
# File browser... block device? FIXME
fileBrowserBlockDeviceAttr.fg=magenta
# file browser character device ??? FIXME
fileBrowserCharacterDeviceAttr.fg=green
# file browser named pipe attr??? FIXME
fileBrowserNamedPipeAttr.fg=yellow
# symbolic link in file browser FIXME
fileBrowserSymbolicLinkAttr.fg=cyan
# unix socket? FIXME in file browser
fileBrowserUnixSocketAttr.fg=red
# selected item in file browser
fileBrowserSelectedAttr.fg=white
fileBrowserSelectedAttr.bg=magenta
# idk FIXME
errorAttr.fg=red
3 changes: 2 additions & 1 deletion src/BrickApp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@ uiMain possibleLocation = do
}
in initProgressMode initialGbs (Just history) trueLocationType

void $ B.customMain initialVty buildVty (Just eventChan) theApp initialState
theme <- getTheme
void $ B.customMain initialVty buildVty (Just eventChan) (theApp {B.appAttrMap=const theme}) initialState
33 changes: 29 additions & 4 deletions src/BrickApp/Utils/Style.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module BrickApp.Utils.Style
, inputDialogBorder
, inputDialogBorderAttr
, borderMappingsInputDialog
, getTheme
, borderMappings
, errorAttr
, inputDialogAttr
Expand All @@ -23,6 +24,11 @@ module BrickApp.Utils.Style
, genericTypeAttr
) where

import Brick.Themes ( Theme
, newTheme
, themeToAttrMap
, loadCustomizations
)
import qualified Brick.Widgets.List as L
import qualified Graphics.Vty as V
import qualified Brick.Widgets.FileBrowser as FB
Expand All @@ -34,6 +40,22 @@ import Brick.Util ( fg
, on
)

import Config.Theme ( getUserThemePath )

-- | In order to use ini-defined themes we need to have a default `Theme`,
-- as that's the way `Brick` works.
defaultTheme :: Theme
defaultTheme = newTheme (V.white `on` V.blue) listMapThingy

-- | Load the main theme..
getTheme :: IO A.AttrMap
getTheme = do
userThemePath <- getUserThemePath
perhapsTheme <- loadCustomizations userThemePath defaultTheme
case perhapsTheme of
Left errorMessage -> error errorMessage
Right theme -> pure $ themeToAttrMap theme

-- TODO: this all feels very messy
customAttr :: A.AttrName
customAttr = "custom"
Expand Down Expand Up @@ -81,14 +103,13 @@ inputDialogLabelAttr = "inputDialogLabelAttr"
inputDialogAttr :: A.AttrName
inputDialogAttr = "inputDialogAttr"

theMap :: A.AttrMap
theMap = A.attrMap
V.defAttr
listMapThingy :: [(A.AttrName, V.Attr)]
listMapThingy =
[ (L.listAttr, V.yellow `on` V.rgbColor (0 :: Int) (0 :: Int) (0 :: Int))
, ( L.listSelectedAttr
, (V.defAttr `V.withStyle` V.bold) `V.withForeColor` V.white
)
, ( inputDialogAttr
, ( inputDialogAttr-- FIXME: unused?
, V.rgbColor (255 :: Int) (255 :: Int) (0 :: Int)
`on` V.rgbColor (0 :: Int) (0 :: Int) (0 :: Int)
)
Expand Down Expand Up @@ -126,6 +147,10 @@ theMap = A.attrMap
, (errorAttr , fg V.red)
]

theMap :: A.AttrMap
theMap = A.attrMap
V.defAttr listMapThingy

customBorder :: BS.BorderStyle
customBorder = BS.BorderStyle { BS.bsCornerTL = ''
, BS.bsCornerTR = ''
Expand Down
29 changes: 29 additions & 0 deletions src/Config/Theme.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{-# LANGUAGE TemplateHaskell #-}

-- | Configuration for themes, namely handling theme.ini.

module Config.Theme ( setupDefaultTheme, getUserThemePath ) where

import System.FilePath
import qualified Data.ByteString.Lazy as BL

import Data.FileEmbed

import Config ( getConfigDirectory, doIfPathDoesntExist )

-- | The standard theme.ini which ships with waffle; before it gets copied
-- to the user's config directory.
defaultThemeContents :: BL.ByteString
defaultThemeContents = BL.fromStrict $(embedFile "data/theme.ini")

-- | Writes a theme.ini to the user's config directory if they don't have one already.
setupDefaultTheme :: IO ()
setupDefaultTheme = do
userThemePath <- getUserThemePath
doIfPathDoesntExist userThemePath (BL.writeFile userThemePath defaultThemeContents)

-- | Get the `FilePath` to the user's open/associations configuration file.
getUserThemePath :: IO FilePath
getUserThemePath = do
configDir <- getConfigDirectory
pure $ joinPath [configDir, "theme.ini"]
1 change: 1 addition & 0 deletions waffle.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ library
Config
Config.ConfigOpen
Config.Bookmarks
Config.Theme

BrickApp

Expand Down

0 comments on commit d1b5157

Please sign in to comment.