| layout | default |
|---|---|
| title | Getting Started |
Shortcutslang tries to be familiar to read and write. To write an action, put the action name with no spaces and a list of arguments in order.
ActionName "Action" "Arguments"
For example, the text action is named Text and has one field, the text inside it.
Text "This is my text"
| Actions shown | Text |
You can convert ScPL to .shortcut using the MCP server or npm package.
MCP Server auto-signs by default! If using the MCP server, shortcuts are signed automatically.
For manual signing:
- CLI (Built into macOS 12+):
shortcuts sign --mode anyone --input file.shortcut --output signed.shortcut - GUI: Use Shortcut Source Tool from RoutineHub
Copy the signed .shortcut file to your device through AirDrop or iCloud files and open it in Shortcuts.
More complex actions have multiple fields
GetFile "iCloud Drive" true false
For these actions, you can put labels to know which field is which.
GetFile service="iCloud Drive" showdocumentpicker=true selectmultiple=false
| Actions shown | GetFile |
Other actions have blocks, like the if action and choose from menu action
Text "hello"
If "Equals" "hello"
ShowAlert title="Alert!" message="It equals hello"
Otherwise
ShowAlert title="Alert!" message="It does not equal hello"
End If
| Actions shown | If | ShowAlert | Text |
Variables are marked with type:varname. For example, a named variable called Input would be v:Input. There are 3 variable types, v for named variable, mv for magic variable, and s for special variables. To use a variable with spaces in the name, surround the name with quotes like v:"Repeat Index"
Variables can be used directly as a field value to an action or they can be put within strings or barlists (more info below).
Text mv:MyMagicVariable
Text "Backslash parenthesis are used to put a variable inside text, like \(v:ThisVariable)."
Text
| The same is used for \(v:Variables) in barlists.
| Actions shown | Text |
Named variables are set just like how they are in shortcuts, using the SetVariable action. For example,
Text "My text"
SetVariable "MyVariable"
# now you can use it
ShowResult "My text is \(v:MyVariable)"
Magic variables are magical and don't require an action to set. Instead you use the -> arrow set syntax to say that the action is magical.
Text "My text" -> mv:Magic
# now you can use it
ShowResult "Magic! \(mv:Magic)"
You cannot set special variables, they are special.
| Actions shown | Text | ShowResult |
ScPL comments can be put in your code like shortcuts comments but they do not output any actions.
# this is a comment
// this is also a comment
-- this is also a comment
Image
This shortcut has no actionsShortcuts has many different field types, for each field type there are many ways you can write them in shortcutslang
Many actions have text fields of different sizes. The Text action has a multiline text field, and the Save file action has a single line text field to enter a destination path.
Text fields can be used with strings and multiline text fields can also be made with barlists
Text "This is a text field with a string"
Text
| This is a multiline text field using a barlist.
| This is the second line
| This is a variable: \(v:MyVariable)
Some text fields do not allow variables, such as the Comment action.
Comment
| This text field does not allow variables
Comment
| \(v:Variable) # Not Allowed
Image
This shortcut fails to convert| Actions shown | Text | Comment |
An Enum Field has a list of options to choose from, such as the Condition field in if or the operator field in calculate.
Calculate "+" 1
If you enter a value that is not allowed, shortcutslang will throw an error. Unlike action names, enum fields are case and space sensitive and must be exact.
Some enum fields allow variables, and some do not.
Calculate v:Operand 3
| Actions shown | Calculate |
If an enum field does not allow variables, it will error when you try to use a variable.
Enum fields cannot have mixed text and variables, so "\(v:Not) Equals" is never allowed.
Number fields accept a number.
Number 16
Number 29.5
Number -924
Number .8
Number -.2
Similar to Enum fields, Number fields cannot have mixed text and variables.
Number v:MyVariable
Number "-\(v:MyVariable)" # Not Allowed
Image
This shortcut fails to convert| Actions shown | Number |
Stepper number fields are like number fields but can only have positive integer numbers (no decimals)
Repeat 5
ShowResult "Hi"
End Repeat
Repeat 5.5 # Not allowed
ShowResult "Hi"
End Repeat
Image
This shortcut fails to convert| Actions shown | Repeat |
Slider number fields are like number fields but can only have numbers from 0 to 1
SetBrightness 0.5
SetBrightness 1.1 # Not Allowed
Image
This shortcut fails to convert| Actions shown | SetBrightness |
Variable picker fields can have a variable.
GetVariable v:MyVariable
GetVariable "MyVariable" # Not Allowed
Image
This shortcut fails to convert| Actions shown | getvariable |
Switch fields can have a true or false value. True is on and false is off.
SetWifi true
SetAirplaneMode false
SetWifi yes # Not Allowed, must be true or false
SetAirplaneMode no # Not Allowed, must be true or false
Image
This shortcut fails to convertSome switch fields allow variables
SetWifi v:Wifi
| Actions shown | SetWifi | List |
Dictionary fields are written like JSON
Dictionary{
"key": "value",
"variable": v:myVariable,
"list": ["item 1", "item 2"],
"dictionary": {"key": "value"}
}
Quotes and commas are not required and = can be used instead of : if wanted
Dictionary{
key = value
variable = v:myVariable
list = ["item 1", "item 2"]
dictionary = {key = value}
}
| Actions shown | Dictionary |
Lists can be made using json-like [] syntax.
ChooseFromMenu "Pick an item" ["item 1", "item 2"]
case 1
case 2
end menu
Similar to dictionaries, lists do not require commas and can span over multiple lines
ChooseFromMenu "Pick an item" [
"item 1"
"item 2"
]
case First
case Second
end menu
Lists can also be made using barlists.
List
| My First Item
| My Second Item
| Actions shown | ChooseFromMenu | List |
(Different from Variable Picker Fields)
Variable fields is the field used in SetVariable to enter a variable name. They can be made using strings or v: variables.
SetVariable "MyNamedVariable"
SetVariable v:MyNamedVariable
Filter fields
FilterFiles :filter{name is "filename"}
| Actions shown | Filter Files |
There are other fields, most are very similar to similar fields like the Storage Service Picker is very similar to the Enum field.
Shortcutslang has some more advanced features to make working on large shortcuts easier
You can put an action inside of a text field or any other field that accepts variable
Text "My number is \(Number -2.5)"
This code is equivalent to
Number -2.5 -> mv:InsideParenthesis
Text "My number is \(mv:InsideParenthesis)"
None of these magic variables actually get a name, they just directly reference the action.
You can even use actions inside other actions this without disrupting the action input
Text "Hello"
If Equals (Text "Goodbye")
ShowResult "If the action input was disrupted, this would run"
Otherwise
QuickLook
End If
is equivalent to writing out
Text "Hello" -> mv:OriginalInput
Text "Goodbye" -> mv:ArgumentValue
GetVariable mv:OriginalInput
If Equals mv:ArgumentValue
ShowResult "If the action input was disrupted, this would run"
Otherwise
QuickLook # Shows "Hello"
End If
| Actions shown | Text | GetVariable | If | QuickLook | Number |
Sometimes you want to disrupt the input, you can use an InputArg
Text "Some text"
QuickLook ^(Text "Different text")
is the same as
Text "Some text"
Text "Different text"
QuickLook
| Actions shown | Text | QuickLook |
When you tap a variable in Shortcuts, a menu pops up containing different actions. Those are called Aggrandizements.
GetVariable v:MyVariable{as:Dictionary,key:myKey}
GetVariable v:MyContact{as:Contact,get:Notes}
Currently, 3 aggrandizements are supported:
- as/coerce
- key/forKey
- get/getProperty (partial)
The key: aggrandizement is used very often in conjunction with the as: Dictionary aggrandizement. Instead of writing that out every time, there is a shortcut for it
GetVariable v:MyDictionary:myKey
is the same as
GetVariable v:MyDictionary{as:Dictionary,key:myKey}
| Actions Shown | GetVariable |
-> can be used to set more than just magic variables, it can also automatically make SetVariable actions.
Text "My Text" -> v:MyNamedVariable
is equivalent to writing
Text "My Text"
SetVariable v:MyNamedVariable
If you prefer, you can set variables before an action instead of after
mv:WowMagic = Text "My Text"
is exactly the same as using an arrow, except it's in the format mv:variable = action
Text "My Text" -> mv:WowMagic
| Actions Shown | Text | | GetVariable |
Actions can usually only take up one line of text, unless you use a barlist. If you have many different arguments, it can be helpful to have actions span multiple lines. You can use an arglist for this.
getfile a{
service="iCloud Drive"
showdocumentpicker=false
filepath="/myfile.txt"
errorifnotfound=false
}
| Actions shown | GetFile |
Shortcuts has 5 special variables, 2 of which seem to have no reason for existing.
- Ask When Run
s:AskWhenRun(prompts the user to enter the field themselves) - Shortcut Input
s:ShortcutInput(the input to the shortcut) - Action Input
s:ActionInput(the input to the action) - Current Date
s:CurrentDate(the current date) - Clipboard
s:Clipboard(the contents of the clipboard)
Parser variables are variables that only exist in your scpl file. When the shortcut is generated, they are replaced with their value.
Set a parser variable with @set, use a parser variable with @:variable
@set varname "value"
text "value is \(@:varname)"
Parser variables inherit the properties of their values.
@set number 0.5
@set list [1, 2, 3]
number @:number
list @:list
Parser variables can contain actions
@set myaction (text "hi")
@:myaction
Parser variables can contain lists of actions
@set EscapeText @{
replacetext "\\" "\\\\"
replacetext (Text "\n") " "
replacetext ";" "\\;"
}
Text ";Hi there!\n\\"
@:EscapeText
Parser variables can take input as a dictionary of parser variables to set
@set test (Text @:value)
@:test{value:"Hi!"}
In shortcuts, you can make functions by checking different inputs. To run these functions, normally it would take lots of code.
runShortcut v:ThisShortcut false ^(Dictionary{ action: Escape, text: "<the text>" })
You can define a macro/parser variable to insert that for you
setVariable v:ThisShortcut ^(text "Shortcut Name")
@set Escape (runShortcut v:ThisShortcut false ^(Dictionary{ action: Escape, text: @:text }))
AskForInput "Text to escape" -> mv:InputtedText
@:Escape{text: mv:InputtedText}
Foreach will repeat an action multiple times
@foreach ["Item 1", "Item 2", "Item 3", "Item 4"] @{
Text @:repeatitem
}
The @if macro allows you to do things if a boolean is true
@if true @{
text "True Condition"
} @{
text "False Condition"
}
The @elseif macro is a shorthand for chaining else ifs.
if Equals WifiOn
SetWifi true
@elseif Equals WifiOff
SetWifi false
@elseif Equals BluetoothOn
SetBluetooth true
else
SetBluetooth false
End
The @error macro throws an error.
@error "There is a problem."
Image
Code does not compile, there is an errorThe @def macro allows you to define your own macros.
@def @printtext ["arg1", "arg2"] @{
ShowResult "Arg1 is \(@:arg1) and Arg2 is \(@:arg2)"
}
@PrintText arg1="Value1" arg2="Value2"









































