hub.darcs.net :: elaforge -> karya-linear_0 -> annotate -> Cmd/Save.hs

Sequencer. (fork of elaforge's karya)

add copyright notice to everything qdunkan@gmail.com Fri May 31 06:59:23 UTC 2013
1
2
3
4
-- Copyright 2013 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
5
{-# LANGUAGE LambdaCase #-}
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
6
{- | Functions to save and restore state to and from files.
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
7
8
9
10
11
12

    The naming convention is that @load@ and @save@ functions either load
    the given file, replace the state with it, and set the SaveFile, or save
    the current state and set the SaveFile.  @read@ and @write@ functions
    are lower level and either read the file and return the state, or write the
    given state, without messing with the SaveFile.
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
13
-}
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
14
15
module Cmd.Save (
    -- * universal
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
16
    save, load, read, read_, load_template
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
17
18
19
20
21
    , infer_save_type
    -- * state
    , save_state, save_state_as, load_state
    , read_state, read_state_, write_state
    , write_current_state
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
22
23
    -- ** path
    , get_state_path, state_path_for_repo, infer_state_path
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
24
25
26
27
    -- * git
    , save_git, save_git_as, load_git, revert
    , get_git_path
    -- * config
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
28
    , save_allocations, load_allocations
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
29
30
31
    -- * misc
    , save_views
) where
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
32
import Prelude hiding (read)
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
33
import qualified Control.Exception as Exception
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
34
import qualified Control.Monad.Identity as Identity
when saving to git, automatically add .git suffix if it doesn't already have one qdunkan@gmail.com Sat Oct 10 04:38:32 UTC 2015
35
import qualified Data.List as List
fix bug where a newly loaded state doesn't get the right focus qdunkan@gmail.com Sat Jul 30 23:50:31 UTC 2011
36
import qualified Data.Map as Map
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
37
import qualified Data.Text as Text
expand `y-m-d` in save file names qdunkan@gmail.com Tue Jun 10 06:47:14 UTC 2014
38
import qualified Data.Time as Time
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
make state loading smarter, now you can give it a directory and it'll look inside for .git or .state files qdunkan@gmail.com Wed Jan 2 06:48:32 UTC 2013
40
import qualified System.Directory as Directory
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
41
import qualified System.FilePath as FilePath
make state loading smarter, now you can give it a directory and it'll look inside for .git or .state files qdunkan@gmail.com Wed Jan 2 06:48:32 UTC 2013
42
import System.FilePath ((</>))
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
44
import qualified Util.File as File
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
45
import qualified Util.Git as Git
quarantine compatibility cpp to Util.Locale qdunkan@gmail.com Sat Oct 10 02:27:24 UTC 2015
46
import qualified Util.Locale as Locale
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
47
import qualified Util.Log as Log
fix bug where a newly loaded state doesn't get the right focus qdunkan@gmail.com Sat Jul 30 23:50:31 UTC 2011
48
import qualified Util.Seq as Seq
add support for serializing events with Im backend insts qdunkan@gmail.com Thu Feb 11 03:58:56 UTC 2016
49
import qualified Util.Serialize as Serialize
expand `y-m-d` in save file names qdunkan@gmail.com Tue Jun 10 06:47:14 UTC 2014
50
import qualified Util.TextUtil as TextUtil
fix bug where a newly loaded state doesn't get the right focus qdunkan@gmail.com Sat Jul 30 23:50:31 UTC 2011
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
52
import qualified Ui.Id as Id
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
53
import qualified Ui.Ui as Ui
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
54
import qualified Ui.UiConfig as UiConfig
keep the old clip namespace around when loading a new score Evan Laforge <qdunkan@gmail.com> Tue Dec 2 05:00:14 UTC 2014
55
56
import qualified Ui.Transform as Transform
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
57
import qualified Cmd.Cmd as Cmd
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
58
import qualified Cmd.Instrument.MidiInst as MidiInst
fix bug where play doesnt stop, I think, by removing unused block_id from Transport.Status qdunkan@gmail.com Sat Jul 30 23:14:37 UTC 2011
59
import qualified Cmd.Play as Play
move Ui.SaveGit to Cmd.SaveGit qdunkan@gmail.com Mon May 7 06:27:14 UTC 2012
60
import qualified Cmd.SaveGit as SaveGit
remove Util.Git dependency from tests qdunkan@gmail.com Sat May 23 02:07:05 UTC 2015
61
import qualified Cmd.SaveGitTypes as SaveGitTypes
add support for serializing events with Im backend insts qdunkan@gmail.com Thu Feb 11 03:58:56 UTC 2016
62
import qualified Cmd.Serialize
display edit mode as global, since it is qdunkan@gmail.com Sun Jun 1 00:21:04 UTC 2008
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
64
65
import qualified Perform.Midi.Patch as Patch
import qualified Instrument.Inst as Inst
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
66
import qualified App.Config as Config
split Util.Control into Global Evan Laforge <qdunkan@gmail.com> Thu Nov 13 06:12:28 UTC 2014
67
import Global
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
check in Cmd.Create, utilities to create and modify UI elements qdunkan@gmail.com Thu Jun 19 20:21:17 UTC 2008
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
70
71
72
73
-- * universal

-- | Save to the current 'Cmd.state_save_file', or create a new git repo if
-- there is none.
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
74
save :: Cmd.CmdT IO ()
make git checkpointing save window configuration properly qdunkan@gmail.com Fri Apr 12 02:43:02 UTC 2013
75
save = Cmd.gets Cmd.state_save_file >>= \x -> case x of
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
76
    Nothing -> save_git
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
77
78
79
80
    -- Try to override Cmd.Writable on an explicit save.  If it's still
    -- read only, this should throw an exception.
    Just (_, Cmd.SaveRepo repo) -> save_git_as repo
    Just (_, Cmd.SaveState fn) -> save_state_as fn
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
82
83
84
85
86
87
-- | Like 'read', but replace the current state and set 'Cmd.state_save_file'.
load :: FilePath -> Cmd.CmdT IO ()
load path = do
    (state, save_file) <- read path
    set_state save_file True state
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
88
89
-- | Try to guess whether the given path is a git save or state save.  If it's
-- a directory, look inside for a .git or .state save.
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
90
read :: FilePath -> Cmd.CmdT IO (Ui.State, StateSaveFile)
add verify_performance command, to check a saved score against its last saved performance qdunkan@gmail.com Tue Feb 4 03:43:25 UTC 2014
91
read path = do
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
92
    path <- expand_filename path
add verify_performance command, to check a saved score against its last saved performance qdunkan@gmail.com Tue Feb 4 03:43:25 UTC 2014
93
94
    save <- Cmd.require_right ("read: "<>) =<< liftIO (infer_save_type path)
    case save of
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
95
        Cmd.SaveRepo repo -> read_git repo Nothing
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
96
        Cmd.SaveState fn -> read_state fn
add verify_performance command, to check a saved score against its last saved performance qdunkan@gmail.com Tue Feb 4 03:43:25 UTC 2014
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
98
-- | Low level 'read'.
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
99
read_ :: Cmd.InstrumentDb -> FilePath -> IO (Either Text Ui.State)
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
100
101
102
103
104
105
106
read_ db path = infer_save_type path >>= \case
    Left err -> return $ Left $ "read " <> showt path <> ": " <> err
    Right save -> case save of
        Cmd.SaveState fname -> first pretty <$> read_state_ db fname
        Cmd.SaveRepo repo -> fmap extract <$> read_git_ db repo Nothing
            where extract (state, _, _) = state
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
107
108
-- | Like 'load', but don't set SaveFile, so you can't overwrite the loaded
-- file when you save.
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
109
110
111
load_template :: FilePath -> Cmd.CmdT IO ()
load_template fn = do
    (state, _) <- read fn
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
112
    set_state Nothing True state
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
113
    now <- liftIO $ Time.getCurrentTime
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
114
    Ui.modify_config $ Ui.meta#Ui.creation #= now
add verify_performance command, to check a saved score against its last saved performance qdunkan@gmail.com Tue Feb 4 03:43:25 UTC 2014
115
116
117
118
119

-- | Given a path, which is either a file or a directory, try to figure out
-- what to load.  Saves can be either a plain saved state, or a directory
-- containing either a git repo @save.git@, or a state @save.state@.  If
-- both are present, the git repo is preferred.
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
120
infer_save_type :: FilePath -> IO (Either Text Cmd.SaveFile)
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
121
infer_save_type path = fmap prepend $ cond
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
122
    [ (return $ SaveGit.is_git path, ok $ Cmd.SaveRepo path)
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
123
    , (is_dir path, cond
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
124
125
        [ (is_dir git_fn, ok $ Cmd.SaveRepo git_fn)
        , (is_file state_fn, ok $ Cmd.SaveState state_fn)
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
126
127
        ] $ return $ Left $ "directory contains neither " <> txt git_fn
            <> " nor " <> txt state_fn)
move load_template to Cmd.Save, and make it keep a filename Evan Laforge <qdunkan@gmail.com> Fri Sep 12 03:44:35 UTC 2014
128
    , (is_file path, ok $ Cmd.SaveState path)
remove .gz suffix from saved states qdunkan@gmail.com Fri Feb 7 09:05:34 UTC 2014
129
    ] $ return $ Left "file not found"
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
130
    where
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
131
    prepend (Left err) = Left $ txt path <> ": " <> err
add verify_performance command, to check a saved score against its last saved performance qdunkan@gmail.com Tue Feb 4 03:43:25 UTC 2014
132
133
134
135
136
137
    prepend (Right val) = Right val
    ok = return . Right
    git_fn = path </> default_git
    state_fn = path </> default_state
    is_dir = Directory.doesDirectoryExist
    is_file = Directory.doesFileExist
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
139
140
141
142
143
144
145
146
147
148
-- | Like guard cases but with monadic conditions.
cond :: Monad m => [(m Bool, m a)] -> m a -> m a
cond [] consequent = consequent
cond ((condition, result) : rest) consequent =
    ifM condition result (cond rest consequent)

-- * expand path

-- | Expand `-delimited macros to make a filepath.
expand_filename :: FilePath -> Cmd.CmdT IO FilePath
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
149
expand_filename = fmap untxt . TextUtil.mapDelimitedM False '`' expand . txt
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
150
    where
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
151
152
    expand text = case lookup text filename_macros of
        Just get -> get
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
153
        Nothing -> Cmd.throw $ "unknown macro " <> showt text
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
154
            <> ", known macros are: "
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
155
            <> Text.intercalate ", " (map fst filename_macros)
throw an error on an unknown macro, instead of creating a file with backticks in it Evan Laforge <qdunkan@gmail.com> Mon Dec 29 10:23:02 UTC 2014
156
157
158
159
160
161
162
163
164

filename_macros :: [(Text, Cmd.CmdT IO Text)]
filename_macros =
    [ ("y-m-d", liftIO date)
    , ("d", do
        dir <- Cmd.require "`d` requires a save dir"
            =<< Cmd.gets Cmd.state_save_dir
        return $ txt dir)
    ]
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
165
166
167
168
169

date :: IO Text
date = do
    tz <- Time.getCurrentTimeZone
    today <- Time.utcToLocalTime tz <$> Time.getCurrentTime
quarantine compatibility cpp to Util.Locale qdunkan@gmail.com Sat Oct 10 02:27:24 UTC 2015
170
    return $ txt $ Time.formatTime Locale.defaultTimeLocale "%y-%m-%d" today
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
incremental save: make loading from a git repo and then undoing actually work qdunkan@gmail.com Tue May 8 14:45:30 UTC 2012
172
173
-- * plain serialize
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
174
save_state :: Cmd.CmdT IO ()
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
175
176
save_state = save_state_as =<< Cmd.require "can't save, no save file"
    =<< get_state_path
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
178
-- | Save the state to the given file and set 'Cmd.state_save_file'.
add a trill call that just applies attributes, and make the note call configurable to ignore +staccato qdunkan@gmail.com Thu Jan 24 04:05:58 UTC 2013
179
180
181
--
-- The directory of the filename will become the project directory, so things
-- like the saved REPL history and the ly subdirectory will go there.
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
182
183
save_state_as :: FilePath -> Cmd.CmdT IO ()
save_state_as fname = do
fix bug where the SaveFile would get the unexpanded filename Evan Laforge <qdunkan@gmail.com> Fri Nov 28 09:51:29 UTC 2014
184
    fname <- write_current_state fname
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
185
    set_save_file (Just (Cmd.ReadWrite, SaveState fname)) False
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
fix bug where the SaveFile would get the unexpanded filename Evan Laforge <qdunkan@gmail.com> Fri Nov 28 09:51:29 UTC 2014
187
write_current_state :: FilePath -> Cmd.CmdT IO FilePath
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
188
write_current_state fname = do
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
189
    fname <- expand_filename fname
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
190
    state <- Ui.get
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
191
192
    ((), _, wall_secs) <- rethrow_io "write_current_state" $ liftIO $
        Log.time_eval $ write_state fname state
im: don't run im synths if the note files haven't changed qdunkan@gmail.com Tue Nov 7 20:03:25 UTC 2017
193
194
    Log.notice $ "wrote state to " <> showt fname <> ", took "
        <> pretty wall_secs <> "s"
fix bug where the SaveFile would get the unexpanded filename Evan Laforge <qdunkan@gmail.com> Fri Nov 28 09:51:29 UTC 2014
195
    return fname
initial save and load using read/show qdunkan@gmail.com Fri May 2 23:43:52 UTC 2008
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
197
write_state :: FilePath -> Ui.State -> IO ()
add Ui.StateConfig.meta_last_save field Evan Laforge <qdunkan@gmail.com> Wed Aug 20 03:08:58 UTC 2014
198
199
write_state fname state = do
    now <- Time.getCurrentTime
im: don't run im synths if the note files haven't changed qdunkan@gmail.com Tue Nov 7 20:03:25 UTC 2017
200
    void $ Serialize.serialize Cmd.Serialize.score_magic fname $
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
201
202
        Ui.config#Ui.meta#Ui.last_save #= now $
        Ui.clear state
remove backward compatibility for saved scores qdunkan@gmail.com Sat Jun 1 03:58:09 UTC 2013
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
204
205
206
load_state :: FilePath -> Cmd.CmdT IO ()
load_state fname = do
    (state, save_file) <- read_state fname
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
207
    set_state save_file True state
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
209
read_state :: FilePath -> Cmd.CmdT IO (Ui.State, StateSaveFile)
remove .gz suffix from saved states qdunkan@gmail.com Fri Feb 7 09:05:34 UTC 2014
210
read_state fname = do
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
211
    let mkmsg err = "load " <> txt fname <> ": " <> pretty err
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
212
    writable <- liftIO $ File.writable fname
convert Log functions from String to Text Evan Laforge <qdunkan@gmail.com> Fri Aug 22 05:49:30 UTC 2014
213
    Log.notice $ "read state from " <> showt fname
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
214
        <> if writable then "" else " (ro)"
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
215
216
    db <- Cmd.gets $ Cmd.config_instrument_db . Cmd.state_config
    state <- Cmd.require_right mkmsg =<< liftIO (read_state_ db fname)
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
217
218
    return (state, Just
        (if writable then Cmd.ReadWrite else Cmd.ReadOnly, SaveState fname))
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
220
221
-- | Low level 'read_state'.
read_state_ :: Cmd.InstrumentDb -> FilePath
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
222
    -> IO (Either Serialize.UnserializeError Ui.State)
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
223
224
225
226
227
228
229
230
read_state_ db fname =
    Serialize.unserialize Cmd.Serialize.score_magic fname >>= \case
        Right state -> mapM_ Log.write logs >> return (Right upgraded)
            where (upgraded, logs) = upgrade_state db state
        Left err -> return $ Left err

-- | Low level 'read_git'.
read_git_ :: Cmd.InstrumentDb -> SaveGit.Repo -> Maybe SaveGit.Commit
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
231
    -> IO (Either Text (Ui.State, SaveGit.Commit, [Text]))
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
232
233
234
235
236
237
238
239
240
241
read_git_ db repo maybe_commit = SaveGit.load repo maybe_commit >>= \case
    Right (state, commit, names) -> do
        mapM_ Log.write logs
        return $ Right (upgraded, commit, names)
        where (upgraded, logs) = upgrade_state db state
    Left err -> return $ Left err


-- * upgrade
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
242
upgrade_state :: Cmd.InstrumentDb -> Ui.State -> (Ui.State, [Log.Msg])
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
243
244
245
246
247
248
249
250
251
252
253
upgrade_state db state = Identity.runIdentity $ Log.run $ do
    upgraded <- forM allocs $ \alloc -> if is_old alloc
        then case upgrade_allocation db alloc of
            Left err -> do
                Log.warn $ "upgrading " <> pretty alloc <> ": " <> err
                return alloc
            Right new -> do
                Log.warn $ "upgraded old alloc: " <> pretty alloc
                    <> " to: " <> pretty (alloc_settings new)
                return new
        else return alloc
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
254
255
    return $ Ui.config#UiConfig.allocations
        #= UiConfig.Allocations upgraded $ state
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
256
    where
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
257
    UiConfig.Allocations allocs = Ui.config#Ui.allocations #$ state
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
258
    is_old = maybe False (Cmd.Serialize.is_old_settings . Patch.config_settings)
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
259
        . UiConfig.midi_config . UiConfig.alloc_backend
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
261
262
263
alloc_settings :: UiConfig.Allocation -> Maybe Patch.Settings
alloc_settings = fmap Patch.config_settings . UiConfig.midi_config
    . UiConfig.alloc_backend
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
265
266
upgrade_allocation :: Cmd.InstrumentDb -> UiConfig.Allocation
    -> Either Text UiConfig.Allocation
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
267
upgrade_allocation db alloc =
rename Ui.StateConfig to Ui.UiConfig, and Ui.StateLog to Ui.UiLog qdunkan@gmail.com Thu Jan 5 08:24:08 UTC 2017
268
    case Inst.lookup (UiConfig.alloc_qualified alloc) db of
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
269
270
271
        Just inst -> MidiInst.merge_defaults inst alloc
        Nothing -> Left "no inst for alloc"
remove backward compatibility for saved scores qdunkan@gmail.com Sat Jun 1 03:58:09 UTC 2013
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
273
-- ** path
incremental save: make loading from a git repo and then undoing actually work qdunkan@gmail.com Tue May 8 14:45:30 UTC 2012
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
275
get_state_path :: Cmd.M m => m (Maybe FilePath)
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
276
get_state_path = do
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
277
    state <- Cmd.get
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
278
    return $ make_state_path . snd <$> Cmd.state_save_file state
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
280
281
282
283
284
285
286
287
288
289
290
291
292
make_state_path :: Cmd.SaveFile -> FilePath
make_state_path (Cmd.SaveState fn) = fn
make_state_path (Cmd.SaveRepo repo) = state_path_for_repo repo

-- | Get a state save path based on a repo path.  This is for saving a backup
-- state, or when switching from SaveRepo to SaveState.
state_path_for_repo :: SaveGit.Repo -> FilePath
state_path_for_repo repo = FilePath.replaceExtension repo ".state"

-- | Figure out a path for a save state based on the namespace.
infer_state_path :: Id.Namespace -> Cmd.State -> FilePath
infer_state_path ns state =
    Cmd.path state Config.save_dir </> untxt (Id.un_namespace ns)
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
293
        </> default_state
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
295
296
297
298
default_state :: FilePath
default_state = "save.state"

-- * git serialize
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
add Cmd.Lang.Global.save_state and save_git, and fix SaveGit.save to create new repos properly qdunkan@gmail.com Sun Jan 13 23:51:43 UTC 2013
300
-- | Save a SavePoint to the git repo in 'Cmd.state_save_file', or start a new
make Cmd.Save.cmd_save_git also set the Cmd.state_save_file qdunkan@gmail.com Wed Jan 16 05:41:19 UTC 2013
301
302
-- one.  Set the 'Cmd.state_save_file' to the repo, so I'll keep saving to
-- that repo.
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
303
304
305
save_git :: Cmd.CmdT IO ()
save_git = save_git_as =<< get_git_path
when saving to git, automatically add .git suffix if it doesn't already have one qdunkan@gmail.com Sat Oct 10 04:38:32 UTC 2015
306
save_git_as :: SaveGit.Repo -- ^ Save to this repo, or create it.
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
307
    -- 'Cmd.Undo.maintain_history' will start checkpointing to it.
when saving to git, automatically add .git suffix if it doesn't already have one qdunkan@gmail.com Sat Oct 10 04:38:32 UTC 2015
308
    -- @.git@ is appended if it doesn't already have that suffix.
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
309
    -> Cmd.CmdT IO ()
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
310
save_git_as repo = do
call expand_filename call at lower level load and save functions in Cmd.Save Evan Laforge <qdunkan@gmail.com> Wed Nov 19 07:09:36 UTC 2014
311
    repo <- expand_filename repo
when saving to git, automatically add .git suffix if it doesn't already have one qdunkan@gmail.com Sat Oct 10 04:38:32 UTC 2015
312
313
    repo <- return $ if SaveGit.git_suffix `List.isSuffixOf` repo then repo
        else repo ++ SaveGit.git_suffix
incremental save: branch the repo properly after an undo followed by changes qdunkan@gmail.com Wed May 16 05:23:09 UTC 2012
314
    cmd_state <- Cmd.get
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
315
    let rethrow = Cmd.require_right (("save git " <> txt repo <> ": ") <>)
undo: git save only makes a save tag, it doesn't resave the entire state from scratch qdunkan@gmail.com Tue Apr 16 15:29:08 UTC 2013
316
317
318
    commit <- case Cmd.hist_last_commit $ Cmd.state_history_config cmd_state of
        Just commit -> return commit
        Nothing -> do
use git's user.name and user.email instead of just hardcoding mine qdunkan@gmail.com Thu Feb 16 03:59:42 UTC 2017
319
            let user = Cmd.config_git_user $ Cmd.state_config cmd_state
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
320
            state <- Ui.get
use git's user.name and user.email instead of just hardcoding mine qdunkan@gmail.com Thu Feb 16 03:59:42 UTC 2017
321
            rethrow =<< liftIO (SaveGit.checkpoint user repo
remove Util.Git dependency from tests qdunkan@gmail.com Sat May 23 02:07:05 UTC 2015
322
                (SaveGitTypes.SaveHistory state Nothing [] ["save"]))
undo: git save only makes a save tag, it doesn't resave the entire state from scratch qdunkan@gmail.com Tue Apr 16 15:29:08 UTC 2013
323
    save <- rethrow =<< liftIO (SaveGit.set_save_tag repo commit)
convert Log functions from String to Text Evan Laforge <qdunkan@gmail.com> Fri Aug 22 05:49:30 UTC 2014
324
    Log.notice $ "wrote save " <> showt save <> " to " <> showt repo
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
325
    set_save_file (Just (Cmd.ReadWrite, SaveRepo repo commit Nothing)) False
fix bug where old git oids stuck around after switching repos qdunkan@gmail.com Mon Jan 14 08:05:39 UTC 2013
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
327
328
load_git :: FilePath -> Maybe SaveGit.Commit -> Cmd.CmdT IO ()
load_git repo maybe_commit = do
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
329
330
331
332
    (state, save_file) <- read_git repo maybe_commit
    set_state save_file True state

read_git :: FilePath -> Maybe SaveGit.Commit
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
333
    -> Cmd.CmdT IO (Ui.State, StateSaveFile)
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
334
read_git repo maybe_commit = do
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
335
    db <- Cmd.gets $ Cmd.config_instrument_db . Cmd.state_config
incremental save: set Cmd.hist_last_save when loading a state qdunkan@gmail.com Thu May 10 05:50:24 UTC 2012
336
    (state, commit, names) <- Cmd.require_right
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
337
        (("load git " <> txt repo <> ": ") <>)
make various MIDI instrument settings configurable per-score qdunkan@gmail.com Sat Oct 1 04:30:47 UTC 2016
338
        =<< liftIO (read_git_ db repo maybe_commit)
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
339
    writable <- liftIO $ File.writable repo
rename Pretty.pretty to prettys and prettyt to pretty Evan Laforge <qdunkan@gmail.com> Fri Feb 6 10:07:34 UTC 2015
340
    Log.notice $ "read from " <> showt repo <> ", at " <> pretty commit
convert Log functions from String to Text Evan Laforge <qdunkan@gmail.com> Fri Aug 22 05:49:30 UTC 2014
341
        <> " names: " <> showt names
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
342
343
344
        <> if writable then "" else " (read-only, not setting save file)"
    return (state, Just (if writable then Cmd.ReadWrite else Cmd.ReadOnly,
        SaveRepo repo commit (Just names)))
incremental save: make loading from a git repo and then undoing actually work qdunkan@gmail.com Tue May 8 14:45:30 UTC 2012
add cmd to revert to last save point qdunkan@gmail.com Mon May 14 01:43:54 UTC 2012
346
-- | Revert to given save point, or the last one.
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
347
348
revert :: Maybe String -> Cmd.CmdT IO ()
revert maybe_ref = do
make various 'require' functions have consistent signatures qdunkan@gmail.com Sat Feb 22 18:37:19 UTC 2014
349
    save_file <- Cmd.require "can't revert when there is no save file"
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
350
351
        =<< Cmd.gets Cmd.state_save_file
    case save_file of
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
352
        (_, Cmd.SaveState fn) -> do
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
353
354
355
            whenJust maybe_ref $ \ref -> Cmd.throw $
                "can't revert to a commit when the save file isn't git: "
                <> txt ref
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
356
            load fn
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
357
        (_, Cmd.SaveRepo repo) -> revert_git repo
convert Log functions from String to Text Evan Laforge <qdunkan@gmail.com> Fri Aug 22 05:49:30 UTC 2014
358
    Log.notice $ "revert to " <> showt save_file
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
359
360
361
    where
    revert_git repo = do
        save <- case maybe_ref of
make various 'require' functions have consistent signatures qdunkan@gmail.com Sat Feb 22 18:37:19 UTC 2014
362
            Nothing -> fmap fst $ Cmd.require "no last save"
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
363
                =<< liftIO (SaveGit.read_last_save repo Nothing)
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
364
            Just ref -> Cmd.require ("unparseable SavePoint: " <> showt ref)
store the current save file in Cmd.State rather than State.State qdunkan@gmail.com Sun Jan 13 18:27:23 UTC 2013
365
                (SaveGit.ref_to_save ref)
convert Ui.State.Error from String to Text Evan Laforge <qdunkan@gmail.com> Sat Feb 7 03:23:14 UTC 2015
366
        commit <- Cmd.require ("save ref not found: " <> showt save)
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
367
            =<< rethrow_git "revert" (SaveGit.read_save_ref repo save)
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
368
        load_git repo (Just commit)
add cmd to revert to last save point qdunkan@gmail.com Mon May 14 01:43:54 UTC 2012
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
370
371
372
373
374
375
376
rethrow_git :: Text -> IO a -> Cmd.CmdT IO a
rethrow_git caller io = Cmd.require_right id =<< liftIO (SaveGit.try caller io)

rethrow_io :: Text -> IO a -> Cmd.CmdT IO a
rethrow_io caller io = Cmd.require_right
    (\exc -> caller <> ": " <> showt (exc :: Exception.IOException))
        =<< liftIO (Exception.try io)
add cmd to revert to last save point qdunkan@gmail.com Mon May 14 01:43:54 UTC 2012
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
378
379
-- ** path
remove redundant parens Evan Laforge <qdunkan@gmail.com> Sat Jul 26 07:51:48 UTC 2014
380
get_git_path :: Cmd.M m => m Git.Repo
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
381
get_git_path = do
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
382
    ns <- Ui.get_namespace
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
383
384
385
386
387
    state <- Cmd.get
    return $ make_git_path ns state

make_git_path :: Id.Namespace -> Cmd.State -> Git.Repo
make_git_path ns state = case Cmd.state_save_file state of
convert various Ui.Id functions from String to Text qdunkan@gmail.com Wed Mar 12 06:25:24 UTC 2014
388
    Nothing -> Cmd.path state Config.save_dir </> untxt (Id.un_namespace ns)
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
389
        </> default_git
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
390
391
392
    Just (_, Cmd.SaveState fn) ->
        FilePath.replaceExtension fn SaveGit.git_suffix
    Just (_, Cmd.SaveRepo repo) -> repo
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
393
394

default_git :: FilePath
when saving to git, automatically add .git suffix if it doesn't already have one qdunkan@gmail.com Sat Oct 10 04:38:32 UTC 2015
395
default_git = "save" ++ SaveGit.git_suffix
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
save aliases along with midi config, and export save and load from LInst qdunkan@gmail.com Mon Jun 9 06:15:27 UTC 2014
397
398
-- * config
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
399
400
save_allocations :: FilePath -> Cmd.CmdT IO ()
save_allocations fname = do
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
401
    allocs <- Ui.config#Ui.allocations <#> Ui.get
expand filename macros when saving and loading midi configs Evan Laforge <qdunkan@gmail.com> Sun Feb 8 05:37:27 UTC 2015
402
    fname <- expand_filename fname
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
403
    Log.notice $ "write instrument allocations to " <> showt fname
im: don't run im synths if the note files haven't changed qdunkan@gmail.com Tue Nov 7 20:03:25 UTC 2017
404
    rethrow_io "save_allocations" $ liftIO $ void $
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
405
        Serialize.serialize Cmd.Serialize.allocations_magic fname allocs
save aliases along with midi config, and export save and load from LInst qdunkan@gmail.com Mon Jun 9 06:15:27 UTC 2014
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
407
408
load_allocations :: FilePath -> Cmd.CmdT IO ()
load_allocations fname = do
expand filename macros when saving and loading midi configs Evan Laforge <qdunkan@gmail.com> Sun Feb 8 05:37:27 UTC 2015
409
    fname <- expand_filename fname
unify Ui.StateConfig.config_midi into config_allocations qdunkan@gmail.com Fri Feb 12 14:28:58 UTC 2016
410
411
412
413
414
    Log.notice $ "load instrument allocations from " <> showt fname
    let mkmsg err = "unserializing instrument allocations " <> showt fname
            <> ": " <> pretty err
    allocs <- Cmd.require_right mkmsg
        =<< liftIO (Serialize.unserialize Cmd.Serialize.allocations_magic fname)
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
415
    Ui.modify_config $ Ui.allocations #= allocs
save aliases along with midi config, and export save and load from LInst qdunkan@gmail.com Mon Jun 9 06:15:27 UTC 2014
incremental save: make loading from a git repo and then undoing actually work qdunkan@gmail.com Tue May 8 14:45:30 UTC 2012
417
-- * misc
replace block derivers with schema/skeleton structure qdunkan@gmail.com Sun May 25 17:54:47 UTC 2008
make git checkpointing save window configuration properly qdunkan@gmail.com Fri Apr 12 02:43:02 UTC 2013
419
420
421
422
423
424
425
426
427
-- | Git repos don't checkpoint views, but because I'm accustomed to them
-- checkpointing everything else I expect the views to always be saved.
--
-- So call this when quitting or switching away from a save file to save the
-- views.
--
-- They could theoretically checkpoint view changes, but it would be
-- complicated (they mostly come from the GUI, not diff) and inefficient
-- (scrolling emits tons of them).
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
428
save_views :: Cmd.State -> Ui.State -> IO ()
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
429
save_views cmd_state ui_state = case Cmd.state_save_file cmd_state of
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
430
    Just (Cmd.ReadWrite, Cmd.SaveRepo repo) ->
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
431
        SaveGit.save_views repo $ Ui.state_views ui_state
make git checkpointing save window configuration properly qdunkan@gmail.com Fri Apr 12 02:43:02 UTC 2013
432
    _ -> return ()
undo: remove Cmd.hist_last_save and simplify the logic that decides whether to save a checkpoint qdunkan@gmail.com Thu Apr 11 23:42:19 UTC 2013
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
434
435
436
437
438
-- | This is just like 'Cmd.SaveFile', except SaveRepo has more data.
data SaveFile =
    SaveState !FilePath
    -- | The Strings are the cmd name of this commit, and only set on a git
    -- load.
convert Log functions from String to Text Evan Laforge <qdunkan@gmail.com> Fri Aug 22 05:49:30 UTC 2014
439
    | SaveRepo !SaveGit.Repo !SaveGit.Commit !(Maybe [Text])
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
440
    deriving (Show)
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
441
type StateSaveFile = Maybe (Cmd.Writable, SaveFile)
be a bit more consistent about always clearing the history when I set SaveFile qdunkan@gmail.com Tue Apr 16 03:25:21 UTC 2013
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
443
444
445
446
447
448
-- | If I switch away from a repo (either to another repo or to a plain state),
-- I have to clear out all the remains of the old repo, since its Commits are
-- no longer valid.
--
-- It's really important to call this whenever you change
-- 'Cmd.state_save_file'!
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
449
set_save_file :: StateSaveFile -> Bool -> Cmd.CmdT IO ()
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
450
set_save_file save_file clear_history = do
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
451
    cmd_state <- Cmd.get
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
452
    when (file /= Cmd.state_save_file cmd_state) $ do
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
453
        ui_state <- Ui.get
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
454
455
        liftIO $ save_views cmd_state ui_state
        Cmd.modify $ \state -> state
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
456
            { Cmd.state_save_file = file
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
457
458
459
460
            , Cmd.state_history = let hist = Cmd.state_history state in hist
                { Cmd.hist_past = if clear_history then []
                    else map clear (Cmd.hist_past hist)
                , Cmd.hist_present = (Cmd.hist_present hist)
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
461
                    { Cmd.hist_commit = maybe_commit }
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
462
463
464
                , Cmd.hist_future = []
                }
            , Cmd.state_history_config = (Cmd.state_history_config state)
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
465
                { Cmd.hist_last_commit = maybe_commit }
fix bug where saving to a new file wouldn't save the views of the old one qdunkan@gmail.com Sat Apr 20 05:51:19 UTC 2013
466
            }
add an indicator that shows when the score is unsaved qdunkan@gmail.com Thu Oct 8 03:51:24 UTC 2015
467
468
469
    -- This is called both when saving and loading, so it's a good place to
    -- mark that the state is synced to disk.
    Cmd.modify $ \st -> st { Cmd.state_saved = Nothing }
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
470
    where
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
471
    (maybe_commit, file) = case save_file of
add features to support read-only scores qdunkan@gmail.com Sat Oct 10 02:28:02 UTC 2015
472
        Nothing -> (Nothing, Nothing)
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
473
474
475
476
        Just (writable, save) -> case save of
            SaveState fname -> (Nothing, Just (writable, Cmd.SaveState fname))
            SaveRepo repo commit _ ->
                (Just commit, Just (writable, Cmd.SaveRepo repo))
fix bug where switching from checkpointing to a repo to a plain state wouldn't clear out the repo state qdunkan@gmail.com Tue Jan 22 05:43:24 UTC 2013
477
478
    clear entry = entry { Cmd.hist_commit = Nothing }
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
479
set_state :: StateSaveFile -> Bool -> Ui.State -> Cmd.CmdT IO ()
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
480
481
set_state save_file clear_history state = do
    set_save_file save_file clear_history
fix bug where play doesnt stop, I think, by removing unused block_id from Transport.Status qdunkan@gmail.com Sat Jul 30 23:14:37 UTC 2011
482
    Play.cmd_stop
fix bug where undo on an uncommitted score didn't work qdunkan@gmail.com Fri May 18 05:09:47 UTC 2012
483
    Cmd.modify $ Cmd.reinit_state (Cmd.empty_history_entry state)
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
484
485
486
    -- Names is only set on a git load.  This will cause "Cmd.Undo" to clear
    -- out the history.
    case save_file of
keep track of ReadOnly save file status instead of just not having a SaveFile qdunkan@gmail.com Sat Oct 17 00:56:34 UTC 2015
487
        Just (_, SaveRepo _ commit (Just names)) -> Cmd.modify $ \st -> st
add Cmd.Repl.LState.load_merge qdunkan@gmail.com Wed Jun 12 05:21:30 UTC 2013
488
489
490
491
            { Cmd.state_history = (Cmd.state_history st)
                { Cmd.hist_last_cmd = Just $ Cmd.Load (Just commit) names }
            }
        _ -> return ()
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
492
493
    old <- Ui.get
    Ui.put $ Ui.clear $
keep the old clip namespace around when loading a new score Evan Laforge <qdunkan@gmail.com> Tue Dec 2 05:00:14 UTC 2014
494
        Transform.replace_namespace Config.clip_namespace old state
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
495
    root <- case Ui.config_root (Ui.state_config state) of
fix bug where a newly loaded state doesn't get the right focus qdunkan@gmail.com Sat Jul 30 23:50:31 UTC 2011
496
        Nothing -> return Nothing
rename Ui.State to Ui.Ui qdunkan@gmail.com Thu Jan 5 06:48:14 UTC 2017
497
498
        Just root -> Seq.head . Map.keys <$> Ui.views_of root
    let focused = msum [root, Seq.head $ Map.keys (Ui.state_views state)]
add ViewConfig.cycle_focus and bind keys to it qdunkan@gmail.com Tue Dec 29 03:04:32 UTC 2015
499
    whenJust focused Cmd.focus