Skip to content

Commit

Permalink
add auto-space fork LuciusChen/.emacs.d
Browse files Browse the repository at this point in the history
  • Loading branch information
chens committed Oct 30, 2024
1 parent 3d97264 commit 7f2884a
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
1 change: 1 addition & 0 deletions init.el
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
(require 'init-perl)
(require 'init-anki)
(require 'init-date)
(require 'init-auto-space)
;; Extra packages which don't require any configuration


Expand Down
106 changes: 106 additions & 0 deletions lisp/init-auto-space.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
;;; auto-space.el --- Automatically add space between Chinese and English characters -*- lexical-binding: t -*-
(defun add-space-between-chinese-and-english ()
"Automatically add a space between Chinese and English characters."
(let ((current-char (char-before))
(prev-char (char-before (1- (point))))
(next-char (char-after)))
(when (and current-char prev-char
(or (and (is-chinese-character prev-char)
(is-halfwidth-character current-char))
(and (is-halfwidth-character prev-char)
(is-chinese-character current-char)))
(not (eq prev-char ?\s))) ; Check if the previous character is a space
(save-excursion
(goto-char (1- (point)))
(insert " ")))
(when (and current-char next-char
(should-insert-space current-char next-char)
(not (eq current-char ?\s))) ; Check if the current character is a space
(save-excursion
(goto-char (point))
(insert " ")))))

(defun is-chinese-character (char)
"Determine if a character is a Chinese character."
(and char (or (and (>= char #x4e00) (<= char #x9fff))
(and (>= char #x3400) (<= char #x4dbf))
(and (>= char #x20000) (<= char #x2a6df))
(and (>= char #x2a700) (<= char #x2b73f))
(and (>= char #x2b740) (<= char #x2b81f))
(and (>= char #x2b820) (<= char #x2ceaf)))))

(defun is-halfwidth-character (char)
"Determine if a character is a halfwidth character using char-width."
(and char (or (and (>= char ?a) (<= char ?z))
(and (>= char ?A) (<= char ?Z))
(and (>= char ?0) (<= char ?9))
(and char (member char '(?% ?> ?< ?+ ?=))))))

(defun should-insert-space (char1 char2)
"Determine if a space should be inserted between CHAR1 and CHAR2."
(or (and (is-chinese-character char1) (is-halfwidth-character char2))
(and (is-halfwidth-character char1) (is-chinese-character char2))))

(defun delayed-add-space-between-chinese-and-english ()
"Delay execution to automatically add a space between Chinese and English characters."
(run-with-idle-timer 0 nil 'add-space-between-chinese-and-english))

(defun insert-space-if-needed (char1 char2 buffer-content)
"Insert a space between CHAR1 and CHAR2 in BUFFER-CONTENT if needed."
(if (and (should-insert-space char1 char2) (not (eq char2 ?\s)))
(concat buffer-content " ")
buffer-content))

(defun process-pasted-text (text prev-char next-char)
"Process pasted TEXT to add spaces between Chinese and English characters, considering PREV-CHAR and NEXT-CHAR."
(with-temp-buffer
(insert (if prev-char (concat (char-to-string prev-char) text) text))
(goto-char (point-min))
(while (not (eobp))
(let ((current-char (char-after))
(next-char-internal (char-after (1+ (point)))))
(when (and current-char next-char-internal
(should-insert-space current-char next-char-internal)
(not (eq (char-after) ?\s)))
(save-excursion
(goto-char (1+ (point)))
(insert " "))))
(forward-char))
(let ((buffer-content (buffer-string)))
(if prev-char
(setq buffer-content (substring buffer-content 1)))
;; Add space between the last char of pasted text and next-char
(setq buffer-content (insert-space-if-needed
(aref buffer-content (1- (length buffer-content)))
next-char
buffer-content))
buffer-content)))

(defun auto-space-yank-advice (orig-fun &rest args)
"Advice to automatically add spaces between Chinese and English characters after yanking."
(let ((beg (point))
(prev-char (char-before)))
(apply orig-fun args)
(let ((end (point))
(next-char (char-after)))
(let ((pasted-text (buffer-substring-no-properties beg end)))
(delete-region beg end)
(insert (process-pasted-text pasted-text prev-char next-char))))))

;;;###autoload
(define-minor-mode auto-space-mode
"Mode to automatically add a space between Chinese and English characters."
:lighter " Auto-Space"
:global t
(if auto-space-mode
(progn
(advice-add 'yank :around #'auto-space-yank-advice)
(advice-add 'yank-pop :around #'auto-space-yank-advice)
(add-hook 'post-self-insert-hook 'add-space-between-chinese-and-english))
(progn
(advice-remove 'yank #'auto-space-yank-advice)
(advice-remove 'yank-pop #'auto-space-yank-advice)
(remove-hook 'post-self-insert-hook 'add-space-between-chinese-and-english))))

(provide 'init-auto-space)
;;; auto-space.el ends here
62 changes: 62 additions & 0 deletions lisp/init-editing-utils.el
Original file line number Diff line number Diff line change
Expand Up @@ -560,5 +560,67 @@ ORIG is the advised function, which is called with its ARGS."



(defun process-pasted-text (text prev-char next-char)
"Process pasted TEXT to add spaces between Chinese and English characters, considering PREV-CHAR and NEXT-CHAR."
(with-temp-buffer
(insert (if prev-char (concat (char-to-string prev-char) text) text))
(goto-char (point-min))
(while (not (eobp))
(let ((current-char (char-after))
(next-char-internal (char-after (1+ (point)))))
(when (and current-char next-char-internal
(should-insert-space current-char next-char-internal)
(not (eq (char-after) ?\s)))
(save-excursion
(goto-char (1+ (point)))
(insert " "))))
(forward-char))
(let ((buffer-content (buffer-string)))
(if prev-char
(setq buffer-content (substring buffer-content 1)))
;; Add space between the last char of pasted text and next-char
(setq buffer-content (insert-space-if-needed
(aref buffer-content (1- (length buffer-content)))
next-char
buffer-content))
buffer-content)))

;; (defun auto-space-yank-advice (orig-fun &rest args)
;; "Advice to automatically add spaces between Chinese and English characters after yanking."
;; (let ((beg (point))
;; (prev-char (char-before)))
;; (apply orig-fun args)
;; (let ((end (point))
;; (next-char (char-after)))
;; (let ((pasted-text (buffer-substring-no-properties beg end)))
;; (delete-region beg end)
;; (insert (process-pasted-text pasted-text prev-char next-char))))))

;; (advice-add 'yank :around #'auto-space-yank-advice)
;; (advice-add 'yank-pop :around #'auto-space-yank-advice)

;; (defun add-space-between-chinese-and-english ()
;; "Automatically add a space between Chinese and English characters."
;; (let ((current-char (char-before))
;; (prev-char (char-before (1- (point))))
;; (next-char (char-after)))
;; (when (and current-char prev-char
;; (or (and (is-chinese-character prev-char) (is-halfwidth-character current-char))
;; (and (is-halfwidth-character prev-char) (is-chinese-character current-char)))
;; (not (eq prev-char ?\s))) ; Check if the previous character is a space
;; (save-excursion
;; (goto-char (1- (point)))
;; (insert " ")))
;; (when (and current-char next-char
;; (or (and (is-chinese-character current-char) (is-halfwidth-character next-char))
;; (and (is-halfwidth-character current-char) (is-chinese-character next-char)))
;; (not (eq current-char ?\s))) ; Check if the current character is a space
;; (save-excursion
;; (goto-char (point))
;; (insert " ")))))




(provide 'init-editing-utils)
;;; init-editing-utils.el ends here

0 comments on commit 7f2884a

Please sign in to comment.