Keyboard configuration for Windows’ developers on OS X (& also IntelliJ)

Recently I've been doing some ActionScript programming. Rather than target a Flash Player app. I've been using ActionScript in combination with Adobe AIR in order to create an iOS app. This has meant I've been spending time in OS X and using IntelliJ with the the ActionScript/Flex/AIR plugin as my IDE.

Most of my previous work has been done on UNIX (so command lines & vi) and Windows. In particular I depend on the various Windows & Visual Studio editor key combinations plus the Insert, Delete, Home & End keys. For starters this means I use a PC keyboard with the iMac rather than the Apple keyboard as it lacks these keys; I'm also based in the UK so I use a British PC keyboard.

In addition to these keys I wanted the following combos to be available across all of OS X and any apps.
  • Alt-Tab to cycle through apps.
  • Ctrl-F for find.
  • Ctrl-S for save current document (I habitually press this whilst editing).
  • Ctrl-C & Ctrl-V for copy & paste.
  • Ctrl-Z for undo.
  • Obtain the correct behaviour for the '\|' key and the '`¬' key. They were swapped initially.
  • '@' & '"' correctly mapped.
Additionally, I wanted these combos to be available in IntelliJ:
  • Ctrl-Left Arrow & Ctrl-Right Arrow to move the previous/next word respectively
    • Plus their selected text equivalents.
  • Ctrl-Home/Ctrl-End to move to the top/bottom of the document being edited.
This post is a description of what I installed & configured to allow to
achieve this.

Configuring a British PC keyboard

The first step was to tell OS X I was using a PC keyboard, specifically a British one. This is achieved through the System Preferences->Keyboard->Input Sources.



Here new input sources can be added by clicking the '+'. I added 'British - PC'. Adding doesn't mean it will be used though. For this also check the 'Show Input menu in menu bar' option. This adds a country flag and the name of the input source. Clicking on this allows the input source to be changed. If you swap between a PC keyboard and the iMac keyboard (which I do from time to time) this is an easy way to swap.



What all this gives you is the '"' and '@' keys in the right place. Otherwise they're transposed. Note: backslash and backquote remain transposed.

Windows' key combos

The second step was obtaining the Windows' key combos. This requires mapping the Windows' combos to the corresponding OS X combos whilst preventing the Windows' combos being interpreted as something else. After some searching it seemed like the preferred solution to this is using a 3rd party program called KeyRemap4MacBook. According to various reviews it does the job well but configuring it, especially creating your own mappings is complicated. The former being down to the UI and the latter to the XML format. All these things are true but once you've got used to it, like a lot of things it's nowhere near as daunting as it first seems; and the document is very good too. Part of the motivation for this post is to record the configuration & steps for my benefit should I need to do it again.

KeyRemap4MacBook comes with a number of canned mappings. In addition to mapping across the board they can be limited to include or exclude a specific set of apps. In particular I make use of a set of pre-defined mappings from the 'For PC Users' section which won't be applied in VMs (generally running Windows, especially useful when running Windows 8 in Parallels from the Bootcamp partition) and terminals.

As I still use the Apply keyboard from time to time when I want to do very Apple-ly stuff I have the 'Don't remap  Apple's keyboards' option enabled.

What I use

The canned mappings I use from 'For PC Users' section are:
  • Use PC Style Copy/Paste
  • Use PC Style Undo
  • Use PC Style Save
  • Use PC Style Find
These can easily be seen these in KeyRemap4MacBook using the 'show enabled only' (from the many definitions) option:



Without doing very little work this meets the majority of my needs. In addition to the 'For PC Users' and 'General' section you may also notice the three re-mappings at the start. These are custom mappings I had to create. I'm not going to explain the XML format as this is available from the documentation. Instead, here are my custom mappings.

<?xml version="1.0"?>
<root>
 <appdef>
  <appname>INTELLIJ</appname>
  <equal>com.jetbrains.intellij</equal>
 </appdef>

 <replacementdef>
  <replacementname>MY_IGNORE_APPS</replacementname>
  <replacementvalue>VIRTUALMACHINE, TERMINAL, REMOTEDESKTOPCONNECTION, VNC, INTELLIJ</replacementvalue>
 </replacementdef>

 <replacementdef>
  <replacementname>MY_IGNORE_APPS_APPENIDX</replacementname>
  <replacementvalue>(Except in Virtual Machine, Terminal, RDC, VNC and IntelliJ)</replacementvalue>
 </replacementdef>


 <item>
  <name>Use PC style alt-TAB for application switching</name>
  <appendix>{{ MY_IGNORE_APPS_APPENIDX }}</appendix>
  <identifier>private.swap_alt-tab_and_cmd-tab</identifier>
  <not>{{ MY_IGNORE_APPS }}</not>
  <autogen>__KeyToKey__ KeyCode::TAB, ModifierFlag::OPTION_L, KeyCode::TAB, ModifierFlag::COMMAND_L</autogen>
 </item>

 <item>
  <name>Swap backslash and backquote for British PC keyboard</name>
  <identifier>private.swap_backslash_and_quote_for_britishpc</identifier>
  <autogen>__KeyToKey__ KeyCode::DANISH_DOLLAR, KeyCode::BACKQUOTE</autogen>
  <autogen>__KeyToKey__ KeyCode::BACKQUOTE, KeyCode::DANISH_DOLLAR</autogen>
 </item>

 <item>
  <name>Use PC Ctrl-Home/End to move to top/bottom of document</name>
  <appendix>{{ MY_IGNORE_APPS_APPENIDX }}</appendix>
  <identifier>private.use_PC_ctrl-home/end</identifier>
  <not>{{ MY_IGNORE_APPS }}</not>
  <autogen>__KeyToKey__ KeyCode::HOME, ModifierFlag::CONTROL_L, KeyCode::CURSOR_UP, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::HOME, ModifierFlag::CONTROL_R, KeyCode::CURSOR_UP, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::END, ModifierFlag::CONTROL_L, KeyCode::CURSOR_DOWN, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::END, ModifierFlag::CONTROL_R, KeyCode::CURSOR_DOWN, ModifierFlag::COMMAND_L</autogen>
 </item>

</root>

I didn't want these mappings other than swapping backslash and backquote to be applied in various apps. i.e. VMs, VNC & RDC (where Windows is running anyway) and Terminal where it interferes with bash. To enable this I used the <not> element giving a list of excluded apps. along with using the appendix element to state this in the description.

Rather than copy the list of apps. and description I used KeyRemap4MacBook's replacement macro feature. There is a list of builtin apps. that can be referred too but I also looked at the XML file from the source that contains the 'For PC Users' mapping.

The _L & _R refer to keys which appear twice: on the left & right side of the keyboard.

The format allows multiple mappings to be grouped. These don't have to be similar but this the intention, i.e. all the ctrl-home/end mappings are together. Each <autogen> entry is a separate mapping but they are enabled/disabled collectively.

The format isn't too bad. The weird thing from an XML perspective is the <autogen> element. This is source combo followed by combo to generate instead separated by a comma. I think it would be easier to understand if this element were broken down into child elements with say <to> and <from> elements.

This private.xml is also available as a GIST.

IntelliJ

IntelliJ complicates things slightly as it provides its own key-mapping functionality similar to that of KeyRemap4MacBook but solely for itself. This means that there can be a conflict with KeyRemap4MacBook.

I'm writing this a while after I originally implemented it. In fact part of the reason I'm writing this post at all is so I have a record of what's required. Since getting this working it looks like I've changed my IntelliJ Keymap (from Preferences). Originally it was set to 'Mac OS X' but is now set to 'Default'.

When is was set to 'Mac OS X' the KeyRemap4MacBook mappings worked well except that Ctrl-Home/End wouldn't work. This is because that combination is mapped to something else. Additionally the 'Mac OS X' mappings don't provide support for Ctrl-Left/Right-Arrow for hoping back and forth over words. My initial solution to this was to modify (by taking a copy) the 'Mac OS X' mapping:
  • Change 'Move Caret to Next Word' from 'alt ->' to 'ctrl->'.
  • Change 'Move Caret to Previous Word' from 'alt <-' to 'ctrl <-'.
  • Change 'Move Caret to Next Word with Selection' from 'alt shift ->' to 'ctrl shift ->'.
  • Change 'Move Caret to Previous Word with Selection' from 'alt shift <-' to 'ctrl shift <-'.
  • Change 'Move Caret to Text End' from 'cmd end' to 'ctrl end'.
  • Change 'Move Caret to Text Start' from 'cmd home' to 'ctrl home'.
However, it seems that the 'Default' key mappings are as per-Windows but when KeyRemap4MacBook is running they all conflict. In fact I may have missed this completely when initially figuring this out.

Therefore the far easier solution is to select the 'Default' IntelliJ mapping and using KeyRemap4MacBook make it aware of IntelliJ and exclude it from key re-mapping as per the other applications. This is the purpose of the appdef section in private.xml. KeyRemap4MacBook doesn't need definitions for other excluded apps. as these are built-in.

The mappings are not perfect. IntelliJ is great but this is now down to IntelliJ's mapping and having excluded it from KeyRemap4MacBook mapping. I still miss Ctrl-Left/Right-Arrow and Ctrl-Home/End in other apps. but hopefully this should just be a case of defining more mappings and the Ctrl-Z (undo) mapping effectiveness seems to vary.



Keyboard configuration for Windows’ developers on OS X (& also IntelliJ)

Recently I've been doing some ActionScript programming. Rather than target a Flash Player app. I've been using ActionScript in combination with Adobe AIR in order to create an iOS app. This has meant I've been spending time in OS X and using IntelliJ with the the ActionScript/Flex/AIR plugin as my IDE.

Most of my previous work has been done on UNIX (so command lines & vi) and Windows. In particular I depend on the various Windows & Visual Studio editor key combinations plus the Insert, Delete, Home & End keys. For starters this means I use a PC keyboard with the iMac rather than the Apple keyboard as it lacks these keys; I'm also based in the UK so I use a British PC keyboard.

In addition to these keys I wanted the following combos to be available across all of OS X and any apps.
  • Alt-Tab to cycle through apps.
  • Ctrl-F for find.
  • Ctrl-S for save current document (I habitually press this whilst editing).
  • Ctrl-C & Ctrl-V for copy & paste.
  • Ctrl-Z for undo.
  • Obtain the correct behaviour for the '\|' key and the '`¬' key. They were swapped initially.
  • '@' & '"' correctly mapped.
Additionally, I wanted these combos to be available in IntelliJ:
  • Ctrl-Left Arrow & Ctrl-Right Arrow to move the previous/next word respectively
    • Plus their selected text equivalents.
  • Ctrl-Home/Ctrl-End to move to the top/bottom of the document being edited.
This post is a description of what I installed & configured to allow to
achieve this.

Configuring a British PC keyboard

The first step was to tell OS X I was using a PC keyboard, specifically a British one. This is achieved through the System Preferences->Keyboard->Input Sources.



Here new input sources can be added by clicking the '+'. I added 'British - PC'. Adding doesn't mean it will be used though. For this also check the 'Show Input menu in menu bar' option. This adds a country flag and the name of the input source. Clicking on this allows the input source to be changed. If you swap between a PC keyboard and the iMac keyboard (which I do from time to time) this is an easy way to swap.



What all this gives you is the '"' and '@' keys in the right place. Otherwise they're transposed. Note: backslash and backquote remain transposed.

Windows' key combos

The second step was obtaining the Windows' key combos. This requires mapping the Windows' combos to the corresponding OS X combos whilst preventing the Windows' combos being interpreted as something else. After some searching it seemed like the preferred solution to this is using a 3rd party program called KeyRemap4MacBook. According to various reviews it does the job well but configuring it, especially creating your own mappings is complicated. The former being down to the UI and the latter to the XML format. All these things are true but once you've got used to it, like a lot of things it's nowhere near as daunting as it first seems; and the document is very good too. Part of the motivation for this post is to record the configuration & steps for my benefit should I need to do it again.

KeyRemap4MacBook comes with a number of canned mappings. In addition to mapping across the board they can be limited to include or exclude a specific set of apps. In particular I make use of a set of pre-defined mappings from the 'For PC Users' section which won't be applied in VMs (generally running Windows, especially useful when running Windows 8 in Parallels from the Bootcamp partition) and terminals.

As I still use the Apply keyboard from time to time when I want to do very Apple-ly stuff I have the 'Don't remap  Apple's keyboards' option enabled.

What I use

The canned mappings I use from 'For PC Users' section are:
  • Use PC Style Copy/Paste
  • Use PC Style Undo
  • Use PC Style Save
  • Use PC Style Find
These can easily be seen these in KeyRemap4MacBook using the 'show enabled only' (from the many definitions) option:



Without doing very little work this meets the majority of my needs. In addition to the 'For PC Users' and 'General' section you may also notice the three re-mappings at the start. These are custom mappings I had to create. I'm not going to explain the XML format as this is available from the documentation. Instead, here are my custom mappings.

<?xml version="1.0"?>
<root>
 <appdef>
  <appname>INTELLIJ</appname>
  <equal>com.jetbrains.intellij</equal>
 </appdef>

 <replacementdef>
  <replacementname>MY_IGNORE_APPS</replacementname>
  <replacementvalue>VIRTUALMACHINE, TERMINAL, REMOTEDESKTOPCONNECTION, VNC, INTELLIJ</replacementvalue>
 </replacementdef>

 <replacementdef>
  <replacementname>MY_IGNORE_APPS_APPENIDX</replacementname>
  <replacementvalue>(Except in Virtual Machine, Terminal, RDC, VNC and IntelliJ)</replacementvalue>
 </replacementdef>


 <item>
  <name>Use PC style alt-TAB for application switching</name>
  <appendix>{{ MY_IGNORE_APPS_APPENIDX }}</appendix>
  <identifier>private.swap_alt-tab_and_cmd-tab</identifier>
  <not>{{ MY_IGNORE_APPS }}</not>
  <autogen>__KeyToKey__ KeyCode::TAB, ModifierFlag::OPTION_L, KeyCode::TAB, ModifierFlag::COMMAND_L</autogen>
 </item>

 <item>
  <name>Swap backslash and backquote for British PC keyboard</name>
  <identifier>private.swap_backslash_and_quote_for_britishpc</identifier>
  <autogen>__KeyToKey__ KeyCode::DANISH_DOLLAR, KeyCode::BACKQUOTE</autogen>
  <autogen>__KeyToKey__ KeyCode::BACKQUOTE, KeyCode::DANISH_DOLLAR</autogen>
 </item>

 <item>
  <name>Use PC Ctrl-Home/End to move to top/bottom of document</name>
  <appendix>{{ MY_IGNORE_APPS_APPENIDX }}</appendix>
  <identifier>private.use_PC_ctrl-home/end</identifier>
  <not>{{ MY_IGNORE_APPS }}</not>
  <autogen>__KeyToKey__ KeyCode::HOME, ModifierFlag::CONTROL_L, KeyCode::CURSOR_UP, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::HOME, ModifierFlag::CONTROL_R, KeyCode::CURSOR_UP, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::END, ModifierFlag::CONTROL_L, KeyCode::CURSOR_DOWN, ModifierFlag::COMMAND_L</autogen>
  <autogen>__KeyToKey__ KeyCode::END, ModifierFlag::CONTROL_R, KeyCode::CURSOR_DOWN, ModifierFlag::COMMAND_L</autogen>
 </item>

</root>

I didn't want these mappings other than swapping backslash and backquote to be applied in various apps. i.e. VMs, VNC & RDC (where Windows is running anyway) and Terminal where it interferes with bash. To enable this I used the <not> element giving a list of excluded apps. along with using the appendix element to state this in the description.

Rather than copy the list of apps. and description I used KeyRemap4MacBook's replacement macro feature. There is a list of builtin apps. that can be referred too but I also looked at the XML file from the source that contains the 'For PC Users' mapping.

The _L & _R refer to keys which appear twice: on the left & right side of the keyboard.

The format allows multiple mappings to be grouped. These don't have to be similar but this the intention, i.e. all the ctrl-home/end mappings are together. Each <autogen> entry is a separate mapping but they are enabled/disabled collectively.

The format isn't too bad. The weird thing from an XML perspective is the <autogen> element. This is source combo followed by combo to generate instead separated by a comma. I think it would be easier to understand if this element were broken down into child elements with say <to> and <from> elements.

This private.xml is also available as a GIST.

IntelliJ

IntelliJ complicates things slightly as it provides its own key-mapping functionality similar to that of KeyRemap4MacBook but solely for itself. This means that there can be a conflict with KeyRemap4MacBook.

I'm writing this a while after I originally implemented it. In fact part of the reason I'm writing this post at all is so I have a record of what's required. Since getting this working it looks like I've changed my IntelliJ Keymap (from Preferences). Originally it was set to 'Mac OS X' but is now set to 'Default'.

When is was set to 'Mac OS X' the KeyRemap4MacBook mappings worked well except that Ctrl-Home/End wouldn't work. This is because that combination is mapped to something else. Additionally the 'Mac OS X' mappings don't provide support for Ctrl-Left/Right-Arrow for hoping back and forth over words. My initial solution to this was to modify (by taking a copy) the 'Mac OS X' mapping:
  • Change 'Move Caret to Next Word' from 'alt ->' to 'ctrl->'.
  • Change 'Move Caret to Previous Word' from 'alt <-' to 'ctrl <-'.
  • Change 'Move Caret to Next Word with Selection' from 'alt shift ->' to 'ctrl shift ->'.
  • Change 'Move Caret to Previous Word with Selection' from 'alt shift <-' to 'ctrl shift <-'.
  • Change 'Move Caret to Text End' from 'cmd end' to 'ctrl end'.
  • Change 'Move Caret to Text Start' from 'cmd home' to 'ctrl home'.
However, it seems that the 'Default' key mappings are as per-Windows but when KeyRemap4MacBook is running they all conflict. In fact I may have missed this completely when initially figuring this out.

Therefore the far easier solution is to select the 'Default' IntelliJ mapping and using KeyRemap4MacBook make it aware of IntelliJ and exclude it from key re-mapping as per the other applications. This is the purpose of the appdef section in private.xml. KeyRemap4MacBook doesn't need definitions for other excluded apps. as these are built-in.

The mappings are not perfect. IntelliJ is great but this is now down to IntelliJ's mapping and having excluded it from KeyRemap4MacBook mapping. I still miss Ctrl-Left/Right-Arrow and Ctrl-Home/End in other apps. but hopefully this should just be a case of defining more mappings and the Ctrl-Z (undo) mapping effectiveness seems to vary.



Using IntelliJ, Adobe ActionScript and AIR SDK to create & package iOS 7 apps.

Just a quick post. Lately I've been learning ActionScript. Having seen how easy it is to get an ActionScript project for Flash Player running on Android using Adobe AIR I wanted to do the same for my iPhone. Getting stuff running on the AIR emulator and on the iOS simulator (under OS X) and AIR was pretty easy. In my case this was using IntelliJ as the IDE (rather than Flash Builder) coupled with Flex 4.6 SDK. The real fun started when I started to package my application for submission to the App Store, in particular creating the App icons.

The version of the AIR SDK that comes with the Flex 4.6 SDK is 3.1. However this isn't aware of the new iOS 7 App icons. It would seem a simple matter of adding additional entries to the Application Descriptor file, i.e. to support the the 152x152 icon just add

<image152x152>icon152.png</image152x152>

to the <icon> section. Unfortunately the schema knows this isn't valid (well doesn't know about) and you end up with the following error:

error 103: application.icon.image152x152 is an unexpected element/attribute

To fix, the first step is to download & install the latest version AIR SDK which is 3.9 (4.0 beta aside). This does not mean download & install the latest version of the Flex SDK as this contains an older version of the AIR SDK. Also, as this needs installing on top of the one present in the existing Flex SDK installation do not download the installer version, instead use the zip (Windows) or tbz2 (OS X). The following link takes you to both: http://www.adobe.com/devnet/air/air-sdk-download.html

Then extract these within the Flex SDK (you might want to take a copy of this first but if things go wrong you can always re-download it). The easiest way is to just copy/move the archive to the Flex SDK directory and extract the files there which will overwrite the existing ones.

NOTE: Up to this point the same thing occurred on both Windows & OS X. The following steps only worked on OS X. In particular updating the scheme in the Application Descriptor didn't work and when reverted back to 3.1 (& support for iOS 7 App Icons removed) then packaging the app. was a problem as the AIR SDK seemed to be missing various binaries to create the ARM binaries. I haven't pursued this further as I was working on OS X at this point.

In theory everything should work now. However if you proceed to package the app. it will still give the same 103 error. This is because the scheme version number in the Application Descriptor needs updating. Most likely the line will be:

<application xmlns="http://ns.adobe.com/air/application/3.1">

the 3.1 needs changing to 3.9.

This may not fix the problem though. If you're using IntelliJ (sorry don't know about Flash Builder) and have selected the 'Generated' option for the Application Descriptor then it appears by default IntelliJ (AIR?) creates this with a version of 3.1. In this case you'll need to stop using this option. Instead choose the 'Custom template' and either create your own or have IntelliJ (AIR?) generate one for you. If you choose the latter option then IntelliJ offers a drop down to specify the version. However, it only lists 3.1 to 3.8. Therefore this will need manually changing to 3.9.


At this point it should be possible to successfully package an iOS app with iOS 7 App Icon support.

Using IntelliJ, Adobe ActionScript and AIR SDK to create & package iOS 7 apps.

Just a quick post. Lately I've been learning ActionScript. Having seen how easy it is to get an ActionScript project for Flash Player running on Android using Adobe AIR I wanted to do the same for my iPhone. Getting stuff running on the AIR emulator and on the iOS simulator (under OS X) and AIR was pretty easy. In my case this was using IntelliJ as the IDE (rather than Flash Builder) coupled with Flex 4.6 SDK. The real fun started when I started to package my application for submission to the App Store, in particular creating the App icons.

The version of the AIR SDK that comes with the Flex 4.6 SDK is 3.1. However this isn't aware of the new iOS 7 App icons. It would seem a simple matter of adding additional entries to the Application Descriptor file, i.e. to support the the 152x152 icon just add

<image152x152>icon152.png</image152x152>

to the <icon> section. Unfortunately the schema knows this isn't valid (well doesn't know about) and you end up with the following error:

error 103: application.icon.image152x152 is an unexpected element/attribute

To fix, the first step is to download & install the latest version AIR SDK which is 3.9 (4.0 beta aside). This does not mean download & install the latest version of the Flex SDK as this contains an older version of the AIR SDK. Also, as this needs installing on top of the one present in the existing Flex SDK installation do not download the installer version, instead use the zip (Windows) or tbz2 (OS X). The following link takes you to both: http://www.adobe.com/devnet/air/air-sdk-download.html

Then extract these within the Flex SDK (you might want to take a copy of this first but if things go wrong you can always re-download it). The easiest way is to just copy/move the archive to the Flex SDK directory and extract the files there which will overwrite the existing ones.

NOTE: Up to this point the same thing occurred on both Windows & OS X. The following steps only worked on OS X. In particular updating the scheme in the Application Descriptor didn't work and when reverted back to 3.1 (& support for iOS 7 App Icons removed) then packaging the app. was a problem as the AIR SDK seemed to be missing various binaries to create the ARM binaries. I haven't pursued this further as I was working on OS X at this point.

In theory everything should work now. However if you proceed to package the app. it will still give the same 103 error. This is because the scheme version number in the Application Descriptor needs updating. Most likely the line will be:

<application xmlns="http://ns.adobe.com/air/application/3.1">

the 3.1 needs changing to 3.9.

This may not fix the problem though. If you're using IntelliJ (sorry don't know about Flash Builder) and have selected the 'Generated' option for the Application Descriptor then it appears by default IntelliJ (AIR?) creates this with a version of 3.1. In this case you'll need to stop using this option. Instead choose the 'Custom template' and either create your own or have IntelliJ (AIR?) generate one for you. If you choose the latter option then IntelliJ offers a drop down to specify the version. However, it only lists 3.1 to 3.8. Therefore this will need manually changing to 3.9.


At this point it should be possible to successfully package an iOS app with iOS 7 App Icon support.