SuperCollider CLASSES


keeps a history of interpreted lines of code
Inherits from: Object


History keeps track of all code lines that are being executed, in order to forward them to other players, to easily reuse earlier versions, or to store and reproduce a performance. Since it records everything that is interpreted, there is only one privileged instance of History - History.current. (adc 2006/7)

Class Methods


start adding interpreted code to (current) history.


end adding interpreted code to (current) history.


remove all items from (current) history.

*enter (lineStr, id: 'me')

add an entry by hand.


post the history in a new document (as story).

*makeWin (where, numItems: 8)

make a HistoryGui for History.current, at the point given, with the given textHeight.


*keepsLog = value

get and set flag whether to log History to a file.


*verbose = value

get and set flag whether to post debug messages from History operations.

*drop (num)

drop the newest n lines from history. if n is negative, drop the oldest n lines.

*keep (num)

keep only the newest n lines from history. if n is negative, keep the oldest n lines.

*saveCS (path, forward: false)

store history as one compileString.

*loadCS (path, forward: false)

load a history from (compilestring) file.

*saveStory (path)

store in a file, in historical order as individual code snippets.

*loadStory (path)

read history into current, from a file in story format.

*play (start: 0, end, verbose: true)

play back current history from start to end line, per default verbose.


stop current history playback.

*rewrite (path, open: true)

Write a properly formatted code file from a history.



The filename is the original name with "_rewritten." appended.


If open is true (default: true), open a text window with the string.

More internal methods:


*current = value

the current History instance



the currently recorded lines in History.current.

lineShorts is a copy with shortened strings for display.

*new (lines)

create a new instance.

Inherited class methods

Undocumented class methods

*checkPath (path)

*formatTime (val)


*forwardFunc = value




*prettyString (str)

*readFromDoc (path)


*recordLocally = value

*removeAt (index)


*shorten (line, maxLength)





*unformatTime (str)

Instance Methods

Inherited instance methods

Undocumented instance methods

-addLine (now, authID, lineStr)


-document (title: "")

-drop (num)


-hasMovedOn = flag: true

-indicesFor (keys, string: "")


-keep (num)




-lines = inLines

-loadCS (path, forward: false)

-loadStory (path)


-makeWin (where, numItems: 8)

-matchKeys (key)

-matchString (str, ignoreCase: true)

-play (start: 0, end, verbose: true)


-removeAt (index)


-saveCS (path, forward: false)

-saveStory (path)




History.clear.end;        // clear to start over
History.start;             // starts recording, opens log file

                // execute these lines one by one
1 + 2;
p = ProxySpace.push(s.boot);
~a = {[1,1] * 30 ) * 0.3 }; //;

History.end;        // History.end ends logging as well.

History.document; // create a document with all the changes
History.showLogFile; // open the log file as it was written.

g = History.makeWin(0@20); // make a gui window, put it where you like
g = History.makeWin(0@20, 5); // lines to see in textview;            // posts lines by default; false);    // just do it, no posting;

    // continue recording

10 + 200;            // enter 5 more lines
~b = { |freq=500| * 0.2 };;
~b.set(\freq, 1000);


    // save current history to a file.
h ="~/Desktop/TestHist.scd");
h.lines.printcsAll; "";

    // under the hood: History.someCommand goes to History.current:

    // History.current is where new codelines always go.
h = History.current;
h.lines.printcsAll; "";
h.lineShorts.printcsAll; "";    // lineshorts are for gui display

History.enter("2 + 2");        // make a simple entry by hand.
h.lines.printcsAll; "";

        // one can edit a history:

History.drop(-1); // drop the oldest memory
History.drop(1); // drop the newest memory

h.keep(9);         h.lines.printAll; "";
h.drop(3);         h.lines.printAll; "";
h.removeLast;        h.lines.printAll;"";
h.removeAt([3, 4]);    h.lines.printAll;"";

// more examples

1 + 2;            // code lines get stored

(nil + 2).postln;    // error lines are ignored

    // comment-only line is kept, empty lines not:

    // save and load as text files

History.saveCS; // save as compilestring for reloading.
            // save with name, in forward time order.
History.saveCS("~/Desktop/testHist.scd", forward: true);
            // load back in from file
h ="~/Desktop/testHist.scd", forward: true);
h.lines.postcs; "";

    // save as human-readable/hand-playable story
History.saveStory        // write all to time-stamped file in historical order
History.saveStory("~/Desktop/myTestStory.scd");    // ... with given filename.
History.loadStory("~/Desktop/myTestStory.scd");    // load from story format file"~/Desktop/myTestStory.scd");    // the story file is human-readable.

    // Various Internals
    // make a new instance of History by hand:
h = History([[0, \me, "1+2"], [1.234, \me, "q = q ? ();"], [3, \me, "\"History\".postln"]]);
h.lines.printcsAll; "";
h.lineShorts.printcsAll; "";;    // play it

    // string formatting utils
/* removes line returns at start and end of code strings ... */

)    // convert a line to a short string of n characters for gui display
History.shorten(h.lines.first.postcs, 60).postcs;

    // in networked setups, one may turn off local recording and rely on remote recording:

    // by default, history always logs here (and makes the folder if not there yet):
History.showLogFile;    // current logfile...
    // todo: optionally, one should be able to turn logging off?

    // filtering lines, to get subsets of all lines by key and/or searchstring:

    // get indices for specific keys
h = History([[0, \me, "a=1+2"], [1, \me, "3+5"], [1.234, \you, "q = q ? ();"], [3, \her, "\"Herstory ==== \".postln"]]);
h.matchKeys;         // nil if no test
h.matchKeys(\all);     // all keys match
h.matchKeys([\me, \her])
h.matchKeys(\isidor)    // empty array if no line found

h.matchString("herStory", false); // ignoreCase is false by default
h.matchString("herStory", true); // ignoreCase

h.indicesFor([\me, \her], "=");    // indices for line written by \me or \her AND containing "=";

    // searching is only an interface/access feature,
    // so please read on at HistoryGui help ...