diff options
| author | Eli Zaretskii | 2025-03-02 15:25:53 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2025-03-02 15:25:53 +0200 |
| commit | 8937dee9e418c64587769dd22bb9683cd3690688 (patch) | |
| tree | d85f4f34c5f0febfb573eea0daf4d465671c40e7 | |
| parent | e34d7a7c4eb90cde7a2dc55ac5a02fae303e5d0f (diff) | |
| download | emacs-8937dee9e418c64587769dd22bb9683cd3690688.tar.gz emacs-8937dee9e418c64587769dd22bb9683cd3690688.zip | |
New commands to convert ASCII to fullwidth characters and back
* lisp/textmodes/text-mode.el (text-mode--fullwidth-table): New
variable.
(text-mode--get-fullwidth-table): New internal function.
(fullwidth-region, halfwidth-region, fullwidth-word)
(halfwidth-word): New commands. (Bug#71822)
* etc/NEWS: Announce new commands.
| -rw-r--r-- | etc/NEWS | 11 | ||||
| -rw-r--r-- | lisp/textmodes/text-mode.el | 79 |
2 files changed, 90 insertions, 0 deletions
| @@ -445,6 +445,17 @@ modal editing packages. | |||
| 445 | * Changes in Specialized Modes and Packages in Emacs 31.1 | 445 | * Changes in Specialized Modes and Packages in Emacs 31.1 |
| 446 | 446 | ||
| 447 | --- | 447 | --- |
| 448 | ** Text mode | ||
| 449 | |||
| 450 | *** New commands to convert between ASCII and full-width characters. | ||
| 451 | New commands 'fullwidth-region' and 'fullwidth-word' convert ASCII | ||
| 452 | characters in region or in the word at point to the corresponding | ||
| 453 | full-width characters, which are customarily used instead of ASCII | ||
| 454 | characters in CJK texts. For example, 'A' is converted to 'A', '1' is | ||
| 455 | converted to '1', etc. Companion commands 'halfwidth-region' and | ||
| 456 | 'halfwidth-word' perform the opposite conversion. | ||
| 457 | |||
| 458 | --- | ||
| 448 | ** ASM mode | 459 | ** ASM mode |
| 449 | 460 | ||
| 450 | *** 'asm-mode-set-comment-hook' is obsolete. | 461 | *** 'asm-mode-set-comment-hook' is obsolete. |
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index d918efa72c6..2d019f54aec 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el | |||
| @@ -271,6 +271,85 @@ The argument NLINES says how many lines to center." | |||
| 271 | 271 | ||
| 272 | (define-obsolete-function-alias 'indented-text-mode #'text-mode "29.1") | 272 | (define-obsolete-function-alias 'indented-text-mode #'text-mode "29.1") |
| 273 | 273 | ||
| 274 | |||
| 275 | |||
| 276 | (defvar text-mode--fullwidth-table nil) | ||
| 277 | |||
| 278 | (defun text-mode--get-fullwidth-table () | ||
| 279 | "Return translation table for converting half-width characters to fullwidth." | ||
| 280 | (or (and (char-table-p text-mode--fullwidth-table) | ||
| 281 | text-mode--fullwidth-table) | ||
| 282 | ;; Create the translation table. | ||
| 283 | (let ((tbl (make-char-table 'translation-table)) | ||
| 284 | (rev-tbl (make-char-table 'translation-table)) | ||
| 285 | (ch ?!)) | ||
| 286 | (while (<= ch ?~) | ||
| 287 | ;; ! -> !, 0 -> 0, A -> A, etc. | ||
| 288 | (aset tbl ch (+ ch #xFEE0)) | ||
| 289 | (aset rev-tbl (+ ch #xFEE0) ch) | ||
| 290 | (setq ch (1+ ch))) | ||
| 291 | (set-char-table-extra-slot tbl 0 rev-tbl) | ||
| 292 | (set-char-table-extra-slot tbl 1 1) | ||
| 293 | (set-char-table-extra-slot rev-tbl 1 1) | ||
| 294 | (put 'text-mode--fullwidth-table 'translation-table tbl) | ||
| 295 | (setq text-mode--fullwidth-table tbl) | ||
| 296 | tbl))) | ||
| 297 | |||
| 298 | (defun fullwidth-region (from to) | ||
| 299 | "Convert ASCII characters in the region to their fullwidth variants. | ||
| 300 | This converts 1 to 1, A to A, etc. | ||
| 301 | When called from Lisp, FROM and TO are character positions that define | ||
| 302 | the region in which to convert characters." | ||
| 303 | (interactive "r") | ||
| 304 | (translate-region from to | ||
| 305 | (text-mode--get-fullwidth-table))) | ||
| 306 | |||
| 307 | (defun halfwidth-region (from to) | ||
| 308 | "Convert fullwidth characters in the region to their ASCII variants. | ||
| 309 | This converts 1 to 1, A to A, etc. | ||
| 310 | When called from Lisp, FROM and TO are character positions that define | ||
| 311 | the region in which to convert characters." | ||
| 312 | (interactive "r") | ||
| 313 | (translate-region from to | ||
| 314 | (char-table-extra-slot (text-mode--get-fullwidth-table) | ||
| 315 | 0))) | ||
| 316 | |||
| 317 | (defun fullwidth-word (arg) | ||
| 318 | "Convert fullwidth characters in word at point, moving over the word. | ||
| 319 | This converts fullwidth characters to their ASCII variants: | ||
| 320 | 1 to 1, A to A, etc. | ||
| 321 | With numerical argument ARG, convert that many words starting from point. | ||
| 322 | With negative argument, convert previous words, but do not move point. | ||
| 323 | If point is in the middle of a word, the part of that word before point | ||
| 324 | is ignored when converting forward, and the part of that word after | ||
| 325 | point is ignored when converting backward." | ||
| 326 | (interactive "p") | ||
| 327 | (let* ((pt (point-marker)) | ||
| 328 | (beg pt) | ||
| 329 | (end (progn | ||
| 330 | (forward-word arg) | ||
| 331 | (point)))) | ||
| 332 | (fullwidth-region beg end) | ||
| 333 | (or (> arg 0) (goto-char pt)))) | ||
| 334 | |||
| 335 | (defun halfwidth-word (arg) | ||
| 336 | "Convert characters in word at point to fullwidth, moving over the word. | ||
| 337 | This converts ASCII characters to their fullwidth variants: | ||
| 338 | 1 to 1, A to A, etc. | ||
| 339 | With numerical argument ARG, convert that many words starting from point. | ||
| 340 | With negative argument, convert previous words, but do not move point. | ||
| 341 | If point is in the middle of a word, the part of that word before point | ||
| 342 | is ignored when converting forward, and the part of that word after | ||
| 343 | point is ignored when converting backward." | ||
| 344 | (interactive "p") | ||
| 345 | (let* ((pt (point-marker)) | ||
| 346 | (beg pt) | ||
| 347 | (end (progn | ||
| 348 | (forward-word arg) | ||
| 349 | (point)))) | ||
| 350 | (halfwidth-region beg end) | ||
| 351 | (or (> arg 0) (goto-char pt)))) | ||
| 352 | |||
| 274 | (provide 'text-mode) | 353 | (provide 'text-mode) |
| 275 | 354 | ||
| 276 | ;;; text-mode.el ends here | 355 | ;;; text-mode.el ends here |