I want to enable one more input language and I wonder is there any way to group similar languages? Suppose I have English, Russian and Ukranian. Russian and Ukranian are similar and it would be convenient to group them. To bind ctrl+shift -- switching between cyrillic and latin groups, alt+shift -- switching inside group between cyrillic languages. Is it possible?

  • Hi Михаил Павлов, posted my answer. Please mention if all is clear. – Jacob Vlijm Feb 2 '17 at 19:34

Script to switch to the next language group, or to the next language inside the current group, depending on the argument.

enter image description here

Preparation

  1. In a terminal, run:

    gsettings get org.gnome.desktop.input-sources sources
    

    This will output something like (in my case):

    [('xkb', 'us+intl'), ('xkb', 'us'), ('xkb', 'nl'), ('xkb', 'be')]
    
  2. Now simply create a file inside your $HOME directory (exactly) named:

    langsets
    

    where you group the languages to your liking. In my example, I will group'us+intl' together with 'us', and 'nl' with 'be'. I group them by their order in the list, which results into a file:

    content of the file ~/home/langsets:

    1 2
    3 4
    

    As you can see, on each line, I put the numbers of the index of the languages, separated by a space (where 1 is the first language in the output list).

    You can set any combination of languages (as long as you don't place languages in multiple groups), and any number of language groups, simply create a new line with indices.

  3. The script

    #!/usr/bin/env python3
    import subprocess
    import os
    import sys
    import ast
    
    arg = sys.argv[1]
    
    key = "org.gnome.desktop.input-sources"
    
    f = [f for f in [l.strip().split() for l in open(
        os.path.join(os.environ["HOME"], "langsets")
        ).readlines()] if f]
    
    def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
    
    def execute(cmd):
        subprocess.Popen(cmd)
    
    langs = ast.literal_eval(get(["gsettings", "get", key, "sources"]).strip())
    currlang = str(int(get(["gsettings", "get", key, "current"]).split()[-1].strip())+1)
    
    currgroup = [l for l in f if currlang in l][0]
    
    if arg == "nextcurr":
        currsub = currgroup.index(currlang)
        try:
            nextlang = currgroup[currsub+1]
        except IndexError:
            nextlang = currgroup[0]
        nextlang = str(int(nextlang)-1)
    
    elif arg == "nextgroup":
        try:
            nextlang = f[[i for i, l in enumerate(f) if f[i] == currgroup][0]+1][0]
        except IndexError:
            nextlang = f[0][0]
    
    subprocess.Popen(["gsettings", "set", key, "current", nextlang])
    
  4. Copy the script into an empty file, save it as language_set.py

  5. Test- run the script with the two commands:

    python3 /path/to/language_set.py nextgroup
    

    an

    python3 /path/to/language_set.py nextcurr
    

    to see if the script (subsequently) moves to the next language group or to the next language in the current group.

  6. If all works fine, create two keyboard shortcuts. One to switch to the next group, one to switch inside the current group.

    Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the commands below.

    1. To change between language groups:

      python3 /path/to/language_set.py nextgroup
      
    2. To change between languages inside a group:

      python3 /path/to/language_set.py nextcurr
      

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.