diff --git a/docs/modules.org b/docs/modules.org index 33b2bdbf4..1a6a70372 100644 --- a/docs/modules.org +++ b/docs/modules.org @@ -89,6 +89,7 @@ Modules that reconfigure or augment packages or features built into Emacs. + wanderlust =+gmail= - TODO * :input ++ [[file:../modules/input/bidi/README.org][bidi]] - (tfel ot) thgir etirw uoy gnipleh + [[file:../modules/input/chinese/README.org][chinese]] - TODO + [[file:../modules/input/japanese/README.org][japanese]] - TODO + [[file:../modules/input/layout/README.org][layout]] =+azerty +bepo= - TODO diff --git a/init.example.el b/init.example.el index 2fe2b108b..07bcfaa6e 100644 --- a/init.example.el +++ b/init.example.el @@ -15,6 +15,7 @@ ;; directory (for easy access to its source code). (doom! :input + ;;bidi ; (tfel ot) thgir etirw uoy gnipleh ;;chinese ;;japanese ;;layout ; auie,ctsrnm is the superior home row diff --git a/modules/input/bidi/README.org b/modules/input/bidi/README.org new file mode 100644 index 000000000..5f801da2e --- /dev/null +++ b/modules/input/bidi/README.org @@ -0,0 +1,156 @@ +#+TITLE: input/bidi +#+DATE: September 28, 2021 +#+SINCE: v3.0.0 +#+STARTUP: inlineimages nofold + +* Table of Contents :TOC_3:noexport: +- [[#description][Description]] + - [[#maintainers][Maintainers]] + - [[#module-flags][Module Flags]] + - [[#plugins][Plugins]] +- [[#prerequisites][Prerequisites]] +- [[#features][Features]] +- [[#configuration][Configuration]] + - [[#using-bidi-mode][Using ~+bidi-mode~]] + - [[#force-rtl-text-alignment][Force RTL text alignment]] + - [[#input-methods][Input Methods]] + - [[#fonts][Fonts]] + - [[#smart-fontify][Smart Fontify]] + - [[#change-dictionary-language-on-bidi-buffers][Change Dictionary Language On Bidi Buffers]] + - [[#automatic-input-mode-switching][Automatic input mode switching]] +- [[#troubleshooting][Troubleshooting]] + - [[#nastaliq-font-display-bug][Nastaliq font display bug]] + +* Description + +This module improves support for bidi (bidirectional text). It should be enabled +if you regularly write in languages that write right-to-left. It also provides +some added configuration instructions in the README, since a lot of it is user +specific. + +** Maintainers ++ [[https://github.com/iyefrat][@iyefrat]] ++ [[https://github.com/ymarco][@ymarco]] + +** Module Flags +This module provides no flags. + +** Plugins +This module provides no plugins. + +* Prerequisites +This module has no prerequisites. + +* Features +This module provides ~+bidi-mode~, a minor mode that improves the display of RTL +text by right-aligning lines that start with an RTL language, on a per-line +basis. Since exact use cases vary, turning on this mode is left to the user. + +It also provides easy font configuration for Hebrew and Arabic-derived scripts +(Arabic, Persian, Urdu, etc.) in ~+bidi-hebrew-font~ and ~+bidi-arabic-font~. +See [[Fonts]] for more information. If you use an RTL language that isn't covered by +these characters, open an issue requesting support for it. + +* Configuration +** Using ~+bidi-mode~ +~+bidi-mode~ is a local minor mode, meaning it has to be turned on a per-buffer +basis. + +If you want to have it on for all buffers, use ~+bidi-global-mode~: + +#+begin_src emacs-lisp +;; ~/.doom.d/config.el +(+bidi-global-mode 1) +#+end_src + +If you only need it for specific purposes, e.g. editing LaTeX +documents, you probably want to enable it through a hook: + +#+begin_src emacs-lisp +(add-hook 'TeX-mode-hook #'+bidi-mode) +#+end_src + +This is also useful for adding specific functionality for when ~+bidi-mode~ is on. + +** Force RTL text alignment +By default, ~+bidi-mode~ will align paragraphs by the first character with +strong directionality. If you want to force all paragraphs to be aligned +right-to-left when ~+bidi-mode~ is on, add the following to your config: + +#+begin_src emacs-lisp +(setq +bidi-paragraph-direction 'right-to-left) +#+end_src + +*Warning:* do not do this if you are using ~+bidi-global-mode~, it will mess up +all of the buffers in Emacs that use English, including things like the =M-x= buffer. + +** Input Methods +If you need bidi support, it's likely that you want to easily switch between +English and your favorite RTL language. In order to be able to do this without +losing access to all of the keybindings require English letters, you should use +[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Input-Methods.html][input methods]] to switch languages instead of changing the system keyboard +language. If you use a non-qwerty layout, you will need extra configuration to +keep the input method consistent, see [[https://github.com/ymarco/doom-emacs-config/blob/2d655adb6a35c5cd3afcba24e76327f5444cf774/dvorak-config.el#L3-L18][here]] for an example for dvorak. + +Toggling the input method bound to =C-\=. It prompts you to choose an input +method the first time you do this in a session, but you bypass this by setting +the default input method: + +#+begin_src emacs-lisp +(setq default-input-method "hebrew") +#+end_src + +** Fonts +Many good English fonts do not have great coverage for RTL languages, especially +for Hebrew and monospace fonts. To this end, we provide ~+bidi-hebrew-font~ and +~+bidi-arabic-font~ as an easy way to override the default fonts but only for +Hebrew and Arabic characters. They are set by default to =DejaVu Sans=, since +it has pretty decent looking Hebrew and Arabic characters. + +Note, that if you are writing in an Arabic-derived script, such as Persian, +Urdu, or Pashto, you may want to change ~+bidi-arabic-font~ to one specific to +your language, especially if you want your script to be written in the Nastaliq +style. + +If you use an RTL language the script of which isn't covered by the =hebrew= or +=arabic= unicode blocks, you can set a font override manually. For example: + +#+begin_src emacs-lisp +(add-hook 'after-setting-font-hook + (lambda () (set-fontset-font t 'syriac (font-spec :family "DejaVu Sans")))) +#+end_src + +Make sure to use the correct unicode block name, see the documentation of +~set-fontset-font~ for more details. + +*** Smart Fontify +Since good bidi fonts are often not monospace (as is the default =DejaVu Sans=), +It usually looks better to have the surrounding spaces and punctuation in the +use the bidi font as well. This is the default behaviour, but you can turn this +off by setting: + +#+begin_src emacs-lisp +(setq +bidi-want-smart-fontify nil) +#+end_src + +** Change Dictionary Language On Bidi Buffers +If you are only using ~+bidi-mode~ in specific buffers, you might want to +automatically change the dictionary language there. For example: + +#+begin_src emacs-lisp +(add-hook! '+bidi-mode-hook + (if +bidi-mode + (ispell-change-dictionary "hebrew") + (ispell-change-dictionary "default"))) +#+end_src + +** Automatic input mode switching +You may want to Emacs to try and guess when you want it to switch input methods. +See [[https://github.com/ymarco/doom-emacs-config/blob/2d655adb6a35c5cd3afcba24e76327f5444cf774/hebrew-latex-config.el#L7-L21][here]] and [[https://github.com/ymarco/doom-emacs-config/blob/2d655adb6a35c5cd3afcba24e76327f5444cf774/hebrew-latex-config.el#L99-L102][here]] for an example of how to get Emacs to switch to hebrew when +entering insert mode after a hebrew character, in LaTeX buffers. + +* Troubleshooting + +** Nastaliq font display bug +If Emacs is having trouble properly displaying a Nastaliq font, try using one of +[[https://urdufonts.net/fonts/jameel-noori-nastaleeq-regular][these]] [[https://urdufonts.net/fonts/alvi-nastaleeq-regular][two]] fonts for ~+bidi-arabic-font~. diff --git a/modules/input/bidi/config.el b/modules/input/bidi/config.el new file mode 100644 index 000000000..1b91819a2 --- /dev/null +++ b/modules/input/bidi/config.el @@ -0,0 +1,93 @@ +;;; input/bidi/config.el -*- lexical-binding: t; -*- + +(defvar +bidi-mode-map (make-sparse-keymap) + "Keymap for `+bidi-mode'.") + +(defvar +bidi-hebrew-font (font-spec :family "DejaVu Sans") + "Overriding font for hebrew script. +Must be a `font-spec', see `doom-font' for examples. + +WARNING: if you specify a size for this font it will hard-lock any usage of this +font to that size. It's rarely a good idea to do so!") + +(defface +bidi-hebrew-face `((t :font ,+bidi-hebrew-font)) "") + +(defvar +bidi-arabic-font (font-spec :family "DejaVu Sans") + "Overriding font for arabic and arabic-derived scripts. +Must be a `font-spec', see `doom-font' for examples. + +WARNING: if you specify a size for this font it will hard-lock any usage of this +font to that size. It's rarely a good idea to do so!") + +(defface +bidi-arabic-face `((t :font ,+bidi-arabic-font)) "") + +(defcustom +bidi-want-smart-fontify t + "Use bidi override fonts on surrounding space and punctuation as well. +Add `+bidi-smart-fontify-keywords' to `font-lock-keywords' on editable buffers +when `+bidi-mode' is on." + :type 'boolean) + +(defvar +bidi-smart-fontify-keywords + `((,(rx (any (#x0590 . #x05FF)) ; Hebrew + (group (one-or-more (any " " punctuation)))) + (1 '+bidi-hebrew-face t)) + (,(rx (or (any (#x0600 . #x06FF)) ; Arabic + (any (#x0750 . #x077F)) ; Arabic Supplement + (any (#x0870 . #x089F)) ; Arabic Extended-B + (any (#x08A0 . #x08FF))) ; Arabic Extended-A + (group (one-or-more (any " " punctuation)))) + (1 '+bidi-arabic-face t))) + + "`font-lock' keywords matching spaces and punctuation after RTL characters. +See the variable `font-lock-keywords' for information on the format.") + +(defcustom +bidi-paragraph-direction nil + "The value of `bidi-paragragh-direction' when `+bidi-mode' is on. +See the `bidi-paragraph-direction' for more info. + +Warning: do not change this if you are using `+bidi-global-mode'.'" + :type '(choice + (const :tag "Left to Right" left-to-right) + (const :tag "Right to Left" right-to-left) + (const :tag "Dynamic, according to paragraph text" nil))) + +;;;###autoload +(define-minor-mode +bidi-mode + "Minor mode for using bidirectional text in a buffer. + +Note that the whole buffer doesn't have to contain any +bidirectional text at all, this mode just makes bidi editing +easier." + :keymap +bidi-mode-map + (if +bidi-mode + (progn + (setq bidi-paragraph-direction +bidi-paragraph-direction ; Better paragraph alignment + bidi-paragraph-separate-re "^" ; No need for empty lines to switch alignment + bidi-paragraph-start-re "^" ; ^ + bidi-inhibit-bpa nil) ; Better bidi paren logic + (when (and +bidi-want-smart-fontify + (not buffer-read-only)) + (font-lock-add-keywords + nil + +bidi-smart-fontify-keywords + 'append) + (font-lock-flush))) + (setq bidi-paragraph-direction 'left-to-right + bidi-paragraph-separate-re nil + bidi-paragraph-start-re nil + bidi-inhibit-bpa t) + (when (and +bidi-want-smart-fontify + (not buffer-read-only)) + (font-lock-remove-keywords + nil + +bidi-smart-fontify-keywords) + (font-lock-flush)))) + +(define-globalized-minor-mode +bidi-global-mode +bidi-mode +bidi-mode) + +(add-hook! 'after-setting-font-hook + (defun +bidi-set-fonts-h () + (set-fontset-font t 'hebrew +bidi-hebrew-font) + (set-fontset-font t 'arabic +bidi-arabic-font) + (set-face-font '+bidi-arabic-face +bidi-arabic-font) + (set-face-font '+bidi-hebrew-face +bidi-hebrew-font)))