Send feedback

Getting Started

Welcome to the Serenade docs! Here, you'll find an overview of everything Serenade can do, along with examples. First, let's get Serenade installed on your device.

Download

First, download and install Serenade. Serenade supports macOS, Windows, and Linux—platform-specific installation instructions can be found on the download page.

Setup

After installing Serenade, you'll be prompted to activate the app via an email link. If that link doesn't work, you can use the code provided on the activation page to activate manually.

After activation, Serenade can automatically install plugins for supported editors—Atom and VS Code. Make sure to restart your editor after the plugins are installed (to make sure the Serenade editor plugin is running), and you're ready to go!

You can use Serenade with your laptop microphone, though we recommend using a headset for the best accuracy. You can verify that a headset is being used by clicking , and then Microphone.

Environment

Serenade floats above all your other windows, so you can keep it side-by-side with other applications, like your code editor. You can toggle Serenade by clicking the Listening switch or pressing Alt+Space. Then, as you speak, you'll see a list of transcripts in the Serenade window.

Sometimes, Serenade isn't sure what you said, so you'll see a few different options. The first one will be used automatically, but to use a different option (and undo the first one), just say the number you want to use instead. For instance, to use the second option, just say two. If none of the options are right, you can just say undo.

Concepts

As you'll see, many Serenade commands take the same form: an action followed by a selector. An action is something you want to do to code, like a add, change, or delete. A selector is a block of code to operate on, like line, word, function, or class. To quickly reference common actions and selectors, check out the Reference section.

Throughout the documentation, you'll see blocks that look like this:

Syntax

(insert | type) [above | below] <text>

Examples

voice
insert sunshine
before
Good morning, ""
after
Good morning, "sunshine"
  • Text in <angle brackets> is free-form text, like the name of a function or variable.
  • Text separated by pipes, like (foo | bar), represents a list of choices (i.e., an or).
  • Text in [square brackets] is optional.

Modes

Serenade supports different commnads depending on which application is currently in the foreground (i.e., focused). At the bottom-left of the Serenade window, you can see which application is currently active, along with an icon indicating which commands are available. Here the various modes Serenade can be in:

Code editing mode

When your editor is in focus, and a file with a supported language is detected, all commands are available. Hover over the active app indicator to see the detected language.

Text mode

When your editor is open to a file with a language that's not supported, a subset of commands are supported.

Global mode

When your editor is not in focus, Serenade can still type raw text and run system commands.

Command CategoryCode editing modeText modeGlobal mode
Navigating CodeText selectors
Adding CodeRaw TextRaw Text
Editing CodeText selectors
Symbols and Formatting
System
Workflow
Custom Commands
SelectorsText selectors

The automatic reminder can be turned off in "Settings > Editor > Active app reminder", and it will always be available when the active app indicator is hovered over.

Adding Code

In this section, we'll take a look at the various voice commands you can use for writing code, including insert, add, and type. As you'll see, there are three different commands you can use to add new code, depending on what you want to do:

  • Use the insert command to insert text at your cursor. This is how most dictation software (and your keyboard!) typically works. The insert command uses machine learning under the hood to handle many formatting details for you, so you don't have to manually specify things like underscores vs. camel case formatting (though you also can specify them if you want!).
  • Use the add command to add programming constructs, like classes and functions. Like insert, the add command will automatically handle many formatting details for you. add will also move your cursor to the right location, while insert inserts text where your cursor already is—for instance, if you say add argument, but your cursor isn't in a function call, then Serenade will automatically move your cursor and add your code to the nearest argument list.
  • Use the type command to insert raw text, without any automatic code formatting. type can be a helpful last resort if insert or add isn't giving you the code you want.

Inserting Code

The insert command will insert code at the current cursor position, handling many formatting details for you. For instance, if you have a variable foo_bar in scope and you say insert foo bar, Serenade will automatically format your code as foo_bar, so you don't have to specify the underscore.

The insert command is useful for appending text to an existing line of code, or inserting text into the middle of a line. When you're writing a new line of code, an add command might be faster, but you can also use insert to write any code, including functions, classes, and so on.

Syntax

insert [above | below] <text>

Examples

voice
insert hello world
result
hello world
insert first equals array brackets zero
first = array[0]
voice
insert quotes hello comma world
before
value = 
after
value = "hello, world"
insert above hello
world
hello
world

Functions & Methods

While the insert code inserts text at your cursor, the add is a convenient way to quickly write larger programming constructs, like classes or methods, with voice. With the add command, you don't need to dictate the boilerplate parts of code, like braces after a try or parens around a condition. Unlike insert, the add command will also move your cursor for you. For instance, if you say add parameter, but your cursor isn't in a place where a parameter could logically go, add will automatically move your cursor to the right spot (in this case, to the nearest parameter list).

Create a new function

add (function | method) [<modifiers>] [<type>] <identifier>
add [<modifiers>] [<type>] (function | method) <identifier>

Examples

voice
add function compute factorial
result
def compute_factorial():
    pass
add method players
class Game:
    def score(self):
        return 5
class Game:
    def players(self):
        pass

    def score(self):
        return 5
add int method score
class Game:
    pass
class Game:
    def score(self) -> int:
        pass

Add a parameter to a function

add parameter [<type>] <identifier>
add [<type>] parameter <identifier>

Examples

voice
add parameter max speed
before
def run(distance):
    pass
after
def run(distance, max_speed):
    pass
add string parameter name
def say_hello():
    pass
def say_hello(name: str):
    pass
add parameter foo bar equals quotes baz
def foo(a):
    pass
def foo(a, foo_bar="baz"):
    pass

Add a return type to a function

add type <type>

Examples

voice
add type str
before
def get_name():
    pass
after
def get_name() -> str:
    pass
add type int
def set_limit(limit):
    pass
def set_limit(limit: int):
    pass

A parameter occurs in a function signature/definition, whereas an argument occurs when a function is called.

Add an argument to a function call

add argument <expression>

Examples

voice
add argument first name plus last name
before
print("hello")
after
print("hello", first_name + last_name)
add argument b equals one
foo(a)
foo(a, b=1)

You can also use lambda within any add command to create an inline anonymous function:

Create a lambda / arrow function

add lambda <identifier> [of <identifier>]

Examples

voice
add f equals lambda of x
result
f = lambda x: x

Classes

Create a new class

add (class | enum) <identifier>

Examples

voice
add class download manager
result
class DownloadManager:
    pass
add enum category type
class CategoryType(enum.Enum):
    pass

Add a superclass / parent class

add (extends | parent | superclass) <identifier>

Examples

voice
add parent animal
before
class Dog(Pet):
    pass
after
class Dog(Pet, Animal):
    pass

Add a property / member / field to a class

add (property | member | field) [<type>] <identifier>
add [<type>] (property | member | field) <identifier>

Examples

voice
add property players equals four
before
class Game:
    pass
after
class Game:
    players = 4

Conditions & Loops

Add a condition

add (if | else if) <condition>

Examples

voice
add if count equals ten
result
if count == 10:
    pass
add else if highest score plus one less than three
if True:
    pass
if True:
    pass
elif highest_score + 1 < 3:
    pass

Add an else branch

add else <expression>

Examples

voice
add else return false
before
if True:
    pass
after
if True:
    pass
else:
    return False

Add a while loop

add while <condition>

Examples

voice
add while i less than three
result
while i < 3:
    pass

Add a for loop

add for [<expression> in <identifier>]

Examples

voice
add for i in range of five
result
for i in range(5):
    pass

Comments

Syntax

add comment <text>

Examples

voice
add comment fix later
result
# fix later

Expressions

Add an import

add import <identifier>

Examples

voice
add import time
before
import random
after
import random
import time
add import numpy as np
import numpy as np
add from flask import capital flask
from flask import Flask

Add a try block

add (try | finally) <expression>

Examples

voice
add try write parens
result
try:
    write()
except e:
    pass
add finally
try:
    pass
except:
    pass
try:
    pass
except:
    pass
finally:
    pass

Add a catch block

add [catch | except] <expression>

Examples

voice
add except value error
before
try:
    pass
except:
    pass
after
try:
    pass
except:
    pass
except ValueError:
    pass

Add an expression

add [decorator | print | raise | return | return value | throw] <expression>

Examples

voice
add age equals current age plus one
result
age = current_age + 1
add decorator login required
@app.route("/")
def index():
    pass
@app.route("/")
@login_required
def index():
    pass
add print value
print(value)
add return random dot random parens
def get_random():
    pass
def get_random():
    return random.random()
add return value four
def get_random():
    return
def get_random():
    return 4

You can also include a preposition after add or insert commands to add code at a particular location.

Syntax

[after | before] <selector>

Examples

voice
add function roll after function random
before
import random

def random(low, high):
    return 4
after
import random

def random(low, high):
    return 4


def roll():
    pass

Newlines

The newline command adds a new line at, above, or below the cursor.

Create a new line

[add] newline [above | below]

Examples

voice
newline
before
one
two
three
after
one
t
wo
three
newline below
one
two
three
one
two

three

Raw Text

The type command inserts text at the current cursor position, without much formatting done for you. It's the simplest way to add text, and it can be useful if you want to manually specify formatting, spacing, etc.

Syntax

type [above | below] <text>

Examples

type camel case hello world
helloWorld
type below world
hello
hello
world

The dictate command inserts text, but doesn't convert coding symbols to their equivalents. This can be useful for writing comments or docs, rather than code.

Syntax

dictate <text>

Examples

voice
dictate a plus b greater than not c
result
a plus b greater than not c

Finally, system command inserts text wherever your cursor has focus. For instance, if you're using VS Code and open a "Find" dialog, system will type into that find dialog rather than the main text editor.

Syntax

system <text>

Examples

voice
system hello world
result
hello world

Editing Code

In this section, we'll take a look at voice commands you can use for editing existing code. You can use the delete command to delete code and the change command to edit existing code. Serenade also supports common operations like copy, cut, and paste, along with refactoring commands to duplicate, comment, and move code.

Deleting

You can delete code with the delete command.

In files in supported languages, you can navigate with any selector, and in files in unsupported languages, you can navigate with any text selector.

Delete text

delete <selector>

Examples

voice
delete line six
before
class Bird:
    def chirp(self):
        print("chirp")

    def fly(self):
        # TODO
        pass
after
class Bird:
    def chirp(self):
        print("chirp")

    def fly(self):
        pass
delete two methods
class Bird:
    def chirp(self):
        print("chirp")

    def fly(self):
        # TODO
        pass
class Bird:
    pass
delete lines five to seven
class Bird:
    def chirp(self):
        print("chirp")

    def fly(self):
        # TODO
        pass
class Bird:
    def chirp(self):
        print("chirp")

delete to end of word
class Bird:
    def chirp(self):
        print("chirp")

    def fly(self):
        # TODO
        pass
class B:
    def chirp(self):
        print("chirp")

    def fly(self):
        # TODO
        pass

Changing

The change command selects the nearest match to the cursor and replaces it with some text.

In files in supported languages, you can navigate with any selector, and in files in unsupported languages, you can navigate with any text selector.

Changing text

change <selector> to <text>

Examples

voice
change fly to jump
before
def fly():
    pass
after
def jump():
    pass

You can also use rename to change the name of a function, variable, class, or other named selector

Change the name of a selector

rename <selector> to <text>

Examples

voice
rename parameter to height
before
def fly(elevation):
    pass
after
def fly(height):
    pass
rename function fly to jump
def fly():
    pass
def jump():
    pass

Selecting

You can use commands likecopy, cut, select,paste and duplicate to manipulate text.

In files in supported languages, you can navigate with any selector, and in files in unsupported languages, you can navigate with any text selector.

Copying and highlighting code

(copy | cut | select) <selector>

Examples

copy first function
copy lines fifty to sixty
cut next class
cut next two words
select to end of block
select words one to three

Pasting code from the clipboard

paste [above | below | inline]

Examples

paste
paste below

Duplicate copies your selection and pastes it above or below your cursor.

Duplicating existing code

duplicate <selector> [above | below]

Examples

duplicate line
duplicate next method
duplicate function foo above

Refactoring

Serenade has a number of powerful refactoring commands to edit your code quickly. You can use the comment command to comment out a line or an entire function, the indent command to change indentation levels, and the move command to move a block of code somewhere else in your file.

In files in supported languages, you can navigate with any selector, and in files in unsupported languages, you can navigate with any text selector.

Commenting existing code

(comment | uncomment) <selector>

Examples

voice
comment function
before
def check(x):
    if x < 3:
        return True
    return False
after
# def check(x):
#     if x < 3:
#         return True
#     return False
uncomment lines two to three
url = "https://serenade.ai"
# pages = 3
# download(url, pages)
url = "https://serenade.ai"
pages = 3
download(url, pages)

Indenting code

(indent | dedent) <selector>

Examples

voice
indent line
before
y = f(x)
z = g(y)
after
    y = f(x)
z = g(y)
dedent line
    y = f(x)
z = g(y)
y = f(x)
z = g(y)

Syntax

join [<number>] lines

Examples

voice
join five lines
before
list = [
  1,
  2,
  3
]
after
list = [1, 2, 3]

Syntax

(shift | move) <selector> (left | right | up | down)

Examples

voice
shift line down
before
y = f(x)
z = g(y)
after
z = g(y)
y = f(x)
move argument left
z = f(x, y)
z = f(y, x)

Symbols & Formatting

Commands like add, insert, and change will automatically handle most formatting for you. For instance, if you have a variable foo_bar in scope and you say insert foo bar, Serenade will automatically format your code as foo_bar, so you don't have to specify the underscore. Similarly, if you have a variable called sayHello and you say change hello to goodbye, Serenade will output sayGoodbye, so you don't have to specify the capital letter.

Sometimes, though, you do want to specify symbols and formatting so you can have complete control over what code you're writing. With Serenade, you can also specify symbols and formatting inside of any voice command.

Text Formatting

To format text using camel case, underscores, etc., you can prefix any text with a style:

FormattingResult
lowercasesing song
camel, camel casesingSong
pascal, pascal caseSingSong
all capsSING_SONG
underscores / snakesing_song
one wordsingsong

Creating text with formatting

(add | insert | ...) <formatting> <text>

Examples

insert camel case my balance equals all caps starting balance plus one
myBalance = STARTING_BALANCE + 1
add argument pascal some class
create()
create(SomeClass)

You can also style existing text by describing a style, followed by a selector to change:

Applying formatting to existing text

(capitalize | camel | pascal | all caps | underscores) <selector>

Examples

capitalize foo
foo
Foo
camel case next two words
sing song
singSong

Symbols

You can include symbols when speaking any insert, add, change, etc. command. Here's a list of all of the symbols supported by Serenade.

TranscriptSymbolTranscriptSymbol
plus+dash, minus-
star, times*slash, divided by/
less than or equal to<=less than<
greater than or equal to>=greater than>
not equal!=double equal==
triple equal===equal=
left shift<<right shift>>
and&&or||
comma,colon:
dot, period.underscore_
semicolon;bang, exclam!
question mark?tilde~
percent, mod%at@
dollar$right arrow->
arrow->space
backslash\hash#
caret^ampersand&
backtick`pipe|
left brace{right brace}
left bracket[right bracket]
single quote'quote, double quote"

Enclosure Symbols

Enclosure symbols can be used to wrap text. You can also dictate opening and closing enclosure symbols separately. Here's a list of all of the enclosure symbols supported by Serenade:

TranscriptSymbolTranscriptSymbol
braces{ }brackets[ ]
comparators, angle brackets< >quotes, string" "
single quotes' 'triple quotes""" """
of, parens( )underscores_ _
double underscores__ __

You can use enclosure symbols in any insert, add, or change command.

Creating text with enclosures

(add | insert | ...) <enclosure> <text>

Examples

insert f of x
f(x)
add greeting equals string name
greeting = "name"
insert value equals values brackets zero
value = values[0]

You can also surround existing code in enclosure symbols with the surround command.

Surround a selection with symbols

surround <selector> with <symbols>

Examples

surround x plus y with parens
x + y
(x + y)
surround bar with quotes
foo = bar
foo = 'bar'
surround bar with asterisk
bar
*bar*

Escaping Symbols

If you need to use the literal text representation of a symbol (e.g., the word dash rather than the - character, you can escape it in a few ways:

Syntax

(add | insert | type) (escape | the word) <symbol>

Examples

insert plus
+
insert escape plus
plus

System-Wide Commands

Serenade doesn't just work for applications that have a native Serenade plugin—you can control any application with voice using Serenade. No matter what application you're using, you can use commands like insert to insert text, press to press keys (to trigger shortcuts), and focus to switch apps.

Sending Keystrokes

Inside of any application, you can use the press command to press combinations of keyboard keys—handy for triggering keyboard shortcuts—or the insert command to dictate text.

Press a key combination

press <key>

Examples

press enter
press control tab
press command k

Type a string

(insert | type) <text>

Examples

insert g mail dot com
gmail.com

Manipulate tabs

(new | close | next | previous) tab

Trigger an undo or redo

(undo | redo)

Copy and paste text

(cut | copy | paste)

Type a string and press enter

run <text>

Trigger a mouse click

[left | right | middle] <click>

App Control

With commands like focus, launch, and close, you can quickly switch, open, and close apps with voice.

Bring an application to the foreground

focus <text>

Examples

focus chrome
focus code

Launch an application

launch <text>

Examples

launch atom
launch slack

Close an application

close <text>

Examples

close terminal
close music

Switching among windows of the current app (macOS only)

switch window

Pause Serenade

(pause | stop listening)

Editor Integrations

Through first-party plugins for editors like Atom, VS Code, and the JetBrains IDEs, Serenade can deeply integrate with the editor of your choice. You can use the open command to open files, the style command to auto-format your code, and commands like toggle breakpoint and start debugging to interact with the debugger.

Editor Controls

With Serenade, you can control much of your editor entirely with voice—you can open files, manage tabs, use the undo stack, and trigger your editor's auto-formatter (or Serenade's own formatter).

Save the current file

save

Undo an operation

undo

Redo an operation

redo

Open a file with a name matching text

open <text>

Format the current file

style [file]

Create a new editor tab

new tab

Close the current editor tab

close tab

Switch to the next or previous tab

(next | previous) tab

Switch to a specific tab

tab (one | two | three ...)

Switch to a specific tab

(first | second | ...) tab

Debugging

Serenade integrates with the debuggers in Visual Studio Code and all of the JetBrains IDEs, so you can run and debug your code with voice.

Add or remove a breakpoint

(add | remove | toggle) breakpoint

Start or stop a debugger session

(start | stop) (debugging | debugger)

Move the debugger step-by-step

step (into | out | over)

Continue until the next breakpoint

continue

Inspect a variable

inspect <selector>

Tips and Tricks

  • Instead of worrying about spacing while writing code, use style file once your code is in a reasonable state, and Serenade will automatically format the entire file.
  • Long insert or add commands can be less accurate than shorter commands. If you're seeing low accuracy, try breaking up longer commands into smaller, separate commands.
  • The insert and add commands are similar, but have distinct use cases—add works best for writing new lines of code, including larger constructs like functions or classes, while insert works best for inserting or appending text to an existing line.
  • Use copy/cut, paste, and go to liberally in order to more quickly move code around.
  • Make sure your system's microphone volume is set to the right level. We've found that around 80%, to make sure the input isn't too loud or too quiet, works best, but try moving it around if Serenade's results aren't accurate.
  • When using Serenade, try to speak conversationally, as though you were pair programming with someone seated next to you. Over-enunciating words can actually make Serenade less accurate!
  • If Serenade doesn't know a word, like numpy, you can spell it in a command, as with add import n u m p y.

Chaining

You can chain commands together to avoid having to pause between commands. For example, you can combine the end of file and paste command by saying end of file paste.

Repetition

Serenade supports several different options for repeating commands.

Syntax

(delete | paste | indent ...) <number> (times | <selectors>)

Examples

indent two times
y = f(x)
    y = f(x)
delete five characters
extraordinary
ordinary

Repeat the last command matching text

repeat [<text>]

Examples

repeat
repeat delete
repeat three times

Reference

This section has a few difference references that you can use as cheat sheets while learning Serenade.

Common Commands

Below is a compact list of commonly-used Serenade functionality that you can use as a reference or cheat sheet as you're learning voice coding.

Actions

CommandDescriptionExamples
go toMove your cursor around a filego to line fifty go to next function
addAdd a new line of codeadd return false add throw exception
insertInsert text at your cursorinsert hello plus capital world
changeChange existing textchange hello to goodbye change return value to false
deleteDelete textdelete foo bar delete next function
copy/pasteCopy, cut, and paste textcopy method cut previous two words paste
indent/dedentChange the indentation level of codeindent block dedent if
saveSave the current filesave
undoUndo the last operationundo
openOpen a new fileopen react dot js
next/previous tabSwitch tabs in your editornext tab previous tab
focusSwitch appsfocus code focus chrome

Add Commands

CommandDescriptionExamples
addAdd a new line of codeadd int value equals three add value plus equals one
add argumentAdd an argument to a function calladd argument true
add classCreate a new classadd class manager
add commentCreate a new commentadd comment fix later
add forCreate a new for loopadd for i in range of ten
add functionCreate a new functionadd function download
add ifCreate a new conditionadd if number equals zero
add importCreate a new importadd import react from react add import numpy as np
add methodAdd a method to a classadd method public int get value
add parameterAdd a parameter to a function declarationadd parameter list of string names
add whileCreate a new while loopadd while i is less than zero

Selector Modifiers

CommandDescriptionExamples
next, previousThe next or previous instance of a selectornext function previous class
first, second, ...The index of a selector in a listsecond parameter first word
one, two, ...The index of a selector in a listline five argument two
start, endThe start or end of a selectorstart of line end of method
X to YA range of selectorslines five to ten words one to three
to start, to endFrom the cursor to the start or end of a selectorto end of next word to previous line
<text>The name of a selectorgo to foo bar function factorial class dog
phraseEscaped, literal textphrase value

Code Selectors

Code selectors can be used to describe a block of code you want to reference, like a function, argument, or class. You can use any of these selectors in commands like go to, delete, change, or any command that contains a selector.

The following selectors work for supported languages:

argument listargumentassertassignment
assignment valueassignment variableattributeattribute value
attribute namebodybreakcall
casecatchclassclose tag
commentcomment textconditionconstructor
contentcontinuedebuggerdeclaration
decoratordefaultdictionarydo
do whileelementelse ifelse
enumexceptexportfor
finallyfunctiongeneratorif
importinterfaceinterface listkeyword argument
keyword parameterkeyentrylambda
listmethodmixinmodifier
modifier listnamenamed parameternamed parameter list
namespaceobjectopen tagparameter list
parameter valueparameterparent listparent
passpositional parameterpositional parameter listproperty
prototypereturnreturn typereturn value
rulesetsetstatementstring
string textstructswitchsymbol
synchronizedtagthrowtop level statement
tupletrytypetype alias
usingwithwith listwith alias
with itemwhilevaluevertical

Text Selectors

Text selectors can be used to describe a block of text you want to reference, independent of any programming language. You can use any of these selectors in commands like go to, delete, change, or any command that contains a selector.

The following selectors work in any file, regardless of whether or not Serenade supports the language:

all
block
character
file
letter
line
number
phrase
term
word

Selector Syntax

By default, a selector applies to the nearest matching object. You can optionally apply previous or next to each selector, as in previous line or next line. Selectors can also include an ordinal prefix/postfix (like first or one) or a range of objects (like two to five).

Syntax

<action> [to] [start of | end of | next | previous] [first | second | third ...] <object>

Examples

go to end of second line
delete next term
copy first function
cut previous argument
delete to end of line
go to line fifty
cut parameter two
delete to end of line five

Syntax

<action> [to] [start of | end of | next | previous | last] (one | two | three ...) <objects>

Examples

select to next parameter
copy previous three characters
delete last two lines
copy functions one to five
delete blocks two to four

FAQ