2

I'm trying to enter unicode chars in emacs in the same manner I can anywhere else in linux, with the C-S-u string shortcut.

Unfortunately, the function I've written does not work.

(defun insert-char-c (charcode)
  (interactive "scharcode: ")
  (insert-char (substring
                (concat
                 "#x"
                 charcode)
                nil -1)))

It prints the number sequence verbatim instead of printing the required character. I can not modify the input, because it's a hard-coded macro on my keyboard, and I use it elsewhere and would like to keep the same shortcut.

Example input:

C-S-u 00e9_

(_ is space)

I actually don't even know WHY I'm getting the charcode printed without the #x. Any help would be appreciated.

(yes, the function is bound to C-S-u in emacs).

Drew
  • 75,699
  • 9
  • 109
  • 225
Latex_xetaL
  • 168
  • 1
  • 7

2 Answers2

3

The insert-char function wants a character, but substring returns a string. They're not the same type, and a character in elisp is essentially an integer. Let's convert the hexadecimal charcode into an integer before passing it to insert-char.

(defun insert-char-c (charcode)
  "Parse a hexadecimal charcode and insert that character."
  (interactive "scharcode: ")
  (insert-char (cl-parse-integer charcode :radix 16)))

UPDATE: Credit to @rpluim for this, but insert-char when used interactively already knows how to parse hexadecimal values (and more). You could rebind C-S-u to insert-char like this.

(global-set-key (kbd "C-S-u") #'insert-char)

UPDATE #2: @Latex_xetaL had an interesting request in the comments.

I don't want to press RET.

I came up with a way to read a 4 key sequence, and after it reads those 4 keys, it will interpret what you typed as a hexadecimal number and pass it on to insert-char. No RET needed.

(defun insert-char-4 ()
  "Read 4 keyboard inputs, interpret it as a hexadecimal number, and insert it as a character."
  (interactive)
  (let* ((k1 (read-key-sequence "____"))
         (k2 (read-key-sequence (concat k1 "___")))
         (k3 (read-key-sequence (concat k1 k2 "__")))
         (k4 (read-key-sequence (concat k1 k2 k3 "_")))
         (charcode (cl-parse-integer (concat k1 k2 k3 k4) :radix 16)))
    (insert-char charcode)
    (message (concat k1 k2 k3 k4 " => " (char-to-string charcode)))))
  • The prompt starts as "____" and as you type the next 4 hexadecimal digits, it'll fill in.
  • I don't know if 4 hexadecimal digits will be enough, but let's go with this for now.
  • The message at the end is to show you what you typed and what was inserted.

Also, this is my first time using read-key-sequence. If there's a better way to do this, let me know. I'm learning as I go.

g-gundam
  • 1,096
  • 1
  • 3
  • 13
1

This is not intended as a direct answer to your question, but the C-S-u keybinding that you are referring to is part of Gnome’s IME support. It should work automatically in any Gtk application, including Emacs. It might be easier to use the Gtk version of the Emacs GUI rather than to try to replicate it. You can also find many other questions about this Gnome feature here on this site (though usually from people who think Emacs is broken somehow and want it to stop).

Also, insert-char can accept character names as well as character numbers. Since it also supports autocompletion, it is often much faster to search by name than to remember the character number. In this case, it might be easier for most people to type “e with acute” and hit TAB to see the four possible completions than to remember that they want character “e9”.

db48x
  • 15,741
  • 1
  • 19
  • 23