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

load and save preferences from preferences dialog to file #133

Closed
cdepillabout opened this issue Oct 19, 2019 · 4 comments
Closed

load and save preferences from preferences dialog to file #133

cdepillabout opened this issue Oct 19, 2019 · 4 comments

Comments

@cdepillabout
Copy link
Owner

cdepillabout commented Oct 19, 2019

PR #130 (for issue #82) implemented a preferences dialog that allows the user to modify Termonad settings at runtime.

Here's what the preferences dialog currently looks like:

image

However, as you can see from the warning, these settings are lost when you exit out of Termonad.

It would be nice if these settings could be serialized to a file, and loaded when Termonad starts.

There are a couple tricky parts about implementing something like this:

  • In the preferences dialog, should there be two buttons, one for setting the preferences temporarily, and one for actually saving the preferences to a file (so the preferences will be loaded next time you start Termonad). Would this be confusing for any users?
  • What sort of file format should you serialize preferences to? It would be nice to have something the user could edit with a text editor (like vim or emacs), but if you allowed this, then things like comments could potentially get overwritten the next time you serialized (saved) their preferences from Termonad. Some sort of binary format that discourages hand-editing might be the best bet.
  • The preferences serialization format should probably be versioned, so old preferences files could be read by newer versions of Termonad.
  • If the user sets the same setting in both the preferences serialization file and their ~/.config/termonad/termonad.hs file, which setting should be used?
  • If the user modifies a setting in the preferences serialization file, maybe it could overwrite the value of the setting in the ~/.config/termonad/termonad.hs. However, what if the user decides that they don't want to use the setting from the preferences serialization file anymore, but instead to use the value of the setting from ~/.config/termonad/termonad.hs. There should be a way to only set some settings in the preferences serialization file, without having to set all settings in the preferences serialization file. For instance, maybe you want the "Scrollback Length" setting to be managed in the preferences serialization file, but you want to set the "Cursor Blink Mode" in ~/.config/termonad/termonad.hs. Termonad should be flexible enough to handle this.

Although note that all of these problems don't necessarily have to be solved in the first PR implementing this.


If you're interested in implementing this, here's the places in the code you'd need to look at:

  • The defaultMain function is the one that interacts with dyre to dynamically reload the ~/.config/termonad/termonad.hs file:

    defaultMain :: TMConfig -> IO ()
    defaultMain tmConfig = do
    let params =
    defaultParams
    { projectName = "termonad"
    , showError = \(cfg, oldErrs) newErr -> (cfg, oldErrs <> "\n" <> newErr)
    , realMain = \(cfg, errs) -> putStrLn (pack errs) *> start cfg
    }
    eitherRes <- tryIOError $ wrapMain params (tmConfig, "")
    case eitherRes of
    Left ioErr
    | ioeGetErrorType ioErr == doesNotExistErrorType && ioeGetFileName ioErr == Just "ghc" -> do
    putStrLn $
    "Could not find ghc on your PATH. Ignoring your termonad.hs " <>
    "configuration file and running termonad with default settings."
    start tmConfig
    | otherwise -> do
    putStrLn $ "IO error occurred when trying to run termonad:"
    print ioErr
    putStrLn "Don't know how to recover. Exiting."
    Right _ -> pure ()

    This function might have to be modified to try to load settings from the serialized preferences file. Or maybe the start function would be a better candidate.

    start :: TMConfig -> IO ()
    start tmConfig = do
    -- app <- appNew (Just "haskell.termonad") [ApplicationFlagsFlagsNone]
    -- Make sure the application is not unique, so we can open multiple copies of it.
    app <- appNew Nothing [ApplicationFlagsFlagsNone]
    void $ onApplicationStartup app (appStartup app)
    void $ onApplicationActivate app (appActivate tmConfig app)
    void $ applicationRun app Nothing

  • This is the function that shows the preferences dialog and actually sets the preferences:

    showPreferencesDialog :: TMState -> IO ()

    This function will have to be modified to possibly serialize the preferences to a file.

    You might want to create a separate datatype to represent the preferences we are serializing.

  • The layout of the actual preferences dialog is in glade/preferences.glade. You probably want to use Glade to add new buttons to this dialog.

@jecaro
Copy link
Contributor

jecaro commented Nov 1, 2019

I think a simple mechanism which covers most use cases would be:

  1. If there is no config file, Termonad writes it with the default settings. Then, when the user validates the preferences dialog, it applies the settings and overrides the config file as well. The warning label is not shown in this case. This is the way most software handle this, so it is the expected behavior. It will be nice for new comer to Termonad and "basic users".

  2. And for "power users", who have a termonad.hs. We can make their termonad.hs file take precedence over the config file. The behavior stays the same but the warning label is shown.

What do you think ?

@cdepillabout
Copy link
Owner Author

@jecaro Sorry for taking a while to get back to you about this!

I think the strategy you have proposed is a good solution. If you want to send a PR implementing this, I would accept it!

@jecaro
Copy link
Contributor

jecaro commented Nov 13, 2019

Great, I'll start working on this very soon.

@cdepillabout
Copy link
Owner Author

cdepillabout commented Dec 7, 2019

This has mostly been implemented in #140.

This is implemented as described in #133 (comment).

At some point, it might be nice to figure out a way for an end-user to use both preferences from the preferences file in ~/.config/termonad/termonad.yaml, and the Haskell settings in ~/.config/termonad/termonad.hs.

But for now, I think forcing the user to use one or the other should be fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants