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.

5

3 Answers 3

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.)
1
  • Thank you! I didn't thought about the use of English (US, intl., with dead keys). This idea is very use to configure and very easy to use. I choosed EurKEY (US based layout with european letters) for my use is perfect.
    – George G.
    Jun 3, 2019 at 2:29
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...

8
  • Interesting solution, hence +1'ed but just one question: why python3-xlib is necessary ? I don't see Xlib being imported anywhere in the code Jun 1, 2019 at 23:24
  • @SergiyKolodyazhnyy Aarrgh, copied too much over from my answer here: askubuntu.com/questions/1071218/… thanks for mentioning! Jun 2, 2019 at 5:40
  • Haha, either script or copy and paste all the things - that's the way to go XD I'll look over the other answer as well. Thanks for the weekend read. Jun 2, 2019 at 5:49
  • @SergiyKolodyazhnyy Hah, I only copied the install instructions! :) Jun 2, 2019 at 5:52
  • 1
    @oglop It actually is, but much improved, now running from a daemon & integrated in Ubuntu Budgie. github.com/ubuntubudgie/quickchar/tree/… Sep 12, 2021 at 19:08
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.

5
  • Clarification: Hold CTRL and SHIFT hit U, let go of CTRL and SHIFT keys, type the code, press enter.
    – Hannu
    Jun 2, 2019 at 8:21
  • Thanks for this idea. However for me personally I think the best option is to use a Keyboard layout. I found EurKEY (US based layout with european letters) the best for people who need German language characters as well as Spanish. I will use you idea for greek characters that I don't use that often.
    – George G.
    Jun 3, 2019 at 2:33
  • @Hannu You can let go of all the keys CTRL and SHIFT and U. There is no need to hold down U while you type the code.
    – mchid
    Jun 4, 2019 at 20:46
  • 1
    "hit U" = no holding.
    – Hannu
    Jun 5, 2019 at 14:43
  • @Hannu Although, you can hold down U when you type the code you just don't need to. Either way works.
    – mchid
    Jun 6, 2019 at 21:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .