How to switch the keyboard input language from the terminal

applescriptbashinput-sourcekeyboardterminal

I already have one way to do this:

function input-switch-darwin() {
    cliclick kd:ctrl kp:space ku:ctrl
}

But this is very slow:

❯ time cliclick kd:ctrl kp:space ku:ctrl
cliclick kd:ctrl kp:space ku:ctrl  0.02s user 0.03s system 13% cpu 0.434 total; max RSS 7088

Best Answer

Thanks to the tip by @user3439894, I found an answer (you need ripgrep and https://github.com/myshov/xkbswitch-macosx installed):

ec() print -r -- "$@"
ecerr() { ec "$@" 1>&2 }

function input-lang-set-darwin() {
    # https://github.com/myshov/xkbswitch-macosx
    # `hyperfine --warmup 5 'xkbswitch -s 3' 'xkbswitch -s 0' 'xkbswitch -se Persian-ISIRI2901' 'xkbswitch -se US'`
    # they all ran about the same 77ms
    local wanted="${1:l}" to='US'
    case "$wanted" in
        en*) to=US ;;
        fa*|per*) to='Persian-ISIRI2901' ;;
        toggle*)
            case "$(input-lang-get-darwin)" in
                U.S.) to='Persian-ISIRI2901' ;;
                Persian*) to='US' ;;
            esac
        ;;
        *) ecerr "Not supported" ; return 1 ;;
    esac
    xkbswitch -se "$to"
}
function input-lang-get-darwin() {
    defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | command rg -e '"KeyboardLayout Name" = "([^"]*)"' --replace '$1' --only-matching --color never
}

Another option is https://github.com/Lutzifer/keyboardSwitcher, but I couldn't build it without xcode.