@@ -99,6 +99,9 @@ module Graphics.Vty.Config
99 , vtyDataDirectory
99 , vtyDataDirectory
100 , terminalWidthTablePath
100 , terminalWidthTablePath
101 , vtyConfigFileEnvName
101 , vtyConfigFileEnvName
103+ , ConfigUpdateResult(..)
@@ -122,9 +125,11 @@ import Graphics.Vty.Input.Events
123import GHC.Generics
126import GHC.Generics
125−import System.Directory (getAppUserDataDirectory)
128+import System.Directory ( getAppUserDataDirectory, doesFileExist
129+ , createDirectoryIfMissing
126import System.Environment (lookupEnv)
131import System.Environment (lookupEnv)
127−import System.FilePath ((</>))
132+import System.FilePath ((</>), takeDirectory)
128import System.Posix.IO (stdInput, stdOutput)
133import System.Posix.IO (stdInput, stdOutput)
129import System.Posix.Types (Fd(..))
134import System.Posix.Types (Fd(..))
130import Foreign.C.Types (CInt(..), CChar(..))
135import Foreign.C.Types (CInt(..), CChar(..))
@@ -419,3 +424,56 @@ getTtyEraseChar fd = do
419 if c /= 0
424 if c /= 0
420 then return $ Just $ toEnum $ fromEnum c
425 then return $ Just $ toEnum $ fromEnum c
421 else return Nothing
426 else return Nothing
428+data ConfigUpdateResult =
429+ ConfigurationCreated
430+ | ConfigurationModified
431+ | ConfigurationConflict String
432+ | ConfigurationRedundant
435+-- | Add a @widthMap@ directive to the Vty configuration file at the
438+-- If the configuration path refers to a configuration that already
439+-- contains the directive for the specified map and terminal type, the
440+-- configuration file will not be modified. If the file does not contain
441+-- the directive, it will be appended to the file.
443+-- If the configuration path does not exist, a new configuration file
444+-- will be created and any directories in the path will also be created.
446+-- This returns @True@ if the configuration was created or modified and
447+-- @False@ otherwise. This does not handle exceptions raised by file or
448+-- directory permissions issues.
449+addConfigWidthMap :: FilePath
450+ -- ^ The configuration file path of the configuration
451+ -- to modify or create.
453+ -- ^ The @TERM@ value for the @widthMap@ directive.
455+ -- ^ The width table file path for the directive.
456+ -> IO ConfigUpdateResult
457+addConfigWidthMap configPath term tablePath = do
458+ configEx <- doesFileExist configPath
461+ else createConfig >> return ConfigurationCreated
464+ directive = "widthMap " <> show term <> " " <> show tablePath <> "\n"
467+ let dir = takeDirectory configPath
468+ createDirectoryIfMissing True dir
469+ writeFile configPath directive
472+ config <- parseConfigFile configPath
473+ if (term, tablePath) `elem` termWidthMaps config
474+ then return ConfigurationRedundant
475+ else case lookup term (termWidthMaps config) of
476+ Just other -> return $ ConfigurationConflict other
478+ appendFile configPath directive
479+ return ConfigurationModified