576 lines
17 KiB
Text
576 lines
17 KiB
Text
|
class:: Document
|
||
|
redirect:: implementationClass
|
||
|
summary:: Editor-specific text document editing
|
||
|
categories:: Frontends
|
||
|
related:: Classes/EmacsDocument, Classes/ScelDocument
|
||
|
|
||
|
description::
|
||
|
The Document class represents a text document within the context of your text editing environment. You can use the class to programmatically create, modify, and query these documents.
|
||
|
|
||
|
Document used to be an abstract class, meaning it didn't provide all the functionality itself, but instead relied on subclasses to complete the functionality. One such subclass was CocoaDocument. Although CocoaDocument was available only to macOS and had an ad hoc interface, it possessed many additional features like code animation and rich text.
|
||
|
|
||
|
In SuperCollider 3.6, Document changed a bit and now the "abstract class" descriptor is only partially true. The SuperCollider IDE provides its own version of the Document class. The Emacs editor still supplies link::Classes/ScelDocument:: (which links to link::Classes/EmacsDocument::) as a subclass of Document. As an unfortunate byproduct of the history of Document, there are inconsistencies in the APIs of SCIDE's Document and Emacs' ScelDocument. This help file describes that of SCIDE.
|
||
|
|
||
|
Future versions of SuperCollider will aim to fix these API inconsistencies and restore the functionality of CocoaDocument.
|
||
|
|
||
|
subsection:: Setting the Environment
|
||
|
|
||
|
By default code::envir:: it is set to the current link::Classes/Environment::. However, you can make it use its own link::Classes/Environment:: also. Thus, e.g., if you were to set the link::Classes/Environment:: variable code::~myVar = 12:: in the current link::Classes/Environment::, you can create a new Document window in which that link::Classes/Environment:: variable is not set.
|
||
|
|
||
|
classmethods::
|
||
|
|
||
|
private:: prGetLast, prSetSyntaxColorTheme, prnumberOfOpen, prBasicNew, prGetIndexOfListener, prDefaultUsesAutoInOutdent, initClass
|
||
|
|
||
|
method:: new
|
||
|
argument:: title
|
||
|
An instance of link::Classes/String:: or link::Classes/Symbol::.
|
||
|
argument:: string
|
||
|
An instance of link::Classes/String::. The contents of the document.
|
||
|
argument:: envir
|
||
|
An instance of link::Classes/Environment::. The link::Classes/Environment:: to be used by the interpreter of the document window. By default, it is set to the current link::Classes/Environment::.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.new("this is the title", "this is the text");
|
||
|
::
|
||
|
|
||
|
method:: open
|
||
|
Open a document from a path.
|
||
|
argument:: path
|
||
|
The file system path to the document. An instance of link::Classes/String::.
|
||
|
argument:: selectionStart
|
||
|
The beginning of the cursor selection of the file content.
|
||
|
argument:: selectionLength
|
||
|
The length of the cursor selection of the file content.
|
||
|
argument:: envir
|
||
|
An instance of link::Classes/Environment::. The Environment to be used by the interpreter of the document window. By default, it is set to the current link::Classes/Environment::.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.open("README", 292,253); // notice the selected text in the open document
|
||
|
::
|
||
|
|
||
|
method:: openDocuments
|
||
|
Returns an Array of all open documents.
|
||
|
code::
|
||
|
d = Document.openDocuments.do{ |doc| doc.name.postln };
|
||
|
::
|
||
|
|
||
|
method:: hasEditedDocuments
|
||
|
Returns true if there are edited Documents.
|
||
|
|
||
|
method:: closeAll
|
||
|
warning::
|
||
|
Closes all open Documents, whether edited or not.
|
||
|
::
|
||
|
argument:: leavePostWindowOpen
|
||
|
An instance of link::Classes/Boolean::.
|
||
|
|
||
|
method:: closeAllUnedited
|
||
|
Closes all unedited Documents.
|
||
|
argument:: leavePostWindowOpen
|
||
|
An instance of link::Classes/Boolean::.
|
||
|
|
||
|
method:: current
|
||
|
Gets/sets the current Document.
|
||
|
argument:: value
|
||
|
A Document.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.name.postln; // Prints "Document.html"
|
||
|
::
|
||
|
|
||
|
method:: allDocuments
|
||
|
Returns all documents.
|
||
|
|
||
|
method:: globalKeyDownAction
|
||
|
Get/set A global action to be performed when a key is pressed.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: globalKeyUpAction
|
||
|
Get/set A global action to be performed when a key is released.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: initAction
|
||
|
Get/set A an action to be performed up opening or creating a Document.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: autoRun
|
||
|
If a document begins with the link::Classes/String::, code::"/*RUN*/"::, then the code following it int he file will be executed on opening the file, if autorun is set to true.
|
||
|
argument:: value
|
||
|
An instance of link::Classes/Boolean::. Default value is code::true::.
|
||
|
|
||
|
method:: implementationClass
|
||
|
The editor implementation specific class which will handle Documents.
|
||
|
argument:: value
|
||
|
A class for implementing Document.
|
||
|
|
||
|
subsection:: Path Utilities
|
||
|
|
||
|
Utilities and settings for dealing with documents such as SuperCollider code files. By default the document directory is SuperCollider's application directory.
|
||
|
|
||
|
method:: dir
|
||
|
Get/set the default document directory. The default is dependent on link::Classes/Document#implementationClass::.
|
||
|
argument:: path
|
||
|
The file system path to the directory. An instance of link::Classes/String::.
|
||
|
discussion::
|
||
|
In Main-startUp you can set this to a more practical directory:
|
||
|
code::
|
||
|
Document.dir = "~/Documents/SuperCollider";
|
||
|
::
|
||
|
|
||
|
method:: standardizePath
|
||
|
argument:: p
|
||
|
The file system path to the directory. An instance of link::Classes/String::.
|
||
|
discussion::
|
||
|
If it is a relative path, expand it to an absolute path relative to your document directory. Expand tildes in path (your home directory), resolve symbolic links (but not aliases). Also converts from Mac OS 9 path format. See PathName for more complex needs.
|
||
|
code::
|
||
|
Document.standardizePath("~/"); // This will print your home directory
|
||
|
|
||
|
Document.standardizePath(":Patches:newfoots:fastRuckAndTuck");
|
||
|
// Returns: /Volumes/Macintosh HD/Users/cruxxial/Documents/SC3docs/Patches/newfoots/fastRuckAndTuck
|
||
|
|
||
|
Document.standardizePath("~/Documents/SC3docs/Patches/newfoots/fastRuckAndTuck");
|
||
|
// Returns: Patches/newfoots/fastRuckAndTuck
|
||
|
|
||
|
Document.standardizePath("Patches/newfoots/fastRuckAndTuck")
|
||
|
// Returns: Patches/newfoots/fastRuckAndTuck
|
||
|
::
|
||
|
|
||
|
method:: abrevPath
|
||
|
Returns a path relative to Document.dir, if the path is inside Document.dir.
|
||
|
argument:: path
|
||
|
The file system path to the directory. An instance of link::Classes/String::.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
instancemethods::
|
||
|
|
||
|
private:: prGetBackgroundColor, prGetBounds, prIsEditable, propen, prGetTitle, prinitByString, prGetLastIndex, prSetBackgroundColor, prSetFileName, prUsesAutoInOutdent, prclose, prGetSelectedBackgroundColor, prGetFileName, prSetSelectedBackgroundColor, prSelectLine, prinitByIndex, prAdd, prSetBounds, prinsertText, prSetTitle, initFromPath, initByString
|
||
|
|
||
|
subsection:: General Document Properties
|
||
|
|
||
|
method:: path
|
||
|
Get / set the the Document's path.
|
||
|
argument:: apath
|
||
|
An instance of link::Classes/String::. A files system path.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.path.postln;
|
||
|
::
|
||
|
|
||
|
method:: dir
|
||
|
Returns the directory of a Document.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.dir.postln;
|
||
|
::
|
||
|
|
||
|
method:: ==
|
||
|
A binary operator.
|
||
|
argument:: that
|
||
|
An instance of Document.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current == Document.listener; // presumably returns false
|
||
|
::
|
||
|
|
||
|
method:: editable
|
||
|
Get / set the the document is editable.
|
||
|
argument:: bool
|
||
|
An instance of link::Classes/Boolean::.
|
||
|
|
||
|
method:: name
|
||
|
Get / set the title (same as link::Classes/Document#title::).
|
||
|
argument:: aname
|
||
|
An instance of link::Classes/String::.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.name.postln;
|
||
|
::
|
||
|
|
||
|
method:: title
|
||
|
Get / set the title (same as link::Classes/Document#name::).
|
||
|
argument:: newTitle
|
||
|
An instance of link::Classes/String::.
|
||
|
|
||
|
method:: promptToSave
|
||
|
Get/set whether a document is prompts to save if it has been changed. Use this with caution.
|
||
|
argument:: bool
|
||
|
An instance of link::Classes/Boolean::.
|
||
|
|
||
|
method:: closed
|
||
|
Returns code::true:: if the document has been closed.
|
||
|
|
||
|
method:: isEdited
|
||
|
Returns code::true:: if the document has been edited.
|
||
|
code::
|
||
|
Document.current.isEdited.postln;
|
||
|
::
|
||
|
|
||
|
method:: isFront
|
||
|
Returns code::true:: if the document is in front.
|
||
|
|
||
|
method:: didBecomeKey
|
||
|
Saves the current link::Classes/Environment::, makes the document current, and performs its link::Classes/Document#toFrontAction::.
|
||
|
|
||
|
method:: didResignKey
|
||
|
Performs the Document's link::Classes/Document#endFrontAction:: and restores the current link::Classes/Environment::.
|
||
|
|
||
|
|
||
|
|
||
|
subsection:: Controlling Document
|
||
|
|
||
|
method:: close
|
||
|
Close a document.
|
||
|
code::
|
||
|
(
|
||
|
Task({
|
||
|
var doc;
|
||
|
doc = Document("background", "closing in 2 seconds");
|
||
|
doc.stringColor_(Color.blue);
|
||
|
1.wait;
|
||
|
doc.background_(Color.blue(alpha:0.8));
|
||
|
1.wait;
|
||
|
doc.close;
|
||
|
}).play(AppClock);
|
||
|
)
|
||
|
::
|
||
|
|
||
|
method:: front
|
||
|
Bring a document to the front.
|
||
|
code::
|
||
|
Document.listener.front;
|
||
|
::
|
||
|
|
||
|
method:: onClose
|
||
|
Get/set the action to be performed on closing the document.
|
||
|
argument:: value
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: endFrontAction
|
||
|
Get/set the action to be performed when the document becomes no longer the front document.
|
||
|
argument:: value
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: toFrontAction
|
||
|
Get / set the action to be performed when the document become the front document.
|
||
|
argument:: value
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::.
|
||
|
|
||
|
method:: mouseDownAction
|
||
|
Get/set the action to be performed on link::Classes/Document#mouseDown::.
|
||
|
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::. The arguments passed to the function are: code::document::, code::x::, code::y::, code::modifiers::, code::buttonNumber::, code::clickCount::, code::clickPos::.
|
||
|
|
||
|
|
||
|
method:: mouseUpAction
|
||
|
Get/set the action to be performed on link::Classes/Document#mouseUp::.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::. The arguments passed to the function are: code::document::, code::x::, code::y::, code::modifiers::, code::buttonNumber::, code::clickCount::, code::clickPos::.
|
||
|
discussion::
|
||
|
code::
|
||
|
(
|
||
|
|
||
|
//add a mouse action to this document:
|
||
|
//example: easy button:
|
||
|
//when you click in front of a 17 a SinOsc will start up;
|
||
|
s.waitForBoot({
|
||
|
Document.current.mouseUpAction_({arg doc;
|
||
|
var char;
|
||
|
char = doc.rangeText(doc.selectionStart, 2);
|
||
|
if(char == "17",{
|
||
|
{EnvGen.kr(Env.perc, doneAction: Done.freeSelf) * SinOsc.ar([600,720,300].choose, 0, 0.5)}.play;
|
||
|
});
|
||
|
if(char == "23",{
|
||
|
{EnvGen.kr(Env.perc, doneAction: Done.freeSelf) * PinkNoise.ar(0.2)}.play;
|
||
|
});
|
||
|
})
|
||
|
});
|
||
|
)
|
||
|
::
|
||
|
Test here and click in front of the numbers: 17 and 23.
|
||
|
code::
|
||
|
Document.current.mouseUpAction = nil; // clear mouseUpActiont
|
||
|
::
|
||
|
|
||
|
|
||
|
method:: keyDownAction
|
||
|
Get/set the action to be performed on link::Classes/Document#keyDown::.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::. The arguments passed to the function are: code::document::, code::char::, code::modifiers::, code::unicode::, code::keycode::. See link::Classes/View#Key actions:: for details on these arguments.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.keyDownAction = { arg ...args; args.postln };
|
||
|
// now type some text
|
||
|
Document.current.keyDownAction = nil;
|
||
|
::
|
||
|
|
||
|
method:: keyUpAction
|
||
|
Get/set the action to be performed on link::Classes/Document#keyUp::.
|
||
|
argument:: action
|
||
|
An instance of link::Classes/Function:: or link::Classes/FunctionList::. The arguments passed to the function are: code::document::, code::char::, code::modifiers::, code::unicode::, code::keycode::. See link::Classes/View#Key actions:: for details on these arguments.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.keyUpAction = { arg ...args; args.postln };
|
||
|
// now type some text
|
||
|
Document.current.keyUpAction = nil;
|
||
|
::
|
||
|
|
||
|
subsection:: Editing Content
|
||
|
|
||
|
method:: selectLine
|
||
|
Select a line of the document by number.
|
||
|
argument:: line
|
||
|
An link::Classes/Integer::.
|
||
|
discussion::
|
||
|
code::
|
||
|
Document.current.selectLine(390);
|
||
|
::
|
||
|
|
||
|
method:: selectRange
|
||
|
Select a text range in the string of the document.
|
||
|
argument:: start
|
||
|
The start index.
|
||
|
argument:: length
|
||
|
The length of the selection.
|
||
|
discussion::
|
||
|
code::
|
||
|
(
|
||
|
Document.current.selectRange(Document.current.selectedRangeLocation + 3, 150);
|
||
|
)
|
||
|
::
|
||
|
|
||
|
method:: selectionStart
|
||
|
Returns the start of a current selection.
|
||
|
code::
|
||
|
Document.current.selectionStart.postln;
|
||
|
::
|
||
|
|
||
|
method:: selectionSize
|
||
|
Returns the size of a current selection.
|
||
|
code::
|
||
|
(
|
||
|
var doc;
|
||
|
doc = Document.current;
|
||
|
doc.selectRange(doc.selectionStart - 40, 10);
|
||
|
doc.selectionSize.postln;
|
||
|
)
|
||
|
::
|
||
|
|
||
|
|
||
|
method:: selectedString
|
||
|
Gets/sets the selected string.
|
||
|
argument:: txt
|
||
|
An instance of link::Classes/String::.
|
||
|
discussion::
|
||
|
code::
|
||
|
(
|
||
|
var doc;
|
||
|
doc = Document.current;
|
||
|
doc.selectRange(doc.selectionStart - 40, 10);
|
||
|
doc.selectedString.postln;
|
||
|
)
|
||
|
::
|
||
|
|
||
|
method:: currentLine
|
||
|
Returns the current line as a link::Classes/String::.
|
||
|
code::
|
||
|
(
|
||
|
var doc;
|
||
|
doc = Document.current;
|
||
|
doc.selectRange(doc.selectionStart - 40, 10);
|
||
|
doc.currentLine.postln;
|
||
|
)
|
||
|
::
|
||
|
|
||
|
method:: getSelectedLines
|
||
|
Returns all full lines from before code::rangestart:: to after code::rangestart + rangesize:: as a link::Classes/String::.
|
||
|
discussion::
|
||
|
code::
|
||
|
(
|
||
|
var doc;
|
||
|
doc = Document.current;
|
||
|
doc.selectRange(doc.selectionStart - 40, 10);
|
||
|
doc.getSelectedLines(doc.selectionStart - 40, 130).postln;
|
||
|
)
|
||
|
::
|
||
|
|
||
|
|
||
|
method:: string
|
||
|
Gets or sets the string within a certain range.
|
||
|
argument:: string
|
||
|
A link::Classes/String::.
|
||
|
argument:: rangestart
|
||
|
An link::Classes/Integer::.
|
||
|
argument:: rangesize
|
||
|
An link::Classes/Integer::.
|
||
|
discussion::
|
||
|
code::
|
||
|
// Select the following code in parentheses and execute it
|
||
|
(
|
||
|
Document.current.string_(": test test test test test ",
|
||
|
Document.current.selectedRangeLocation + 12,
|
||
|
18);
|
||
|
)
|
||
|
// Watch me change content
|
||
|
::
|
||
|
|
||
|
subsection:: Subclassing and Internal Methods
|
||
|
|
||
|
The following methods are usually not used directly or are called by a primitive. Programmers can still call or override these as needed.
|
||
|
code::
|
||
|
*startup
|
||
|
*numberOfOpen
|
||
|
mouseUp (x, y, modifiers, buttonNumber, clickCount, clickPos)
|
||
|
keyDown (character, modifiers, unicode, keycode)
|
||
|
keyUp (character, modifiers, unicode, keycode)
|
||
|
getIdentifierCoordFromEnd (endPos)
|
||
|
dataptr
|
||
|
|
||
|
Private. Used only internally:
|
||
|
*newFromIndex (idx)
|
||
|
*prnumberOfOpen
|
||
|
*prGetLast
|
||
|
*prGetIndexOfListener
|
||
|
*prBasicNew
|
||
|
prAdd
|
||
|
prGetLastIndex
|
||
|
setFont (font, rangeStart, rangeSize)
|
||
|
setTextColor (color, rangeStart, rangeSize)
|
||
|
propen (path, selectionStart, selectionLength)
|
||
|
rangeText (rangestart, rangesize)
|
||
|
insertTextRange (string, rangestart, rangesize)
|
||
|
prinitByString (title, str, makeListener)
|
||
|
prSetBackgroundColor (color)
|
||
|
prGetBackgroundColor (color)
|
||
|
prSelectLine (line)
|
||
|
prIsEditable_ (editable)
|
||
|
prSetTitle (argName)
|
||
|
prGetTitle
|
||
|
prGetFileName
|
||
|
prSetFileName (apath)
|
||
|
prGetBounds (argBounds)
|
||
|
prSetBounds (argBounds)
|
||
|
prclose
|
||
|
prinsertText (dataPtr, txt)
|
||
|
prinitByIndex (idx)
|
||
|
envir
|
||
|
envir_ (ev)
|
||
|
text
|
||
|
removeUndo
|
||
|
selectedText
|
||
|
selectUnderlinedText (clickPos)
|
||
|
linkAtClickPos (clickPos)
|
||
|
selectedRangeLocation
|
||
|
selectedRangeSize
|
||
|
restoreCurrentEnvironment
|
||
|
saveCurrentEnvironment
|
||
|
initByIndex (idx)
|
||
|
initLast
|
||
|
initFromPath (path, selectionStart, selectionLength)
|
||
|
initByString (argTitle, str, makeListener)
|
||
|
::
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
examples::
|
||
|
|
||
|
code::
|
||
|
//unfocusedFront_
|
||
|
(
|
||
|
Document.allDocuments.at(0).unfocusedFront
|
||
|
)
|
||
|
|
||
|
|
||
|
(
|
||
|
var doc;
|
||
|
doc = Document("", "||");
|
||
|
doc.background_(Color.blue(alpha: 1.0.rand));
|
||
|
|
||
|
Task({
|
||
|
1000.do({
|
||
|
doc.setFont(rangeSize: [7, 8, 9, 24].choose);
|
||
|
0.08.wait;
|
||
|
})
|
||
|
}).play(AppClock);
|
||
|
|
||
|
Task({
|
||
|
100.do({
|
||
|
1.01.wait;
|
||
|
doc.stringColor_([Color.red(alpha: 1.0.rand), Color.green(alpha: 1.0.rand)].choose);
|
||
|
})
|
||
|
}).play(AppClock);
|
||
|
|
||
|
Task({
|
||
|
100.do({
|
||
|
1.01.wait;
|
||
|
doc.selectedString_(["\"\n#", "||", "-", "--"].choose);
|
||
|
})
|
||
|
}).play(AppClock);
|
||
|
|
||
|
Task({
|
||
|
var co, mul;
|
||
|
co = 0.1;
|
||
|
mul = 1.02;
|
||
|
100.do({
|
||
|
0.16.wait;
|
||
|
co = co * mul;
|
||
|
if(co > 0.99, { co = 0.1 });
|
||
|
doc.background_(Color.blue(alpha: co));
|
||
|
});
|
||
|
doc.close;
|
||
|
}).play(AppClock)
|
||
|
)
|
||
|
::
|
||
|
|
||
|
A simple implementation of TBT (time based text) http://tbt.dyne.org/?info=download
|
||
|
code::
|
||
|
// record: type some text
|
||
|
(
|
||
|
var time = Main.elapsedTime;
|
||
|
a = List.new;
|
||
|
r = Routine { |char|
|
||
|
loop {
|
||
|
a = a.add([char, Main.elapsedTime - time]);
|
||
|
char = 0.yield;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Document.new("type some text")
|
||
|
.bounds_(Rect(100,SCWindow.screenBounds.height - 250, 400, 200))
|
||
|
.keyDownAction = { |doc, key| r.value(key) ; time = Main.elapsedTime};
|
||
|
)
|
||
|
|
||
|
// play back text in time
|
||
|
(
|
||
|
d = Document.new("type some text")
|
||
|
.bounds_(Rect(550,SCWindow.screenBounds.height-250,400,200));
|
||
|
fork({
|
||
|
a.do { |pair|
|
||
|
d.string = d.string ++ pair[0];
|
||
|
pair[1].wait;
|
||
|
}
|
||
|
}, AppClock)
|
||
|
)
|
||
|
::
|
||
|
|
||
|
Changing the default look of documents can be done with the help of the link::#*initAction:: method. Run the following example once. Afterwards all newly created documents will have a dark grey background. To make this change happen every time you start SuperCollider, put the code inside your startup.scd file (and optionally wrap it in a code::{}.defer(0.1):: ).
|
||
|
code::
|
||
|
(
|
||
|
Document.listener.background = Color.red; //a special color for post document
|
||
|
Document.listener.bounds = Rect(1, 461, 620, 567); //move and resize post document
|
||
|
Document.initAction = {|doc| //function to run for every new document
|
||
|
doc.background = Color.grey(0.1, 0.9);
|
||
|
doc.bounds = Rect(0, 119, 1280, 659);
|
||
|
doc.selectedBackground = Color(0.4, 0.05, 0.18);
|
||
|
doc.stringColor = Color.grey(0.9);
|
||
|
};
|
||
|
)
|
||
|
::
|