Keymando Blog

Keyboard automation at its best

Handy Key Mappings for Quick Navigation

| Comments

Here are some mappings I use everyday for navigating applications.

Notice the use of the ‘;’ leader key.

keymandorc.rb
1
2
3
4
5
6
7
  except /(iTerm|MacVim)/ do
    map ";uic", Commands.ui_controls
    map ";lc", Commands.left_click_element
    map ";rc", Commands.right_click_element
    map ";dc", Commands.double_click_element
    map ";mi", Commands.show_current_app_menu_items
  end

Screencast: Leveraging Keymando’s Hit-A-Hint Style Feature for Clicking/pressing Ui Elements

| Comments

In this screencast I walk you through the awesome (and yet still not very well known) feature of being able to have Keymando highlight elements that you want to act on (typically by left clicking, double clicking etc) in a user interface and then trigger them by typing in the identifier.

If you have ever used Pentadactyl or Vimperator, you are already familiar with the feature. In Pentadactyl, when a web page is being displayed, if you press the ‘f’ key, it will highlight all of the clickable links on the page. To click a link, you just have to type in the digits/letters that correspond to the link. As you can imagine, this feature can save quite a lot of time!!

Well, Keymando supports the same style of feture, except you can use it in any OSX based app that supports OSX Accessibility.

In the screencast I show you a sample usage scenario of this awesome feature!

Go here to get the latest version of Keymando, and get busy automating your way through OSX!

Menu Item Automation Example

| Comments

We’re going to start trying to post more examples of how to use different features of Keymando.

Todays example shows how to use the accessibility layer to access menu items and take action. Specifically we’re just going to map a key to simply reload a page in Google Chrome.

Obviously we could simply map our trigger, , in this case, to .

keymandorc.rb
1
  map "<Ctrl-r>", "<Cmd-r>"

But as a demonstration, let’s do the same thing through the Accessibility Gateway.

keymandorc.rb
1
2
3
4
5
  map "<Ctrl-r>" do
    app = Accessibility::Gateway.get_application_by_name "Google Chrome"
    menu_item = app.menu_bar.find.first_item_matching(:role => Matches.partial("menuitem"), :title => Matches.exact("Reload This Page"))
    menu_item.press
  end

From this we can see we’re simply get the application by name, Google Chrome, then doing a search to find the menu item we want, “Reload This Page”. In a later post we’ll show you how to get all the menu items of an application using Keymando’s accessibility layer, but for this post we’ll assume you just found the menu item name via Chome’s menu bar. After that we just “press” the menu item.

For more information about using the accessibility features of Keymando, visit the ever-updating docs at

http://updates.keymando.com/releases/current/doc/

Feel free to ask send questions to contact@keymando.com and we’ll try our best to answer them. We’ll do our best to post answers here to blog if we think they’d be helpful to other users.

Keymando No Longer Available in App Store

| Comments

Like several other applications recently, we’ve also made the decision to move Keymando out the App Store.

This is due to two main reasons:

  • Updates can be released much, much faster.
  • Keymando makes use of low level libraries that no longer qualifies Keymando to be approved for the App Store.

This is unfortunate, but rest assure we’re committed to the development of Keymando and want to make sure all of you who bought Keymando from the App Store continue to receive the latest updates.

Please email us at contact@keymando.com with your name, order number or receipt email and we’ll send you a new license right away.

Thanks, The Keymando Team

Webinar: Curious About What the Current Version of Keymando Can Do?

| Comments

Are you an existing Keymando user, or are you curious about what it can actually do for the keyboard ninja in you?

A lot of existing Keymando users are barely scratching the surface of what can be done with the product. This is due to mostly 2 things:

  1. Lack of documentation on how to manipulate the underlying engine(Sorry about that everyone! We are working to remedy this)
  2. Not quite sure of exactly what it can do as both a key remapper, and more importantly general purpose keyboard automation.

Please join in on a webinar that will help open the doors a little on what is possible with the tool and more importantly, your creativity and imagination!!

The presentation will take place tomorrow at 12PM MST.

Register here.

Keymando vNext - Automate Your OSX World

| Comments

Between working full time jobs and lots of other responsibilities, Kevin and I are putting the final touches on the next release of Keymando!!

For a long time, we have observed that a large majority of Keymando users are using the tool for just basic shortcut remapping. Since we both use this tool all the time, it is now time to show off some of things it can do, and believe me when I say, that using it for jusk key remapping is a big waste of its potential.

Over the course of the next couple of weeks, I am going to be giving presentations to existing, and hopefully some new users, to show them what they can do with this tool, and the infinite customizations that are now possible with a bit of Ruby magic!!

If you take a look at my current Keymando Configuration Scripts you can see how “basic” my regular shortcut mapping is:

Main Configuration Script - keymandorc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
toggle "<Cmd-9>"
map "<Cmd-e>", "<Escape>"
map "<Cmd-Shift-d>", "<Cmd-Shift-Tab>"
map "<Cmd-d>", current_app_windows
map "<Cmd-f>", trigger_app
map "<Cmd-Shift-f>", "<Cmd-Tab>"
map "<Cmd-h>", "<Left>"
map "<Cmd-j>", "<Down>"
map "<Cmd-k>", "<Up>"
map "<Cmd-l>", "<Right>"
map "<Cmd-m>", "<Tab>"
map "<Cmd-,>", "<Shift-Tab>"
map "<Cmd-n>", "<Ctrl-n>"
map "<Cmd-r>", RightClick.instance
map "<Cmd-0>", "<Cmd-Shift-D>"
map "<Cmd-o>",RunLastCommand.instance
map "<Cmd- >", launch_app
map "<Cmd-i>", RunHistoryItem.instance
map "<Cmd-p>", hit_a_hint
map "<Cmd-y>", run_registered_command

The 2 biggest new changes to the Keymando internal engine is that almost everything is modelled as commands. This allows for history, replaying and a host of other features. And the 2nd biggest new feature is the addition of an automation layer we are dubbing the Keymando Automation Engine. To see this engine in action, take a look at my script to manipulate iTunes:

iTunes Manipulation - itunes.rb
1
2
3
4
5
6
7
itunes_command_for_button("iTunes Play",/Play\s*space/)
itunes_command_for_button("iTunes Pause",/Pause\s*space/)
itunes_command_for_button("iTunes Stop",/Stop\s*space/)
itunes_command_for_button("iTunes Previous Song",/Previous/)
itunes_command_for_button("iTunes Next Song",/Next/)
itunes_command_for_button("iTunes Increase Volume",/Increase Volume/)
itunes_command_for_button("Decrease iTunes Volume",/Decrease Volume/)

This is code in one of my configuration scripts under my plugins folder. It will setup one command for each iTunes function. Here is the code for the itunes_command_for_button method (written in the same plugin script):

Creating A Command - command.rb
1
2
3
4
5
6
7
def itunes_command_for_button(name,name_reg_ex)
  Command.to_run :description => name do
    add_block do
      itunes_button(name_reg_ex).press
    end
  end
end

Notice the use of the simple dsl for registering a command. This is one of 2 dsl’s for registering commands. At the completion of the dsl block, a new command with the name provided in the description will be place in the set of available commands to run. And finally, the itunes_button method, shows the use of the Keymando Automation Engine to find the actual button:

Using The Keymando Accessibility API - accessibility.rb
1
2
3
4
def itunes_button(name_reg_ex)
  app = Accessibility::Gateway.get_application_by_name "itunes"
  return app.menu_bar.find.first_item_matching(:title => Matches.regex(name_reg_ex))
end

I will be doing more posts on the Automation Engine over the next little while. In the meantime, looking through the scripts in my GitHub repository should give you an idea of what some of the capabilities are.

The net result of registering all of those commands is that when I press Cmd-y (which is my mapping to run a registered command), it will pop up a list of all of the registered commands based on my settings:

Keymando
Uploaded with Skitch!

Keymando - Version 1.0.3 Is Out and a Small Taste of What’s on the Horizon!!

| Comments

Keymando version 1.0.3 is out, and we have opened up a long awaited trial mode so that people can give it a whirl. We understand that a $20 price tag for most developers is not spent lightly, so we want to make sure that people get time to play with it. For anyone who knows me and know what a keyboard freak I am, I can literally say, that I can’t even use a machine that does not have this program on it anymore!! I am going to create some small 1-2 minute screen casts that will demonstrate some of the worflows that I use on a day to day basis.

There are many constructs, algorithms and patterns that go into making this thing sing. Kevin and I are hard at work adding new features, and for now we are going to keep the lid closed on 2 awesome features that are coming down the pipe. I can say with complete confidence that it will revolutionize the way you use osx with the keyboard!!

It is also beneficial to know that we have a small, but growing, community of plugin developers who are writing freely available plugins and making them available through the official keymando plugin repository. 2 that I use quite often are the:

  1. underscore - Great if you like to type with underscores when you code (or if you are like me, all over the place!!)
  2. abbrev - An abbreviation plugin that emulates complex text expansion!!

What more OSX power users and developers need to realize, is that there is so much you can do for customization if you know how to code ruby. For regular users we are keeping the barrier to entry as low as possible and keeping the dsl as “simple” for the 80/20 rule. For developers who know ruby, well, you are really only limited by your imagination.

We are going to be adding more capabilities to the core pipeline that will be exposed to plugin developers, or just simple config scripts. So hold onto your hats!! For now we are also not focusing on any fancy user interfaces, as we are currently focusing on growing the core engine. The pretty UI’s for some of the features will come in time!!

For now, I’ll leave you with a large section of code from my current .keymandorc.rb file (the main configuration script). Keep in mind that some of the code in this file is based on the main line of development!! Hopefully most of it will be self descriptive enough for me to not need to include comments.

Main Configuration File - keymandorc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

# Ignore the following apps
disable "Remote Desktop Connection"
disable /VirtualBox/

#commands----------------------------------------------------
launch_firefox = launch("Firefox")
quit_the_current_application = send_keys("<Cmd-q>", :description => "Quit current application",:remember => true)
vimperator_pass_through_mode = send_keys("<Shift-Escape>")
gmail_send_new_mail = send_keys("<Shift-Tab>" * 6)
gmail_send_reply_mail = send_keys("<Shift-Tab>" * 5)
gmail_discard_new_mail = send_keys("<Shift-Tab>" * 4)
gmail_discard_reply_mail = send_keys("<Shift-Tab>" * 3)
screen_flow_stop_recording = send_keys("<Cmd-Shift-2>")
window_hide_current = send_keys("<Cmd-w>")
#end_commands----------------------------------------------------

#----------------------------------------
#core_shortcuts
#----------------------------------------
toggle "<Cmd-9>"
map "<Cmd-d>","<Cmd-Shift-Tab>"
map "<Cmd-e>", "<Escape>"
map "<Cmd-f>","<Cmd-Tab>"
map "<Cmd-h>", "<Left>"
map "<Cmd-j>", "<Down>"
map "<Cmd-k>", "<Up>"
map "<Cmd-l>", "<Right>"
map "<Cmd-m>", "<Tab>"
map "<Cmd-,>", "<Shift-Tab>"
map "<Cmd-n>", "<Ctrl-n>"
map "<Cmd-r>", RightClick.instance
map "<Cmd-0>", "<Cmd-Shift-D>"
map "<Cmd-c>",RunLastCommand.instance
map "<Cmd- >", launch_quicksilver

# end_core_shortcuts---------------------

#mnemonic_mappings-----------------------
@window_management= {
    "wm" => mercury_mover_move_window,
    "wfs" => Divvy.full_screen,
    "wtl" => Divvy.top_left,
    "wtr" => Divvy.top_right,
    "wbl" => Divvy.bottom_left,
    "wbr" => Divvy.bottom_right,
    "wl" => Divvy.left,
    "wr" => Divvy.right,
    "wt" => Divvy.top,
    "wb" => Divvy.bottom,
    "wc" => Divvy.center,
    "w" => window_hide_current
  }

@itunes = {
  "iiv" => itunes_increase_volume,
  "div" => itunes_decrease_volume,
  "bt" => itunes_browse_tracks
}

@firefox = {
  "fi" => launch_firefox,
  "pp" => vimperator_pass_through_mode
}


@quicksilver ={
  "mi" => show_current_menu_items,
  "wi" => show_current_app_windows
}

@gmail ={
  "msn" => gmail_send_new_mail ,
  "msr" => gmail_send_reply_mail,
  "mdn" => gmail_send_reply_mail,
  "mdr" => gmail_discard_reply_mail
}

@skype ={
  "sl" => skype_login,
  "scp" => skype_call_phones
}

@sound = {
  "sts" => switch_to_speakers,
  "sti" => switch_to_imic
}

@general_mappings = {
  "aa" => app_code_all_items,
  "rel" => reload_configuration,
  "ls" => lock_the_screen,
  "x" => quit_the_current_application,
  "gmm" => gotomeeting_mute_me,
  "sr" => screen_flow_stop_recording,
  "ntt" => things_new_task,
  "jj" => RunHistoryItem.instance
}
#end_mnemonic_mappings------------------------------------------------------------

map "<Cmd-y>" do
  input(@general_mappings
         .merge(@window_management)
         .merge(@itunes)
         .merge(@firefox)
         .merge(@quicksilver)
         .merge(@gmail)
         .merge(@skype)
         .merge(@sound)
        )
end

Happy keyboarding!!

Keymando Intro

| Comments

In this video you are given a whirlwind introduction to the basic features of keymando.