Skip to content

Overriding Default Commands

Ben Meyer edited this page Oct 1, 2015 · 21 revisions

Place your command overriding code in the file:

~/voicecode/commando/user/commands.coffee

Or if that file is getting too busy, create another file in the same directory, maybe named: 'overrides.coffee'

Overview

Often times you want to slightly change how a command operates, add some logic or actions before the command executes, or add some logic or actions after the command executes. A good example would be extending a default command to perform a different action in a certain application, without changing its action in other applications.

VoiceCode takes the approach of allowing multiple "event handlers" for any command, much like typical browser event bubbling in javascript.

These handlers or "extensions" get executed in the reverse order that they are added. So whichever handler is added last, gets executed first.

Furthermore, any handler can call the method @stop() to prevent the further propagation of the handler chain. This allows you to totally override a command's actions, or just add your own customizations but still allow the default action be performed.

This design also allows people to easily share code that will add functionality for a certain context or application, without conflicts.

Extending A Command

Scenario: the "shockoon" command inserts a new line below the current line by moving the cursor all the way to the right, then pressing "return". However, when using applications like Skype, the behavior needs to be different because pressing "return" will accidentally send the current message instead of inserting a new line. So in those cases the command needs to be customized to press 'option-return' instead of just 'return'. Let's see how you would do that:

Commands.extend "shockoon", ->
  if @currentApplication() is "Skype"
    @key 'Right', 'command'
    @key 'Return', 'option'
    @stop()

The above command will check the current application, and if it matches the criteria, will perform its own logic and stop event propagation so the default action does not get called. If it does not match the criteria, this handler will do nothing and the next handler will be called.

Wrapping A Command

Other times you want to keep the default action, but "wrap" your own code around the defaults. To do this you can hook into before and after actions. These before and after actions have their own chain of propagation, independent from the core command and its overrides - therefore ALL 'before' actions get executed in order before the command and its extensions get executed. Finally, after the command executes, all of the 'after' actions get executed in order.

Here is an example that illustrates the concept:

Commands.before "snake", (input)  ->
  console.log "starting the snake command with input: #{input}"

Or doing something after the command executes like:

Commands.after "snake", (input)  ->
  console.log "just finished the snake command with input: #{input}"

Using these before and after hooks allows you to add your own logic, without completely over-writing the default command's action. That way if the command is updated or enhanced, you still get the update, and your customizations are still applied on top of it.

For example, imagine if whenever I used the "shackle" command to select an entire line of text, I also wanted to perform a "copy" keystroke afterwards, but only if I am in the Mail application. I could do this:

Commands.after "shackle", ->
  if @currentApplication() is "Mail"
    @key "C", 'command'

You can get as fancy as you want with these extensions so that VoiceCode gets tailored to your specific workflows and use-cases.

Changing a command's name

Occasionally you may have some reason to change the name of a built-in command. To achieve this, simply do:

Commands.changeName "old name", "new name"

Changing a command's properties

If you want to change some properties of an existing command you can do it like this:

Commands.mapping.skoosh.description = "some new description"

Misspellings

Sometimes Dragon Dictate mis-recognizes a command name. If you find that this happens predictably with a certain command, you can add a 'spelling'. A Misspelling is an alternate pronunciation or spelling. This means that the command will be triggered when it's name is spoken AND when the alternate spelling is spoken.

Commands.addMisspellings "shock", ["shocks", "shox"]

Note: Adding a misspelling, does not create a new "root-level" command; It is only intended to fix mis-spellings in command chains / phrases. So it would not make sense to add an alias that sounds significantly different than the original. For that, you should simply create a new command that mimics the original command, or simply rename the original command.

Clone this wiki locally