Skip to content

Latest commit

 

History

History
524 lines (382 loc) · 20.6 KB

README_EN.org

File metadata and controls

524 lines (382 loc) · 20.6 KB

Emacs Rime

https://melpa.org/packages/rime-badge.svg https://stable.melpa.org/packages/rime-badge.svg

https://i.imgur.com/jHpk7BT.gif

Emacs in Rime, support multiple schemas.

Part 1: Installation & How to use

Check Intallation.

Part 2: Rime Configuration and Data

toggle-folding

Keybindings in Rime.

With following configuration, you can send a serials of keybindings to Rime. Since you may want them to help you with cursor navigation, candidate pagination and selection, defined in RIME’s input method schema.

Currently the keybinding with Control(C-), Meta(M-) and Shift(S-) is supported.

;; defaults
(setq rime-translate-keybindings
  '("C-f" "C-b" "C-n" "C-p" "C-g" "<left>" "<right>" "<up>" "<down>" "<prior>" "<next>" "<delete>"))

Assign Rime share-data-dir and user-data-dir

rime-share-data-dir is where Rime store its configuration (including schema) post installation. E.g. default path for Linux is usually /usr/share/rime-data , Normally you could just use the default value, or configure the variable to use another location. E.g. for fcitx5-rime maybe this path: ~/.local/share/fcitx5/rime .

rime-user-data-dir is where emacs-rime deploy at, including vocabulary frequency information. The default path is ~/.emacs.d/rime . Configure the variable to use another location.

Making ~emacs-rime~ 与 ~fcitx-rime~ share user-data-dir is NOT recommended 。 Take using terra-pinyin in fcitx-rime and emacs-rime as an example, if configured

(setq rime-user-data-dir "~/.config/fcitx/rime/")

then after first deployment of emacs-rime , a new terra_pinyin.userdb/ folder is generated, and the original fcitx-rime usage logs are be moved to terra_pinyin.userdb.old/ , leading to an empty vocabulary frequency information in terra_pinyin.userdb.txt .

Shortcut to open Rime configuration file

Use rime-open-configuration.

Redeploy

toggle-folding

Same as RIME, the configuration file of emacs-rime does NOT take effect until redeployment.

Take adding terra-pinyin as an example.

Find the path where the configuration of emacs-rime locates, or use M-x rime-open-configuration to open default.custom.yaml , goto patch:schema_list and add - schema: terra_pinyin . Now you need M-x rime-deploy to redeploy to enable terra-pinyin. After that you may press C-` to pop up rime menu and select the desired schema, i.e. terra-pinyin.

Example:

patch:
  schema_list:
    - schema: luna_pinyin
    - schema: pinyin_simp
    - schema: terra_pinyin
  menu/page_size: 7 # show 7 candidates per page.
  switcher:
    hotkeys:
      - Control+grave # Key binding to active RIME's menu. Some editions of RIME support <F4> as shortcut, which is likely to clash with other programs.

Lost user vocabulary database after redeployment?

The cause may be using the same user-data-dir by emacs-rime and fcitx-rime , as explained earlier.

How to recover: (still, take terra_pinyin as an example) Set user-data-dir of emacs-rime to another folder, delete terra_pinyin.userdb/ and rename terra_pinyin.userdb.old/ to the previous one, resync or redeploy, terra_pinyin.userdb.txt should recover now.

Sync vocabulary

toggle-folding

M-x rime-sync is capable of syncing and backing up for RIME input method schema and vocabulary data, and every sync is a dual-directional sync. The backup file generated for vocabulary data is sync/ins_id/schema.userdb.txt , the file is the plain text of vocabulary data and vocabulary frequency log in the folder schema.userdb/ , for convenience using it across platforms on multiple devices.

The so called dual-directional sync is that, the vocabulary frequency and user customed vocabulary of current device (in schema.userdb/ ) and the vocabulary logged in the backup file (in sync/ins_id/schema.userdb.txt ) will be merged by RIME, and the generated union will continue to be logged in schema.userdb/ . Then a new backup file will be generated, still naming as sync/ins_id/schema.userdb.txt , and (without prompt to ask the user) override the old one.

The mentioned path of sync folder and configuration file default.custom.yaml is under the same directory. ins_id , respectively, is the value of installation_id in the file installation.yaml . The default value is generated by random, and can be set to some customed string value.

Taking adding terra-pinyin and sync as an example. After enable this input method schema, a folder terra_pinyin.userdb under RIME share data directory is generated, which has the log of usage frequency user defined vocabulary, so better not modify it. Before you sync, modify the content of installation.yaml to the customed installation_id: "hesperus" . Then M-x rime-sync , which will generate the file terra_pinyin.userdb.txt (vocabulary data) and terra_pinyin.schema.yaml (input method schema) under sync/hesperus/ .

If you have vocabulary data accumulated on other devices or systems, and you want to keep using it, then you should sync in the original system, and copy the generated terra_pinyin.userdb.txt to the targed system’s sync/hesperus/ , then do sync or deploy. Now, the vocabulary data backed up in the old system willby merged under terra_pinyin.userdb/ in the new system, and new union will be exported too, overriding terra_pinyin.userdb.txt .

Vocabulary data sync failed?

toggle-folding

Take using terra-pinyin as an example.

It’s suggested to set a same value for ~installation_id~ on different devices or systems. If they’re not the same, the sync process may fail, i.e. the vocabulary frequency log in terra_pinyin.userdb.txt copied from old system won’t be obtained in current terra_pinyin.userdb/ . At time, the vocabulary frequency info in this file is not empty, but with a different user_id , and possibly not take effect even after modify the value and resync.

Part 3: Appearance

toggle-folding

Candidate menu style

Set via rime-show-candidate.

Valuedescription
nildon’t show candidate at all.
minibufferDisplay in minibuffer.
messageDisplay with message function, useful when you use minibuffer as mode-line.
popupUse popup.
posframeUse posfarme, will fallback to popup in TUI
sidewindowUse sidewindow.

Candidate style

FaceMeaning
rime-default-facedefault foreground and background color(posframe only)
rime-code-facecolor of code
rime-candidate-num-facecolor of candidate number
rime-comment-facecolor of candidate comment

posframe/popup/sidewindow candidate style

Configure rime-posframe-style , rime-popup-style or rime-sidewindow-style , possible values:

valuemeaning
simplesingle lined
horizontalhorizontal(default)
verticalvertical

Other properties of posframe

Configure rime-posframe-properties , but rime-default-face for color.

(setq rime-posframe-properties
 (list :font "sarasa ui sc"
       :internal-border-width 10))

For supported configuration, see posframe .

Other properties of sidewindow

Configure rime-sidewindow-style , possible values are top , bottom , left , right , meaning the position where sidewindow should appear.

Configure rime-sidewindow-keep-window , if t then keeps sidewindow open.

The lighter

You can get a lighter via (rime-lighter), which returns you a colored . Put it in modeline or anywhere you want.

You can customize with rime-title, rime-indicator-face and rime-indicator-dim-face.

The soft cursor

Default to | , you can customize it with

(setq rime-cursor "˰")

Style of preedit text

Configure rime-preedit-face .

Appearence format of preedit code

Configure rime-show-preedit, possible values:

valuesmeaning
tshow in menu
inlinereplace commit preview
nildon’t show

Note: Soft cursor won’t appear using inline or nil .

Part 4: Automation

toggle-folding

Temporarily ascii mode

If you want specific a list of rules to automatically enable ascii mode, you can customize rime-disable-predicates.

Following is an example to use ascii mode in evil-normal-state or when cursor is after alphabet character or when cursor is in code.

(setq rime-disable-predicates
      '(rime-predicate-evil-mode-p
        rime-predicate-after-alphabet-char-p
        rime-predicate-prog-in-code-p))

Built-in Predicate Functions

  • rime-predicate-after-alphabet-char-p

    After an alphabet character (must beginning with letter [a-zA-Z]).

  • rime-predicate-after-ascii-char-p

    After any alphabet character.

  • rime-predicate-prog-in-code-p

    On prog-mode and conf-mode, not in comments and quotes.

  • rime-predicate-in-code-string-p

    In the code string(not comment string).

  • rime-predicate-evil-mode-p

    In the non-editing state of evil-mode.

  • rime-predicate-ace-window-p

    If the ace-window-mode is activated.

  • rime-predicate-hydra-p

    If a hydra keymap is activated.

  • rime-predicate-current-input-punctuation-p

    When entering punctuation.

  • rime-predicate-punctuation-after-space-cc-p

    When entering punctuation after a Chinese character appended with whitespaces.

  • rime-predicate-punctuation-after-ascii-p

    When entering punctuation after an ascii character.

  • rime-predicate-punctuation-line-begin-p

    When entering punctuation at the beginning of the line.

  • rime-predicate-space-after-ascii-p

    After an ascii character appended with whitespaces.

  • rime-predicate-space-after-cc-p

    After a Chinese character appended with whitespaces.

  • rime-predicate-current-uppercase-letter-p

    When entering a uppercase letter.

  • rime-predicate-tex-math-or-command-p

    When inside a (La)TeX math environment or entering a (La)TeX command.

Indicator for indicating the state of temporary English state

Use (rime-lighter) to generate a character for showing. Customization is available by configuring rime-indicator-face and rime-indicator-dim-face .

The configuration below could replace the icon of input method, to make it using color to indicate the current state of temporary English state.

;;; See the default value of mode-line-mule-info as reference, which may contain somthing useful.
(setq mode-line-mule-info '((:eval (rime-lighter))))

Temporary English input based on Rime inline ascii mode

Configure rime-inline-predicates , which structure is same as rime-disable-predicates but with lower priority.

The function is mainly for temporary input English text with spaces.

Because of the limit of current code, if not using default Shift_L to toggle inline ascii mode in Rime configuration, shoud specify that in emacs-rime. It won’t activate normally unless the configurations on both sides are the same.

;;; support shift-l, shift-r, control-l, control-r
(setq rime-inline-ascii-trigger 'shift-l)

When preedit code exists, use rime-inline-ascii to toggle mode.

(define-key rime-active-mode-map (kbd "M-j") 'rime-inline-ascii)

Prevent specific single characters from auto commit in inline-ascii mode

(setq rime-inline-ascii-holder ?x)      ; Any single character that not trigger auto commit

Force enable

If one of rime-disable-predicates returns t, you can still force enable the input method with rime-force-enable. The effect will only last for one input behavior.

You probably want to give this command a keybinding.

Auto Commit1

emacs-rime has defined the function rime-commit1 , which automatically commit the 1st item among the candidates during input state.

The function is especially useful for schema that don’t rely on manually selecting desired candidate.

The function is not suitable for using alone, but using within other functions defined by user to suit various personal needs.

Example: Commit the 1st item when toggle input method.

Some input method programs, e.g. fcitx5-rime, support commit the 1st item before toggle input method. Here’s an example to realize the same function in emacs-rime, for explaning the usage of rime-commit1 .

Now, the basic idea is that:

  1. Define a function which commits the 1st item and toggles input method.
  2. Bind the defined function to some keys, and use it to alternative which toggle-input-method does.

Example configuration:

(defun rime-commit1-and-toggle-input-method ()
  "Commit the 1st item if exists, then toggle input method."
  (interactive)
  (ignore-errors (rime-commit1))
  (toggle-input-method))

(global-set-key (kbd "C-;") #'rime-commit1-and-toggle-input-method)

Here ignore-errors is for preventing rime-commit1 triggering error because that it’s not loaded until every first time you enable rime during a emacs session. After the example configuration taking effects, press C-; to toggle input method.

Auto commit1 for all command unrelated to emacs-rime

If there’s many functions that you’d like to auto-commit1 before executing them, and you don’t want to define many customed functions for each of them, you could configure a auto-commit1 for all of them.

How it works:

  • During input state of emacs-rime, if a function unrelated with rime is executed, rime--clear-state is triggered by default.
  • If set rime-commit1-forall to a non-nil value, the function to be triggered will be rime-commit1 instead.

Example configuration:

(setq rime-commit1-forall t)

Auto commit1 for pressing ESC

The for-all configuration above does not apply to pressing ESC, here we have a workaround.

Why it works: During input state of emacs-rime, ESC is mapped to the function rime--escape , which is apparently not a function unrelated with emacs-rime.

Example: Taking using with evil as an example. For making ESC acts as auto-commit1 then evil-normal-state, define a function and bind it to ESC. (notice: at least for evil, C-[ is the same as ESC to emacs, so that another binding for C-[ is NOT needed.)

Example configuration:

(defun rime-commit1-and-evil-normal ()
  "Commit the 1st item if exists, then go to evil normal state."
  (interactive)
  (rime-commit1)
  (evil-normal-state))
(define-key rime-active-mode-map (kbd "<escape>") 'rime-commit1-and-evil-normal)

Auto close input method after using minibuffer

Auto close as default. Set rime-deactivate-when-exit-minibuffer to nil to cancel this behavior.

How to integrate this with <code>evil-escape</code>?

The following code may have performance issue

Add the following code snippet in your configuration files, then you can use evil-escape to return to normal state when having nothing in editing(no preedit overlay).

(defun rime-evil-escape-advice (orig-fun key)
  "advice for `rime-input-method' to make it work together with `evil-escape'.
        Mainly modified from `evil-escape-pre-command-hook'"
  (if rime--preedit-overlay
      ;; if `rime--preedit-overlay' is non-nil, then we are editing something, do not abort
      (apply orig-fun (list key))
    (when (featurep 'evil-escape)
      (let (
            (fkey (elt evil-escape-key-sequence 0))
            (skey (elt evil-escape-key-sequence 1))
            )
        (if (or (char-equal key fkey)
                (and evil-escape-unordered-key-sequence
                     (char-equal key skey)))
            (let ((evt (read-event nil nil evil-escape-delay)))
              (cond
               ((and (characterp evt)
                     (or (and (char-equal key fkey) (char-equal evt skey))
                         (and evil-escape-unordered-key-sequence
                              (char-equal key skey) (char-equal evt fkey))))
                (evil-repeat-stop)
                (evil-normal-state))
               ((null evt) (apply orig-fun (list key)))
               (t
                (apply orig-fun (list key))
                (if (numberp evt)
                    (apply orig-fun (list evt))
                  (setq unread-command-events (append unread-command-events (list evt))))))
              )
          (apply orig-fun (list key)))))))


(advice-add 'rime-input-method :around #'rime-evil-escape-advice)

Part 5: Misc

toggle-folding

Open Rime menu

Assuming you use C-~ for the menu.

switcher:
  caption: 〔方案選單〕
  hotkeys:
    - Control+grave

You can bind this key to rime-mode-map with command rime-send-keybinding.

(use-package
  ...

  :bind
  (:map rime-mode-map
        ("C-`" . 'rime-send-keybinding))
  ...
  )

Part 6: FAQ

toggle-folding

Use in isearch

emacs-rime won’t work properly in isearch. Use phi-search instead.

The last item of the candidate box is not displayed?

Few users occasionally have a issue that the last candidate word is not displayed. It can be determined that this is related to `posframe`, but the reason has not been found. A temporary solution is to append a full-width whitespace to the end of the candidate list.

(defun +rime--posframe-display-content-a (args)
  "Append a full-width whitespace to the input string.
This can temporarily solve the problem of `posframe` occasionally
\"eating\" words."
  (cl-destructuring-bind (content) args
    (let ((newresult (if (string-blank-p content)
                         content
                       (concat content " "))))
      (list newresult))))

(if (fboundp 'rime--posframe-display-content)
    (advice-add 'rime--posframe-display-content
                :filter-args
                #'+rime--posframe-display-content-a)
  (error "Function `rime--posframe-display-content' is not available."))

Want a pure emacs input method without <code>librime</code>?

Maybe, you need pyim.

Part Fin: Thanks for all the contributors