Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set completion when define my own function

I wrote a function to insert some special characters in "EMACS", which will ask to input the name and it inserts the corresponding special character.

Example: when I type "alpha", the function will insert α instead.

But when I type these characters, I found out that I cannot use auto completion. I defined alpha as α and beta as β, but when I type al[Tab] it just inserts a tab.

How can I define the auto completion for my function?

--Edit--------------------------------

Sorry, I'm still new to emacs and just started to write elisp function yesterday.

I just used a straightforward way to implement this function, using interactive with code s to read strings

That's why I wonder how to get the auto-completion done. Because I didn't find any tutorials about such things. Maybe it's for my lack in elisp knowledge to search the right answer.

Anyway, here is my code:

(defun sp-char (char)
"Insert some special chars."
(interactive "sInput char name: ")
(let ((funky-char))
    (setq funky-char
      (cond
       ((string= char "Alpha" ) "Α")
       ((string= char "alpha" ) "α")
       ((string= char "Beta" ) "Β")
       ((string= char "beta" ) "β")
       ((string= char "Gamma" ) "Γ")
       ((string= char "gamma" ) "γ")
       ((string= char "Delta" ) "Δ")
       ((string= char "delta" ) "δ")
       ))
(insert funky-char)))

I searched the read-string, but still confused how to get the completion done.

I'd appreciate it if you show me a little piece of code as example.

like image 415
CyberLuc Avatar asked Jul 28 '13 03:07

CyberLuc


2 Answers

If it's just Unicode chars you're after, there are other ways to solve the problem:

  1. There's insert-char bound to C-x 8 RET. It's got completion, so *alpha will get you everything with alpha in it.
  2. If it's just Greek chars you're after, and you're on Linux, you can use xmodmap to redefine your keyboard: each key, like w has not two, but four states: normal, shift, Mod4 and Mod4+shift. I've it configured like this: w W ω Ω.
  3. You could use yasnippet to accomplish this task. Like the second method, and different from the first and your method, it has a big advantage that it doesn't break your flow: you're not distracted by having to look at the minibuffer and/or read the possible choices - you just type what you wanted to type and expand.
  4. expand-abbrev is similar to yasnippet but easier to add to, since each abbrev is just an element in the list, instead of a file. But it doesn't have fields/mirrors.

But it all really depends on what you're trying to do.

UPD Corrected version of your code

This completion will exit as soon as the candidate is unique.

(defvar zz-minibuffer-map (copy-keymap minibuffer-local-must-match-map))

(define-key zz-minibuffer-map
  [remap self-insert-command] 'zz-self-insert-complete-and-exit)

(defun zz-self-insert-complete-and-exit (n)
  (interactive "p")
  (self-insert-command n)
  (ignore-errors
    (completion--do-completion nil 'expect-exact))
  (let ((candidates (completion-all-sorted-completions)))
    (cond
      ((null candidates)
       (backward-delete-char-untabify 1)
       (minibuffer-complete))
      ((eq 1 (safe-length candidates))
       (minibuffer-complete-and-exit)))))

(defun sp-char (char)
  "Insert some special chars."
  (interactive
   (list
    (let ((minibuffer-local-must-match-map zz-minibuffer-map))
      (completing-read "Input char name: " special-char-alist nil t))))
  (insert (cadr (assoc char special-char-alist))))

(defvar special-char-alist
  '(("Alpha" "Α")
    ("alpha" "α")
    ("Beta" "Β")
    ("beta" "β")
    ("Gamma" "Γ")
    ("gamma" "γ")
    ("Delta" "Δ")
    ("delta" "δ")))
like image 161
abo-abo Avatar answered Nov 26 '22 15:11

abo-abo


Use completing-read rather than read-string (or worse, read-from-minibuffer).

like image 39
Stefan Avatar answered Nov 26 '22 15:11

Stefan