4

I write and work in several languages: German, Spanish, French, Greek, English. In mac when you press a key longer than 2 seconds you can choose between special characters derivative from a main character. In windows there is a software called Holdkey that does the same. Is there anything similar in Linux. I haven't found it yet.

George G.
  • 491

3 Answers3

2

I have two advices:

  1. Use a suitable keyboard layout, i.e. a layout with dead keys. If you have an English keyboard, pick for instance English (US, intl., with dead keys). But there are several other variants.
  2. Define a compose key. That way you'll be able to type many characters which are not included in the keyboard layout you are using. (Compose key is a XKB feature, so it's available on Kubuntu, but you need to figure out how to define it there.)
2

If you are not afraid to set up (instructions should be clear), below could give you an alternative to quickly insert your often used special character (-alternatives).

Editable special character tool

The script below is a flexible tool (window to insert characters from, in a click) to have often used characters available in a second:

enter image description here

How it works

  • Call the window with a shortcut
  • To insert a character, simply click on it, and it will paste the character into the window you were working in.
  • To add a set of characters, press + A text editor window will open, add your "family" name on the first line, related special characters on the next lines, one character per line, for example:

    a
    å
    ä
    ã
    â
    á
    à
    ª
    

    (from the image). Close the file, the special characters will be available from now on from the next time you call the window.

  • to delete a set of available characters, press x

How to set up

  1. You need to satisfy a few dependencies:

    • python3-xlib

      sudo apt install python3-xlib
      
    • pyautogui:

      pip3 install pyautogui
      
    • pyperclip:

      sudo apt install python3-pyperclip xsel xclip
      
    • You might have to install Wnck:

      python3-gi gir1.2-wnck-3.0
      

    Log out and back in.

  2. Copy the script below into an empty file, save it as specialchars.py and make it executable

    #!/usr/bin/env python3
    import os
    import gi
    gi.require_version("Gtk", "3.0")
    gi.require_version('Wnck', '3.0')
    from gi.repository import Gtk, Wnck, Gdk
    import subprocess
    import pyperclip
    import pyautogui
    
    
    css_data = """
    .label {
      font-weight: bold;
      color: blue;
    }
    .delete {
      color: red;
    }
    """
    
    fpath = os.environ["HOME"] + "/.specialchars"
    
    def create_dirs():
        try:
            os.mkdir(fpath)
        except FileExistsError:
            pass
    
    
    def listfiles():
        files = os.listdir(fpath)
        chardata = []
        for f in files:
            f = os.path.join(fpath, f)
            chars = [s.strip() for s in open(f).readlines()]
            try:
                category = chars[0]
                members = chars[1:]
            except IndexError:
                os.remove(f)
            else:
                chardata.append([category, members, f])
        chardata.sort(key=lambda x: x[0])
        return chardata
    
    
    def create_newfamily(button):
        print("yay")
        n = 1
        while True:
            name = "charfamily_" + str(n)
            file = os.path.join(fpath, name)
            if os.path.exists(file):
                n = n + 1
            else:
                break
        open(file, "wt").write("")
        subprocess.Popen(["xdg-open", file])
    
    
    class Window(Gtk.Window):
        def __init__(self):
            Gtk.Window.__init__(self)
            self.set_decorated(False)
            # self.set_active(True)
            self.set_keep_above(True);
            self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
            self.connect("key-press-event", self.get_key)
            self.set_default_size(0, 0)
            self.provider = Gtk.CssProvider.new()
            self.provider.load_from_data(css_data.encode())
            self.maingrid = Gtk.Grid()
            self.add(self.maingrid)
            chardata = listfiles()
            # get the currently active window
            self.screendata = Wnck.Screen.get_default()
            self.screendata.force_update()
            self.curr_subject = self.screendata.get_active_window().get_xid()
            row = 0
            for d in chardata:
                bbox = Gtk.HBox()
                fambutton = Gtk.Button(d[0])
                fambutton_cont = fambutton.get_style_context()
                fambutton_cont.add_class("label")
                fambutton.connect("pressed", self.open_file, d[2])
                Gtk.StyleContext.add_provider(
                    fambutton_cont,
                    self.provider,
                    Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
                )
                fambutton.set_tooltip_text(
                    "Edit special characters of '" + d[0] + "'"
                )
                bbox.pack_start(fambutton, False, False, 0)
                for c in d[1]:
                    button = Gtk.Button(c)
                    button.connect("pressed", self.replace, c)
                    button.set_size_request(1, 1)
                    bbox.pack_start(button, False, False, 0)
                self.maingrid.attach(bbox, 0, row, 1, 1)
                deletebutton = Gtk.Button("X")
    
                deletebutton_cont = deletebutton.get_style_context()
                deletebutton_cont.add_class("delete")
                Gtk.StyleContext.add_provider(
                    deletebutton_cont,
                    self.provider,
                    Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
                )
    
                deletebutton.connect("pressed", self.delete_file, d[2], bbox)
                deletebutton.set_tooltip_text("Delete family")
    
                self.maingrid.attach(deletebutton, 100, row, 1, 1)
                row = row + 1
            addbutton = Gtk.Button("+")
            addbutton.connect("pressed", create_newfamily)
            addbutton.set_tooltip_text("Add family")
            self.maingrid.attach(addbutton, 100, 100, 1, 1)
            self.maingrid.attach(Gtk.Label("- Press Esc to exit -"), 0, 100, 1, 1)
            self.show_all()
            Gtk.main()
    
        def get_key(self, button, val):
            # keybinding to close the previews
            if Gdk.keyval_name(val.keyval) == "Escape":
                Gtk.main_quit()
    
        def replace(self, button, char, *args):
            pyperclip.copy(char)
            subprocess.call(["wmctrl", "-ia", str(self.curr_subject)])
            pyautogui.hotkey('ctrl', 'v')
            Gtk.main_quit()
    
    
        def open_file(self, button, path):
            subprocess.Popen(["xdg-open", path])
    
        def delete_file(self, button, path, widget):
            os.remove(path)
            widget.destroy()
            button.destroy()
            self.resize(10, 10)
    
    create_dirs()
    Window()
    
  3. Set up a shortcut key to run:

    python3 /path/to/specialchars.py
    

On first run, you will only see a + button. Start Adding your character "families" and restart (-call) the window to have all available in a click.

That's it...

Jacob Vlijm
  • 85,475
0

You can use unicode to type special characters on Linux.

To type a special character, first press down CTRL+SHIFT+U and then let go of the keys.

Next, type the hexadecimal code for the character you wish to insert and then press ENTER

The hexadecimal code for "ü" is 00fc.

Click here to see the Wikipedia page for Unicode characters.

Click here to see the Wikipedia page for Unicode math characters.

mchid
  • 44,904
  • 8
  • 102
  • 162