I would like to determine the OS X keyboard layout (or \"input source\" as OS X calls it) from the terminal so that I can show it in places like the tmux status bar.
I am not sure of this answer, but it may be worth checking out. If you look in file:
/Library/Preferences/com.apple.HIToolbox.plist
there is a variable called
AppleCurrentKeyboardLayoutSourceID
and mine is set to "British" and I am in Britain...
You can read the file in a script with:
defaults read /Library/Preferences/com.apple.HIToolbox.plist AppleEnabledInputSources
sample output below:
(
{
InputSourceKind = "Keyboard Layout";
"KeyboardLayout ID" = 2;
"KeyboardLayout Name" = British;
}
)
So, I guess your question can be simply answered using this:
#!/bin/bash
defaults read /Library/Preferences/com.apple.HIToolbox.plist AppleEnabledInputSources | grep -sq Swedish
[[ $? -eq 0 ]] && echo Swedish
This question led to the creation of the keyboardSwitcher CLI Tool: https://github.com/Lutzifer/keyboardSwitcher
Though similar to the already mentioned https://github.com/myshov/xkbswitch-macosx this has additional features, e.g. the list of Layouts is not hardcoded and thus can also support third party layouts (e.g. Logitech) and supports installation via homebrew.
I was searching for an answer to an issue I was having with the keyboard layout that lead me to this post. I found the solution for my problem here.
Resolved Issues You might experience difficulty logging into your account because the keyboard layout may change unexpectedly at the Login window. (40821875)
Workaround: Log in to your account, launch Terminal, and execute the following command:
sudo rm -rf /var/db/securityagent/Library/Preferences/com.apple.HIToolbox.plist
This is an Apple official release note for Mojave
Note: @MarkSetchell deserves credit for coming up with the fundamental approach - where to [start to] look and what tools to use. After further investigation and back and forth in the comments I thought I'd summarize the solution (as of OS X 10.9.1):
do shell script "defaults read ~/Library/Preferences/com.apple.HIToolbox.plist \\
AppleSelectedInputSources | \\
egrep -w 'KeyboardLayout Name' | sed -E 's/^.+ = \"?([^\"]+)\"?;$/\\1/'"
Note how \
is escaped as \\
for the benefit of AppleScript, which ensures that just \
reaches the shell. If you want to execute the same command directly from the shell (as one line), it would be:
defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | egrep -w 'KeyboardLayout Name' |sed -E 's/^.+ = \"?([^\"]+)\"?;$/\1/'
~/Library/Preferences/com.apple.HIToolbox.plist
, top-level key AppleSelectedInputSources
, subkey KeyboardLayout Name
.defaults read
ensures that the current settings are read (sadly, as of OSX 10.9, the otherwise superior /usr/libexec/PlistBuddy
sees only a cached version, which may be out of sync).defaults read
cannot return an individual key's value, the value of interest must be extracted via egrep
and sed
- one caveat there is that defaults read
conditionally uses double quotes around key names and string values, depending on whether they are a single word (without punctuation) or not.Update:
Turns out that AppleScript itself can parse property lists, but it's a bit like pulling teeth. Also, incredibly, the potentially-not-fully-current-values problem also affects AppleScript's parsing.
Below is an AppleScript handler that gets the current keyboard layout; it uses a do shell script
-based workaround to ensure that the plist file is current, but otherwise uses AppleScript's property-list features, via the Property List Suite
of application System Events
.
Note: Obviously, the above shell-based approach is much shorter in this case, but the code below demonstrates general techniques for working with property lists.
# Example call.
set activeKbdLayout to my getActiveKeyboardLayout() # ->, e.g., "U.S."
on getActiveKeyboardLayout()
# Surprisingly, using POSIX-style paths (even with '~') works with
# the `property list file` type.
set plistPath to "~/Library/Preferences/com.apple.HIToolbox.plist"
# !! First, ensure that the plist cache is flushed and that the
# !! *.plist file contains the current value; simply executing
# !! `default read` against the file - even with a dummy
# !! key - does that.
try
do shell script "defaults read " & plistPath & " dummy"
end try
tell application "System Events"
repeat with pli in property list items of ¬
property list item "AppleSelectedInputSources" of ¬
property list file plistPath
# Look for (first) entry with key "KeyboardLayout Name" and return
# its value.
# Note: Not all entries may have a 'KeyboardLayout Name' key,
# so we must ignore errors.
try
return value of property list item "KeyboardLayout Name" of pli
end try
end repeat
end tell
end getActiveKeyboardLayout
Recently I had written a small console utility (https://github.com/myshov/xkbswitch-macosx) on Objective-C to do this. It's a lot faster than a script based solutions. It can to get the current input layout but also it can to set the given input layout.
To get a current layout:
$xkbswitch -ge
> US
To set a given layout:
$xkbswith -se Russian
Figured out how to do it with AppleScript, assuming you have the menu bar input menu.
Run this in a terminal:
osascript -e 'tell application "System Events" to tell process "SystemUIServer" to get the value of the first menu bar item of menu bar 1 whose description is "text input"'
Works fine even if you only show the input menu as flag icons, without the input source name.
Mavericks will probably prompt you to allow access, the first time. In earlier versions of OS X I suspect you'll need to turn on support for assistive devices in your accessibility preferences.