├── .elpaignore ├── .gitignore ├── .travis.yml ├── Cask ├── Makefile ├── README.md ├── pangu-spacing.el ├── screenshot └── screenshot.gif └── test ├── pangu-spacing-test.el └── test-helper.el /.elpaignore: -------------------------------------------------------------------------------- 1 | .travis.yml 2 | .gitignore 3 | test/ 4 | screenshot/ 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | /.cask/ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Use nix-emacs-ci for travis CI 3 | # URL: https://github.com/purcell/nix-emacs-ci 4 | # 5 | 6 | language: nix 7 | 8 | os: 9 | - linux 10 | # - osx 11 | 12 | env: 13 | - EMACS_CI=emacs-24-2 14 | - EMACS_CI=emacs-24-3 15 | - EMACS_CI=emacs-24-4 16 | - EMACS_CI=emacs-24-5 17 | - EMACS_CI=emacs-25-1 18 | - EMACS_CI=emacs-25-2 19 | - EMACS_CI=emacs-25-3 20 | - EMACS_CI=emacs-26-1 21 | - EMACS_CI=emacs-26-2 22 | - EMACS_CI=emacs-26-3 23 | - EMACS_CI=emacs-snapshot 24 | 25 | # emacs-24-2 and emacs-24-3 may failure on test 26 | # just ignore it now. 27 | matrix: 28 | allow_failures: 29 | - env: EMACS_CI=emacs-24-2 30 | - env: EMACS_CI=emacs-24-3 31 | - env: EMACS_CI=emacs-snapshot 32 | 33 | # The default "emacs" executable on the $PATH will now be the version named by $EMACS_CI 34 | install: 35 | - bash <(curl https://raw.githubusercontent.com/purcell/nix-emacs-ci/master/travis-install) 36 | - export PATH="$HOME/.cask/bin:$PATH" 37 | - curl -fsSkL https://raw.github.com/cask/cask/master/go | python 38 | 39 | script: 40 | - emacs --version 41 | - make clean 42 | - make 43 | - make test 44 | 45 | # Local Variables: 46 | # indent-tabs-mode: nil 47 | # coding: utf-8 48 | # End: 49 | -------------------------------------------------------------------------------- /Cask: -------------------------------------------------------------------------------- 1 | (source gnu) 2 | (source melpa) 3 | 4 | (package-file "pangu-spacing.el") 5 | (development 6 | (depends-on "ert-runner")) 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EMACS ?= emacs 2 | BATCH := $(EMACS) $(EFLAGS) -batch -q -no-site-file -L . 3 | 4 | all: pangu-spacing.elc 5 | 6 | README.md: make-readme-markdown.el 7 | emacs --script $< $@ 2>/dev/null 8 | 9 | make-readme-markdown.el: 10 | wget -q -O $@ https://raw.github.com/mgalgs/make-readme-markdown/master/make-readme-markdown.el 11 | .INTERMEDIATE: make-readme-markdown.el 12 | 13 | clean: 14 | $(RM) *.elc 15 | 16 | %.elc: %.el 17 | $(BATCH) --eval '(byte-compile-file "$<")' 18 | 19 | test: 20 | $(BATCH) -L . -l test/pangu-spacing-test.el -f ert-run-tests-batch-and-exit 21 | 22 | .PHONY: check clean test README.md 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Emacs Logo 2 | ## pangu-spacing.el 3 | *Minor-mode to add space between Chinese and English characters.* 4 | 5 | --- 6 | [![License GPLv3](https://img.shields.io/badge/license-GPL_v3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.html) 7 | [![MELPA](http://melpa.org/packages/pangu-spacing-badge.svg)](http://melpa.org/#/pangu-spacing) 8 | [![MELPA Stable](http://stable.melpa.org/packages/pangu-spacing-badge.svg)](http://stable.melpa.org/#/pangu-spacing) 9 | 10 | ### Screenshot 11 | 12 | ![Screenshot](https://github.com/coldnew/pangu-spacing/raw/master/screenshot/screenshot.gif) 13 | 14 | ### Commentary (English) 15 | 16 | pangu-spacing-mode is an minor-mode to auto add `space` between Chinese 17 | and English characters. Note that these whitespace characters are not really 18 | added to your file. It's just a local visual change. 19 | 20 | Take following sentance for example: 21 | 22 | 你好,我是coldnew,我喜歡使用emacs。 23 | 24 | After you use pangu-spacing-mode, you will see 25 | 26 | 你好,我是 coldnew,我喜歡使用 emacs。 27 | 28 | But the text doesn't get modified by this mode. After disabling 29 | pangu-spacing-mode, or when using another text editor to open the file, you 30 | will still see: 31 | 32 | 你好,我是coldnew,我喜歡使用emacs。 33 | 34 | pangu-spacing is named from [pangu.js](https://github.com/vinta/pangu.js)'s README. 35 | 36 | Translation of pangu.js's README [1] 37 | 38 | If you are the one who feel quiet ill when see Chinese, 39 | English and digits characters squeezed together and 40 | want to add whitespace to separate them, this plugin (support 41 | Chrome and Firefox) is what you need when surfing the 42 | internet. It will add whitespace between Chinese, 43 | half-width English, digits and symbols automatically. 44 | 45 | These spaces between English and Chinese characters are called 46 | pangu-spacing by a sinologist, since it breaks the confusion 47 | between full-width and half-width characters. 48 | Studies showed that people who dislike adding whitespace between 49 | English and Chinese characters also have relationship problems. 50 | Almost 70 percent of them will get married to the one they 51 | don't love, the rest are only left to their cat. 52 | Indeed, love and writing need some space in good time. 53 | 54 | Let's go for it. 55 | 56 | [1] https://github.com/vinta/pangu.js 57 | 58 | ### Commentary (Chinese) 59 | 60 | 61 | pangu-spacing-mode 是一個可以自動幫你將中文與英文之間加上`空白`作為分隔的 minor-mode, 他的名稱來自於 [pangu.js](https://github.com/vinta/pangu.js) 上的 README。 62 | 63 | 引述自 pangu.js README [1] 64 | 65 | 如果你跟我一樣,每次看到網頁上的中文字和英文、數字、符號擠在一塊,就會 66 | 坐立難安,忍不住想在它們之間加個空格。這個外掛(支援 Chrome 和 Firefox) 67 | 正是你在網路世界走跳所需要的東西,它會自動替你在網頁中所有的中文字和半 68 | 形的英文、數字、符號之間插入空白。 69 | 70 | 漢學家稱這個空白字元為「盤古之白」,因為它劈開了全形字和半形字之間的混 71 | 沌。另有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都 72 | 走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成 73 | 的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。 74 | 75 | 與大家共勉之。 76 | 77 | [1] https://github.com/vinta/pangu.js 78 | 79 | ### Installation 80 | 81 | 82 | If you have `melpa` and `emacs24` installed, simply type: 83 | 84 | M-x package-install pangu-spacing 85 | 86 | 87 | For `cask` user, just add following lines in your `Cask` file 88 | 89 | ```elisp 90 | (source melpa) 91 | 92 | (depends-on "pangu-spacing") 93 | ``` 94 | 95 | 96 | ### Configuration 97 | 98 | 99 | In your .emacs 100 | 101 | ```elisp 102 | (require 'pangu-spacing) 103 | (global-pangu-spacing-mode 1) 104 | ``` 105 | 106 | pangu-spacing-mode does not actuall yinsert space between English and 107 | Chinese by default. If you want this behaviour, enable this option manually. 108 | 109 | ```elisp 110 | (setq pangu-spacing-real-insert-separtor t) 111 | ``` 112 | 113 | After enabling this, pangu-space will be inserted before you save file. 114 | 115 | If you only want to insert whitespace in some specific mode, but add 116 | virtual space in another mode, you can use following code to achieve 117 | this: (take org-mode as example) 118 | 119 | ```elisp 120 | (add-hook 'org-mode-hook 121 | '(lambda () 122 | (set (make-local-variable 'pangu-spacing-real-insert-separtor) t))) 123 | ``` 124 | 125 | 126 | 127 | 128 | ### Customization Documentation 129 | 130 | #### `pangu-spacing-separator` 131 | 132 | String to be displayed between Chinese and English. 133 | 134 | #### `pangu-spacing-real-insert-separtor` 135 | 136 | Set t or nil to make space show only on overlay or insert in file. 137 | When you set t here, the space will be insert when you save file. 138 | 139 | #### `pangu-spacing-inhibit-mode-alist` 140 | 141 | Inhibit mode alist for pangu-spacing-mode. 142 | 143 | #### `pangu-spacing-special-region-func-alist` 144 | 145 | Alist mapping major-mode to the corresponding function to 146 | check for special region that shall not write real pangu-space 147 | 148 | ### Function and Macro Documentation 149 | 150 | #### `(pangu-spacing-chinese-two-byte-category)` 151 | 152 | Return the correct category name for Chinese two-byte characters. 153 | 154 | #### `(pangu-spacing-search-buffer REGEXP START END FUNC)` (macro) 155 | 156 | Helper macro to search buffer and do func according regexp for 157 | pangu-spacing-mode. 158 | 159 | #### `(pangu-spacing-search-overlay BEG END FUNC REGEXP)` (macro) 160 | 161 | Helper macro to search and update overlay according func and regexp for 162 | pangu-sapce-mode. 163 | 164 | #### `(pangu-spacing-search-and-replace MATCH REGEXP)` 165 | 166 | Replace regexp with match in buffer. 167 | 168 | #### `(pangu-spacing-overlay-p OV)` 169 | 170 | Determine whether overlay OV was created by space-between. 171 | 172 | #### `(pangu-spacing-check-overlay BEG END)` 173 | 174 | Insert a space between English words and Chinese characters in overlay. 175 | 176 | #### `(pangu-spacing-modify-buffer)` 177 | 178 | Real insert separator between English words and Chinese characters in buffer. 179 | 180 | #### `(pangu-spacing-region-has-pangu-spacing-overlays BEG END)` 181 | 182 | Check if region specified by BEG and END has overlay. 183 | Return t if it has at least one pangu-spacing overlay, nil if no overlay. 184 | 185 | #### `(pangu-spacing-make-overlay BEG END)` 186 | 187 | Allocate a pangu-spacing overlay in range. 188 | 189 | #### `(pangu-spacing-delete-overlay BEG END)` 190 | 191 | Delete all pangu-spacing-overlays in BUFFER. 192 | 193 | #### `(pangu-spacing-delete-all-overlays &optional BEG END)` 194 | 195 | Delete all pangu-spacing-overlays in BUFFER. 196 | 197 | #### `(pangu-spacing-space-current-buffer)` 198 | 199 | Space current buffer. 200 | It will really insert separator, no matter what 201 | `pangu-spacing-real-insert-separtor` is. 202 | 203 | ----- 204 |
205 | Markdown README file generated by 206 | make-readme-markdown.el 207 |
208 | -------------------------------------------------------------------------------- /pangu-spacing.el: -------------------------------------------------------------------------------- 1 | ;;; pangu-spacing.el --- Minor-mode to add space between Chinese and English characters. 2 | 3 | ;; Copyright (C) 2013, 2014 Yen-Chin, Lee. 4 | 5 | ;; Author: coldnew 6 | ;; Kyewords: converience 7 | ;; Version: 0.4 8 | ;; X-URL: http://github.com/coldnew/pangu-spacing 9 | ;; URL: http://github.com/coldnew/pangu-spacing 10 | 11 | ;; This file is free software: you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation, either version 3 of the License, or 14 | ;; (at your option) any later version. 15 | 16 | ;; This file is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with GNU Emacs. If not, see . 23 | 24 | 25 | ;;; Commentary: 26 | 27 | ;;; Screenshot: 28 | ;; ![Screenshot](https://github.com/coldnew/pangu-spacing/raw/master/screenshot/screenshot.gif) 29 | 30 | ;;; Commentary (English): 31 | ;; pangu-spacing-mode is an minor-mode to auto add `space' between Chinese 32 | ;; and English characters. Note that these whitespace characters are not really 33 | ;; added to your file. It's just a local visual change. 34 | 35 | ;; Take following sentance for example: 36 | ;; 37 | ;; 你好,我是coldnew,我喜歡使用emacs。 38 | ;; 39 | ;; After you use pangu-spacing-mode, you will see 40 | ;; 41 | ;; 你好,我是 coldnew,我喜歡使用 emacs。 42 | ;; 43 | ;; But the text doesn't get modified by this mode. After disabling 44 | ;; pangu-spacing-mode, or when using another text editor to open the file, you 45 | ;; will still see: 46 | ;; 47 | ;; 你好,我是coldnew,我喜歡使用emacs。 48 | 49 | ;; pangu-spacing is named from [pangu.js](https://github.com/vinta/pangu.js)'s README. 50 | ;; 51 | ;; Translation of pangu.js's README [1] 52 | ;; 53 | ;; If you are the one who feel quiet ill when see Chinese, 54 | ;; English and digits characters squeezed together and 55 | ;; want to add whitespace to separate them, this plugin (support 56 | ;; Chrome and Firefox) is what you need when surfing the 57 | ;; internet. It will add whitespace between Chinese, 58 | ;; half-width English, digits and symbols automatically. 59 | 60 | ;; These spaces between English and Chinese characters are called 61 | ;; pangu-spacing by a sinologist, since it breaks the confusion 62 | ;; between full-width and half-width characters. 63 | ;; Studies showed that people who dislike adding whitespace between 64 | ;; English and Chinese characters also have relationship problems. 65 | ;; Almost 70 percent of them will get married to the one they 66 | ;; don't love, the rest are only left to their cat. 67 | ;; Indeed, love and writing need some space in good time. 68 | 69 | ;; Let's go for it. 70 | 71 | ;; [1] https://github.com/vinta/pangu.js 72 | 73 | ;;; Commentary (Chinese): 74 | 75 | ;; pangu-spacing-mode 是一個可以自動幫你將中文與英文之間加上`空白'作為分隔的 minor-mode, 他的名稱來自於 [pangu.js](https://github.com/vinta/pangu.js) 上的 README。 76 | ;; 77 | ;; 引述自 pangu.js README [1] 78 | ;; 79 | ;; 如果你跟我一樣,每次看到網頁上的中文字和英文、數字、符號擠在一塊,就會 80 | ;; 坐立難安,忍不住想在它們之間加個空格。這個外掛(支援 Chrome 和 Firefox) 81 | ;; 正是你在網路世界走跳所需要的東西,它會自動替你在網頁中所有的中文字和半 82 | ;; 形的英文、數字、符號之間插入空白。 83 | ;; 84 | ;; 漢學家稱這個空白字元為「盤古之白」,因為它劈開了全形字和半形字之間的混 85 | ;; 沌。另有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都 86 | ;; 走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成 87 | ;; 的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。 88 | ;; 89 | ;; 與大家共勉之。 90 | 91 | ;; [1] https://github.com/vinta/pangu.js 92 | 93 | ;;; Installation: 94 | 95 | ;; If you have `melpa` and `emacs24` installed, simply type: 96 | ;; 97 | ;; M-x package-install pangu-spacing 98 | ;; 99 | 100 | ;; For `cask' user, just add following lines in your `Cask' file 101 | ;; 102 | ;; ```elisp 103 | ;; (source melpa) 104 | ;; 105 | ;; (depends-on "pangu-spacing") 106 | ;; ``` 107 | ;; 108 | 109 | ;;; Configuration 110 | 111 | ;; In your .emacs 112 | ;; 113 | ;; ```elisp 114 | ;; (require 'pangu-spacing) 115 | ;; (global-pangu-spacing-mode 1) 116 | ;; ``` 117 | ;; 118 | ;; pangu-spacing-mode does not actuall yinsert space between English and 119 | ;; Chinese by default. If you want this behaviour, enable this option manually. 120 | ;; 121 | ;; ```elisp 122 | ;; (setq pangu-spacing-real-insert-separtor t) 123 | ;; ``` 124 | ;; 125 | ;; After enabling this, pangu-space will be inserted before you save file. 126 | ;; 127 | ;; If you only want to insert whitespace in some specific mode, but add 128 | ;; virtual space in another mode, you can use following code to achieve 129 | ;; this: (take org-mode as example) 130 | ;; 131 | ;; ```elisp 132 | ;; (add-hook 'org-mode-hook 133 | ;; '(lambda () 134 | ;; (set (make-local-variable 'pangu-spacing-real-insert-separtor) t))) 135 | ;; ``` 136 | ;; 137 | 138 | ;;; Code: 139 | 140 | (defgroup pangu-spacing nil 141 | "Add space between Chinese and English characters automatically." 142 | :group 'convenience 143 | :link '(url-link :tag "Github" "https://github.com/coldnew/pangu-spacing")) 144 | 145 | ;;;; Custom Variables 146 | 147 | (defcustom pangu-spacing-separator " " 148 | "String to be displayed between Chinese and English." 149 | :group 'pangu-spacing 150 | :type 'string 151 | :initialize 'custom-initialize-default) 152 | 153 | (defcustom pangu-spacing-real-insert-separtor nil 154 | "Set t or nil to make space show only on overlay or insert in file. 155 | When you set t here, the space will be insert when you save file." 156 | :group 'pangu-spacing 157 | :type 'boolean) 158 | 159 | (defface pangu-spacing-separator-face nil 160 | "Face for pangu-spacing-mode separator." 161 | :group 'pangu-spacing) 162 | 163 | (defcustom pangu-spacing-inhibit-mode-alist '(eshell-mode shell-mode term-mode) 164 | "Inhibit mode alist for pangu-spacing-mode." 165 | :group 'pangu-spacing 166 | :type 'list) 167 | 168 | ;;;; Local variables 169 | 170 | ;; NOTE: 171 | ;; We use `chinse-two-byte' instead of `chinese-two-byte', since there 172 | ;; are some typo in emacs version 21.1-24.3. For more information, 173 | ;; see: 174 | ;; 175 | ;; [Emacs-diffs] trunk r115873: Fix misspelling of 'chinese' in rx. 176 | ;; 177 | ;; Url: http://lists.gnu.org/archive/html/emacs-diffs/2014-01/msg00049.html 178 | ;; 179 | (eval-when-compile (require 'rx)) 180 | (defun pangu-spacing-chinese-two-byte-category () 181 | "Return the correct category name for Chinese two-byte characters." 182 | (if (assq 'chinese-two-byte rx--categories) 183 | "chinese-two-byte" 184 | "chinse-two-byte")) 185 | 186 | (defvar pangu-spacing-include-regexp 187 | ;; we didn't add korean because korean-hangul-two-byte is not implemented 188 | (eval `(rx (or (and (or (group-n 3 (any "。,!?;:「」()、")) 189 | (group-n 1 (or (category ,(intern (pangu-spacing-chinese-two-byte-category))) 190 | (category japanese-hiragana-two-byte) 191 | (category japanese-katakana-two-byte)))) 192 | (group-n 2 (in "a-zA-Z0-9"))) 193 | (and (group-n 1 (in "a-zA-Z0-9")) 194 | (or (group-n 3 (any "。,!?;:「」()、")) 195 | (group-n 2 (or (category ,(intern (pangu-spacing-chinese-two-byte-category))) 196 | (category japanese-hiragana-two-byte) 197 | (category japanese-katakana-two-byte)))))))) 198 | "Regexp to find Chinese character before English character. 199 | 200 | Group 1 contains the character before the potential pangu 201 | spacing, and group 2 the character after that. A space is needed 202 | when both group 1 and group 2 are non-nil. Group 3 exists as a 203 | workaround for excluded characters. Since rx does not support 204 | matching text that satisfy two regexp at the same time (we want 205 | to match all Chinese two byte characters, but not punctuations), 206 | we first try to match excluded characters, then the characters 207 | that need pangu-spacing. The excluded characters will be matched 208 | to group 3, and shortcut the matching for Chinese characters. 209 | Thus group 1 and group 2 will both be non nil when a pangu space 210 | is needed.") 211 | 212 | ;;;; Functions 213 | 214 | (defmacro pangu-spacing-search-buffer (regexp start end func) 215 | "Helper macro to search buffer and do func according regexp for 216 | pangu-spacing-mode." 217 | `(let ((start ,start) (end ,end)) 218 | (save-excursion 219 | (goto-char start) 220 | (while (re-search-forward ,regexp end t) 221 | (when (and (match-beginning 1) 222 | (match-beginning 2)) 223 | ,func 224 | (backward-char)))))) 225 | 226 | (defmacro pangu-spacing-search-overlay (beg end func regexp) 227 | "Helper macro to search and update overlay according func and regexp for 228 | pangu-sapce-mode." 229 | `(pangu-spacing-search-buffer ,regexp ,beg ,end 230 | (,func (match-beginning 1) (match-end 1)))) 231 | 232 | (defun pangu-spacing-org-mode-at-special-region () 233 | (interactive) 234 | (let ((element (org-element-at-point))) 235 | (when (or (member (org-element-type element) 236 | '(src-block keyword example-block export-block 237 | latex-environment planning)) 238 | (member (car (org-element-context element)) 239 | '(inline-src-block timestamp link code verbatim))) 240 | t))) 241 | 242 | (defcustom pangu-spacing-special-region-func-alist 243 | '((org-mode . pangu-spacing-org-mode-at-special-region)) 244 | "Alist mapping major-mode to the corresponding function to 245 | check for special region that shall not write real pangu-space" 246 | :group 'pangu-spacing 247 | :type '(alist :key-type (symbol) 248 | :value-type (function))) 249 | 250 | (defun pangu-spacing-search-and-replace (match regexp) 251 | "Replace regexp with match in buffer." 252 | (let ((at-special-region-func 253 | (cdr (assq major-mode pangu-spacing-special-region-func-alist)))) 254 | (pangu-spacing-search-buffer 255 | regexp (point-min) (point-max) 256 | (unless (and at-special-region-func 257 | (save-match-data (funcall at-special-region-func))) 258 | (replace-match match nil nil))))) 259 | 260 | (defun pangu-spacing-overlay-p (ov) 261 | "Determine whether overlay OV was created by space-between." 262 | (and (overlayp ov) (overlay-get ov 'pangu-spacing-overlay))) 263 | 264 | 265 | (defun pangu-spacing-check-overlay (beg end) 266 | "Insert a space between English words and Chinese characters in overlay." 267 | (setq beg (if beg 268 | (max (- beg 1) (point-min)) 269 | (point-min)) 270 | end (or end (point-max))) 271 | (pangu-spacing-delete-overlay beg end) 272 | (setq end (min (1+ end) (point-max))) 273 | (pangu-spacing-search-overlay beg end 274 | pangu-spacing-make-overlay 275 | pangu-spacing-include-regexp) 276 | ) 277 | 278 | (defun pangu-spacing-modify-buffer () 279 | "Real insert separator between English words and Chinese characters in buffer." 280 | (when pangu-spacing-real-insert-separtor 281 | (pangu-spacing-search-and-replace "\\1 \\2" 282 | pangu-spacing-include-regexp)) 283 | ;; nil must be returned to allow use in write file hooks 284 | nil) 285 | 286 | (defun pangu-spacing-region-has-pangu-spacing-overlays (beg end) 287 | "Check if region specified by BEG and END has overlay. 288 | Return t if it has at least one pangu-spacing overlay, nil if no overlay." 289 | (let ((ov (overlays-in beg end)) 290 | (has-pangu-spacing-overlays nil)) 291 | (while (consp ov) 292 | (when (pangu-spacing-overlay-p (car ov)) 293 | (setq has-pangu-spacing-overlays t 294 | ;; break the while loop 295 | ov nil)) 296 | (setq ov (cdr ov)) 297 | has-pangu-spacing-overlays))) 298 | 299 | (defun pangu-spacing-make-overlay (beg end) 300 | "Allocate a pangu-spacing overlay in range." 301 | (when (not (pangu-spacing-region-has-pangu-spacing-overlays beg end)) 302 | (let ((ov (make-overlay beg end nil t t)) 303 | (face 'pangu-spacing-separator-face)) 304 | (overlay-put ov 'pangu-spacing-overlay t) 305 | (overlay-put ov 'after-string (propertize pangu-spacing-separator 'face face)) 306 | ov))) 307 | 308 | (defun pangu-spacing-delete-overlay (beg end) 309 | "Delete all pangu-spacing-overlays in BUFFER." 310 | (dolist (ov (overlays-in beg end)) 311 | (when (pangu-spacing-overlay-p ov) 312 | (delete-overlay ov)))) 313 | 314 | (defun pangu-spacing-delete-all-overlays (&optional beg end) 315 | "Delete all pangu-spacing-overlays in BUFFER." 316 | (pangu-spacing-delete-overlay (point-min) (point-max))) 317 | 318 | (defun turn-on-pangu-spacing (beg end) 319 | (pangu-spacing-check-overlay beg end)) 320 | 321 | ;;;###autoload 322 | (defun pangu-spacing-space-current-buffer () 323 | "Space current buffer. 324 | It will really insert separator, no matter what 325 | `pangu-spacing-real-insert-separtor' is." 326 | (interactive) 327 | (let ((pangu-spacing-real-insert-separtor t)) 328 | (pangu-spacing-modify-buffer))) 329 | 330 | ;;;###autoload 331 | (define-minor-mode pangu-spacing-mode 332 | "Toggle pangu-spacing-mode" 333 | :group 'pangu-spacing 334 | :global nil 335 | :init-value nil 336 | :lighter " Ρ" 337 | (unless (or (member major-mode pangu-spacing-inhibit-mode-alist) 338 | (minibufferp (current-buffer))) 339 | (save-restriction 340 | (widen) 341 | (if pangu-spacing-mode 342 | (progn 343 | (jit-lock-register 'turn-on-pangu-spacing) 344 | (add-hook 'local-write-file-hooks 'pangu-spacing-modify-buffer)) 345 | (progn 346 | (jit-lock-unregister 'turn-on-pangu-spacing) 347 | (remove-hook 'local-write-file-hooks 'pangu-spacing-modify-buffer) 348 | (pangu-spacing-delete-all-overlays))))) 349 | pangu-spacing-mode) 350 | 351 | ;;;###autoload 352 | (define-globalized-minor-mode global-pangu-spacing-mode 353 | pangu-spacing-mode pangu-spacing-mode) 354 | 355 | 356 | (provide 'pangu-spacing) 357 | ;;; pangu-spacing.el ends here 358 | -------------------------------------------------------------------------------- /screenshot/screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coldnew/pangu-spacing/6509df9c90bbdb9321a756f7ea15bb2b60ed2530/screenshot/screenshot.gif -------------------------------------------------------------------------------- /test/pangu-spacing-test.el: -------------------------------------------------------------------------------- 1 | ;;; pangu-spacing-test.el --- Tests for pangu-spacing 2 | 3 | (require 'ert) 4 | (require 'pangu-spacing) 5 | 6 | (ert-deftest pangu-spacing-test/modify () 7 | "Test if modify works" 8 | (with-temp-buffer 9 | (pangu-spacing-mode 1) 10 | (insert "跟alex解释 task 弹性的问题。a。") 11 | (let ((pangu-spacing-real-insert-separtor t)) 12 | (pangu-spacing-modify-buffer)) 13 | (should (string-equal "跟 alex 解释 task 弹性的问题。a。" (buffer-string))) 14 | ) 15 | (with-temp-buffer 16 | (pangu-spacing-mode 1) 17 | (insert "2019年08月22日 星期四") 18 | (let ((pangu-spacing-real-insert-separtor t)) 19 | (pangu-spacing-modify-buffer)) 20 | (should (string-equal "2019 年 08 月 22 日 星期四" (buffer-string))) 21 | ) 22 | ) 23 | 24 | (ert-deftest pangu-spacing-test/org-mode-special-region () 25 | (with-temp-buffer 26 | (insert "* English中文English [[https://github.com/][link中文link]] 27 | CLOSED: [2018-10-14日21:42] 28 | - State \"DONE\" from \"TODO\" [2018-10-14日21:42] 29 | [2018-09-17一] 30 | English中文English 31 | * ~English中文English~ 32 | <2018-09-17一> 33 | =/home/me/English中文English.conf= 34 | #+BEGIN_SRC conf :tangle English中文English.conf 35 | English中文English 36 | #+END_SRC") 37 | (message "1") 38 | (pangu-spacing-mode 1) 39 | (message "2") 40 | (org-mode) 41 | (message "3") 42 | (let ((pangu-spacing-real-insert-separtor t)) 43 | (pangu-spacing-modify-buffer)) 44 | (message "4") 45 | (should (string-equal (buffer-string) 46 | "* English 中文 English [[https://github.com/][link中文link]] 47 | CLOSED: [2018-10-14日21:42] 48 | - State \"DONE\" from \"TODO\" [2018-10-14日21:42] 49 | [2018-09-17一] 50 | English 中文 English 51 | * ~English中文English~ 52 | <2018-09-17一> 53 | =/home/me/English中文English.conf= 54 | #+BEGIN_SRC conf :tangle English中文English.conf 55 | English中文English 56 | #+END_SRC")))) 57 | 58 | (ert-deftest pangu-spacing-test/show () 59 | "Test if showing works" 60 | (with-temp-buffer 61 | (pangu-spacing-mode 1) 62 | (insert "跟alex解释 task 弹性的问题。a。") 63 | (should (string-equal "跟alex解释 task 弹性的问题。a。" (buffer-string))) 64 | (pangu-spacing-check-overlay (point-min) (point-max)) 65 | (let* ((overlay-list (overlays-in (point-min) (point-max))) 66 | (overlay-pos (mapcar (lambda (ov) 67 | (when (pangu-spacing-overlay-p ov) 68 | (overlay-end ov))) 69 | overlay-list)) 70 | (sorted-pos (sort overlay-pos '>=))) 71 | (mapcar (lambda (pos) 72 | (goto-char pos) 73 | (insert " ")) 74 | sorted-pos) 75 | (should (string-equal "跟 alex 解释 task 弹性的问题。a。" (buffer-string)))))) 76 | 77 | (ert-deftest pangu-spacing-test/japanese () 78 | "Test Japanese and Korean pangu-spacing" 79 | (with-temp-buffer 80 | (pangu-spacing-mode 1) 81 | (insert "こんにちはhello worldこんにちは 82 | コンニチハhello worldコンニチハ") 83 | (let ((pangu-spacing-real-insert-separtor t)) 84 | (pangu-spacing-modify-buffer)) 85 | ;; (pangu-spacing-check-overlay (point-min) (point-max)) 86 | ;; (let* ((overlay-list (overlays-in (point-min) (point-max))) 87 | ;; (overlay-pos (mapcar (lambda (ov) 88 | ;; (when (pangu-spacing-overlay-p ov) 89 | ;; (overlay-end ov))) 90 | ;; overlay-list)) 91 | ;; (sorted-pos (sort overlay-pos '>=))) 92 | ;; (mapcar (lambda (pos) 93 | ;; (goto-char pos) 94 | ;; (insert " ")) 95 | ;; sorted-pos) 96 | (should (string-equal "こんにちは hello world こんにちは 97 | コンニチハ hello world コンニチハ" (buffer-string)))) 98 | ) 99 | 100 | ;;; pangu-spacing-test.el ends here 101 | -------------------------------------------------------------------------------- /test/test-helper.el: -------------------------------------------------------------------------------- 1 | ;;; test-helper.el --- Helpers for pangu-spacing-test.el 2 | 3 | ;;; test-helper.el ends here 4 | --------------------------------------------------------------------------------