Category Archives: WindowsOnMac

PowerShell String.Split() Off-by-Method-Overload Error

This seemed to me an error and I and was on the point of raising it as a bug on the Powershell github repo:

PS> "\this".Split( [char]'\', [StringSplitOptions]::RemoveEmptyEntries).Length
# >> 2

Presumably it is because [StringSplitOptions]::RemoveEmptyEntries is coerced to a [char] and so the line is parsed as:

PS> "\this".Split( ([char]'\', [StringSplitOptions]::RemoveEmptyEntries) ).Length

Instead of as

PS> \this".Split( (,[char]'\'), [StringSplitOptions]::RemoveEmptyEntries).Length

If the first parameter is a string not a character then it works as expected:

PS> "\this".Split( '\', [StringSplitOptions]::RemoveEmptyEntries).Length
# >> 1

But the really unfortunate case is :

PS> "\this".Split( [System.IO.Path]::DirectorySeparatorChar, [StringSplitOptions]::RemoveEmptyEntries).Length
# >> 2

which results in

PS> "\this".Split( [System.IO.Path]::DirectorySeparatorChar, [StringSplitOptions]::RemoveEmptyEntries).[0]
# >> $null
# instead of 
# >> "this"

It turns out that it’s fixed in Powershell 6 Beta; or to be more precise, it doesn’t happen in PowerShell 6. What changed is that the underlying .Net framework has added new overloads to String.Split():

string[] Split(char separator, System.StringSplitOptions options)                                                                                    
string[] Split(char separator, int count, System.StringSplitOptions options)                                                                         
string[] Split(string separator, System.StringSplitOptions options)                                                                                  
string[] Split(string separator, int count, System.StringSplitOptions options)                                                                       

Whereas PowerShell 5 only has these overloads available:

string[] Split(Params char[] separator)                                                                                                              
string[] Split(char[] separator, int count)                                                                                                          
string[] Split(char[] separator, System.StringSplitOptions options)                                                                                  
string[] Split(char[] separator, int count, System.StringSplitOptions options)                                                                       
string[] Split(string[] separator, System.StringSplitOptions options)                                                                                
string[] Split(string[] separator, int count, System.StringSplitOptions options)                                                                     

And so the best-match overload that PowerShell 6 chooses is different to PowerShell 5’s best match.

Using Windows keystrokes on a Mac

Alas. I’ve been using Windows so long that now I go back to the Mac and want Ctrl-C to work. Sad, but there it is. At last I found Karabiner, which does keyboard remapping, and created a set of Karabiner rules to map the main Windows Ctrl-keystrokes to the matching ⌘-keystroke on Mac:

Karabiner Rules for main Windows Ctrl-keystrokes on MacOs

Okay, so Ctrl-W isn’t strictly a windows keystroke. But who can work without Ctrl-W?

Karabiner Complex Rules Snippet

 
{
    "profiles": [
        {
            "complex_modifications": {
                "parameters": {  /* ... etc ... */ },
"README": "********************************************************************************************************",
"README": "*" COPY JUST THE ELEMENTS OF THIS "rules" array into your profiles.complex_modifications.rules array. "*",
"README": "********************************************************************************************************",
              
                "rules": [
                    {
                        "description": "Change Control+Z to Command+Z",
                        "manipulators": [ { "from": { "key_code": "z","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "z","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+X to Command+X",
                        "manipulators": [ { "from": { "key_code": "x","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "x","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+C to Command+C",
                        "manipulators": [ { "from": { "key_code": "c","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "c","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+V to Command+V",
                        "manipulators": [ { "from": { "key_code": "v","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "v","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+N to Command+N",
                        "manipulators": [ { "from": { "key_code": "n","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "n","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+S to Command+S",
                        "manipulators": [ { "from": { "key_code": "s","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "s","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+O to Command+O",
                        "manipulators": [ { "from": { "key_code": "o","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "o","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+Y to Command+Y",
                        "manipulators": [ { "from": { "key_code": "y","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "y","modifiers": ["command"]}],"type": "basic"}]
                    },
                    {
                        "description": "Change Control+W to Command+W",
                        "manipulators": [ { "from": { "key_code": "w","modifiers": {"mandatory": ["control"],"optional": ["any"]}},"to": [{"key_code": "w","modifiers": ["command"]}],"type": "basic"}]
                    }
                ],
"README": "******************************************************************************************************",
"README": "******************************************************************************************************",
            /* ... etc ... */
            }
        }
    ]
}

Editing the Keyboard Map

This approach didn’t work for me. I’m not sure what I missed.

‘bash\r’: No such file or directory. Or, editing unix files on a Windows machine

'bash\r': No such file or directory

What does that mean, you ask yourself? It usually means you are editing *nix script files on a windows system, and then running the files on a *nix machine. For instance in docker, or a VM. Your solution is to use a text editor that allows you to save with unix line endings. `Notepad++` calls it, very reasonably, `’EOL conversion’`. Sublime text calls it `View->Line Endings`.

A further complication if you are using git is that it keeps getting reset back to windows. You could fix this with `git config core.autocrlf false` but that may have other consequences which you don’t want to bother with.

AutoHotKey script for they who, being Mac Users and also equipped with an Apple keyboard, yet still they work at a Windows desktop

Surprising how much time you can spend on these little niggles…

  • Irritated that Windows doesn’t have an ellipsis key?
  • Wondering how to do printscreen from your apple keyboard?
  • Really really fed up with swapping between Cut‘n’Paste is “⌘-C,⌘-V” and Cut‘n’Paste is “Ctrl-c-Ctrl-v”?

Help is at hand.

AutoHotKey

When I first came across I was a bit unsure about using AutoHotKey. But I have seen the light. It is the bee’s knees. It is open source, widely used for years, free, small footprint and is the ultimate customise-all-the-things tool for Windows. It is a combined scripting tool & Keyboard/Mouse hotkey manager.

My AutoHotKey for a Mac User with an Apple keyboard on Windows Script

https://gist.github.com/chrisfcarroll/dddf32fea1f29e75f564

There you are. It’s all you need. That, and a few hours to customise it yourself. Then a few more hours to… oh, never mind.

Disclaimer

When I said that AHK is the bee’s knees, I didn’t say that the language isn’t arcane, unintuitive and bearing signs of organic growth over a decade or more…

Apple MacOS UK Keyboard Layout for Windows & the Command key for Control

If like me, you swap between Mac and PC you’ll have been irritated by everso slightly different keyboard layouts. So here’s my Apple Extended UK Keyboard Layout for Windows Installer.

When I wrote it I was using one of these:
Apple Pro Keyboard
But since the Apple full-size layout hasn’t actually changed since then, I still use it for my aluminium keyboard.

Swapping between Mac and Windows

In addition – even if using a PC keyboard – a Mac-PC swapper will undoubtedly suffer repeated Cmd and Ctrl shortcut confusion: You want to type Cmd-X for cut and suddenly the Win-X menu comes up instead.

My preferred solution for this is an AutoHotkey script, partly because after using Autohotkey for a few weeks I realised it was an utterly brilliant, all-singing, all-dancing customise-your-Windows-in-every-way tool, with an all-but-zero footprint.
My script is https://gist.github.com/chrisfcarroll/dddf32fea1f29e75f564, which also has shortcut keys for arranging windows on a big screen.

The other reason I use autohotkey is that it enables a cherry-picking approach to swapping or duplicating Cmd-key/Ctrl-key shortcuts, which I find works much much better than doing a straight Cmd<=>Ctrl key swap. I got this approach from the keyboard layout used by Parallels on the Mac, which simply duplicated common shortcuts such as Ctrl-X, Ctrl-V to the Cmd-key. If you swap regularly between Mac & PC, this approach works well.

Inverting Mouse Scroll Direction

Since about the time that iPhone launched, OS X scroll direction, both mouse and keyboard, has used the metaphor of “push the document up to move it up the window” rather than the previous “push the scroll bar up to move the document down the window.” Windows has stayed firmly on the scrollbar metaphor.
Oddly enough, Microsoft mice come with a Windows driver that let you reverse scroll direction via the UI. For other mice, you can FlipFlopScrollWheel. Oddly, this is not per-user but per mouse/usb port combination, which means if you plug the same mouse into a different port it’s scrolls in the opposite direction.

Back to the Keyboard

If you do want a more complete Cmd<=>Ctrl key swap, then you do it with Randy’s SharpKeys.

Warning! You can’t swap keys around with it so do just this: map Left-Windows key to Left-Control. The right windows key will then still open the Windows menu and do all the Windows-Key stuff that it should do, such as Windows-L for Lock screen/Switch User:

Sharp Keys: Map just the left Windows key to Control key

If you want other keyboards than Apple UK, download the Microsoft Keyboard Layout Creator to tweak your layout.