Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Lem エディタの Windows 用の文字幅データの設定サンプル (実験中)

Lem エディタの Windows 用の文字幅データの設定サンプル (実験中)

  • Lem エディタ ( https://github.com/cxxxr/lem ) の
    Windows 用の文字幅データの設定サンプルです。
    一部の文字の表示が改善されます。
    (カーソルの表示位置がずれたりするケース等)

    <<現状、Windows 10 では、あまり改善できていません>>

使用方法

  • 下にある init.lisp の wide characters setting の部分を、
    Lem の設定ファイル ( ~/.lem/init.lisp ) にコピーしてください。
    ( ~ の場所については、後述の「Lem エディタの 設定ファイルについて (補足)」を参照ください )

  • Windows 8.1 で、ConEmu上で、フォント設定を「MS ゴシック」にしていた場合には、
    上記コピー内の (defvar *conemu-font-is-ms-gothic* nil) という箇所を、
    (defvar *conemu-font-is-ms-gothic* t) に変更してください。
    (フォント設定が「Consolas」や「Lucida Console」の場合には、変更不要です)
    (現状、Windows 10 では、本設定は無効です)

その他 情報等

  • 参考用に、文字幅データの生成に使ったツール ( lem_eaw_conv.scm ) も下に置いておきます。
    (実行には Gauche が必要です。詳細については、ソースのコメントを参照ください)
    (使っているフォントと設定が合わない場合には、本ツールを改造することで対応できる場合があります)
    (現状、Windows 10 では、あまり改善できていません)

  • Lem エディタの Windows 上でのインストール手順については、以下のページを参照ください。
    https://gist.github.com/Hamayama/deba598ab70f5d5d6952b51f82793473
    (現状、MSYS2/MinGW-w64 の開発環境が必要です)

  • Lem エディタの Windows Terminal 上での実行方法 (Windows 10)
    https://gist.github.com/Hamayama/fc442e71304629527866f7c69c2e9f5e

  • Lem エディタの ConEmu 上での実行方法
    https://gist.github.com/Hamayama/16268a9d607eaebcc56df907eac97cd2

  • 関連プルリクエスト / 参考URL
    https://github.com/cxxxr/lem/pull/381
    https://github.com/cxxxr/lem/pull/380
    https://github.com/cxxxr/lem/pull/354
    https://github.com/hamano/locale-eaw

  • mintty 上での絵文字の幅
    Windows 8.1 では、.minttyrc に Charwidth=unicode という行を追加すると、
    絵文字 (#\U1F363 の「すし」等) の表示幅が2倍になり、
    カーソルがずれなくなる。
    (.minttyrc は MSYS2 の /home/(ユーザ名) フォルダにある)
    (ただし、#\U1F336 の「とうがらし」のように、まだずれる絵文字もあるもよう。。。)
    <参考URL>
    https://github.com/mintty/mintty/wiki/Tips#character-width
    https://github.com/cxxxr/lem/pull/348
    (現状、Windows 10 では、mintty 上で絵文字を表示できていません)

  • Lem エディタの 設定ファイルについて (補足)
    ~/.lem/init.lisp が、Lem エディタの設定ファイルになります(存在しなくても動作します)。
    ~ はホームディレクトリで、環境によって異なります。
    MSYS2/MinGW-w64 環境 (mintty 上の bash 等) では、通常、
    /home/(ユーザ名) がホームディレクトリになります。
    ( echo $HOME で確認できます )
    その他の環境 (Windows Terminal 上の cmd.exe 等) では、通常、
    c:\Users\(ユーザ名) がホームディレクトリになります。
    ( cmd.exe では、echo %USERPROFILE% で確認できます )
    ( PowerShell では、echo $env:USERPROFILE で確認できます )

(2018-12-14)(2018-12-15)(2018-12-20)(2019-5-12)(2019-5-15)
(2019-5-31)(2020-1-27)(2020-2-2)(2020-4-6)(2020-5-10)
(2020-10-1)(2020-10-12)(2020-11-3)(2020-11-23)(2021-1-14)
(2021-1-16)

;; -*- mode:lisp -*-
;;; Lem editor setting file (init.lisp)
;;; 2021-4-18 v2.04
;;;
;;; Usage : copy to ~/.lem/init.lisp
(in-package :lem-user)
;(load-theme "emacs-light")
(load-theme "emacs-dark")
;; for frame
(progn
;(defun lem-frame-multiplexer::enable-frame-multiplexer ())
;(define-key *global-keymap* "C-z c" 'lem-frame-multiplexer::frame-multiplexer-create-with-new-buffer-list)
;(define-key *global-keymap* "C-z d" 'lem-frame-multiplexer::frame-multiplexer-delete)
;(define-key *global-keymap* "C-z p" 'lem-frame-multiplexer::frame-multiplexer-prev)
;(define-key *global-keymap* "C-z n" 'lem-frame-multiplexer::frame-multiplexer-next)
(define-key *global-keymap* "C-x z c" 'lem-frame-multiplexer::frame-multiplexer-create-with-new-buffer-list)
(define-key *global-keymap* "C-x z d" 'lem-frame-multiplexer::frame-multiplexer-delete)
(define-key *global-keymap* "C-x z p" 'lem-frame-multiplexer::frame-multiplexer-prev)
(define-key *global-keymap* "C-x z n" 'lem-frame-multiplexer::frame-multiplexer-next)
)
;; for logical line move
(progn
;(setf lem::*use-new-vertical-move-function* t)
;(setf lem::*use-cursor-movement-workaround* t)
#+(and (not win32) lem-ncurses)
(progn
;(lem-ncurses::defkeycode "M-up" 564 (make-key :meta t :sym "Up"))
(lem-ncurses::defkeycode "M-down" 523 (make-key :meta t :sym "Down"))
(lem-ncurses::defkeycode "M-left" 543 (make-key :meta t :sym "Left"))
(lem-ncurses::defkeycode "M-right" 558 (make-key :meta t :sym "Right"))
)
(define-key *global-keymap* "M-Up" 'previous-logical-line)
(define-key *global-keymap* "M-Down" 'next-logical-line)
(when (fboundp 'move-to-beginning-of-logical-line)
(define-key *global-keymap* "M-Left" 'move-to-beginning-of-logical-line)
(define-key *global-keymap* "M-Right" 'move-to-end-of-logical-line))
)
;; for lisp-mode
(progn
;; indentation setting
(lem-lisp-syntax:set-indentation "alexandria:when-let" 1)
)
;; for scheme-mode
(progn
;; scheme process
;(setf lem-scheme-mode:*use-scheme-process* t)
;(setf lem-scheme-mode:*scheme-run-command* '("gosh" "-i"))
;(setf lem-scheme-mode:*scheme-load-command* "load")
;; scheme slime
;(setf lem-scheme-mode:*use-scheme-slime* :auto)
;(setf lem-scheme-mode:*use-scheme-set-library* :repl)
;(setf lem-scheme-mode:*use-scheme-autodoc* t)
(setf lem-scheme-mode:*scheme-swank-server-run-command*
;'("c:/Program Files (x86)/Gauche098/bin/gosh" "-r7" "-AC:/work/r7rs-swank-Gauche-custom"
;'("gosh" "-r7" "-A/home/(username)/devtool/r7rs-swank-Gauche-custom"
'("gosh" "-r7" "-AC:/work/r7rs-swank-Gauche-custom"
"-e(begin (import (gauche-swank)) (start-swank ,port))"))
;; scheme repl
;(setf lem-scheme-mode:*use-scheme-repl-shortcut* nil)
;; scheme keyword data
(setf (lem-scheme-mode:scheme-keyword-data)
(append
(lem-scheme-mode:scheme-keyword-data)
;; name completion highlight indentation
'(("reset" t t nil)
("shift" t t 1)
("call/pc" t t nil))))
)
;; for ncurses (not windows)
#+(and (not win32) lem-ncurses)
(progn
;; escape key delay setting
;(setf (variable-value 'lem-ncurses::escape-delay :global) 100)
(setf (variable-value 'lem-ncurses::escape-delay :global) 1000)
)
;; for windows pdcurses
#+(and win32 lem-ncurses)
(progn
;; escape key delay setting
;(setf (variable-value 'lem-ncurses::escape-delay :global) 1000)
;; input polling interval (sec)
;(setf (lem-ncurses:input-polling-interval) 0.001)
;; reserve last lines setting
;(setf (lem-ncurses::reserved-last-lines lem-ncurses::*windows-term-setting*) 1)
;(setf (lem-ncurses::reserved-last-lines lem-ncurses::*windows-term-setting*) 0)
;; write something to last line
;(setf (lem-ncurses::write-last-line lem-ncurses::*windows-term-setting*) t)
;(setf (lem-ncurses::write-last-line lem-ncurses::*windows-term-setting*) nil)
;; color setting
(when (or ;(eq (lem-ncurses::windows-term-type) :mintty)
;(eq (lem-ncurses::windows-term-type) :conemu)
(eq (lem-ncurses::windows-term-type) :winterm)
;(eq (lem-ncurses::windows-term-type) :cmd.exe)
)
(lem.term:term-set-color 0 #x00 #x00 #x00)
(lem.term:term-set-color 1 #x00 #x00 #x80)
(lem.term:term-set-color 2 #x00 #x80 #x00)
(lem.term:term-set-color 3 #x00 #x80 #x80)
(lem.term:term-set-color 4 #x80 #x00 #x00)
(lem.term:term-set-color 5 #x80 #x00 #x80)
(lem.term:term-set-color 6 #x80 #x80 #x00)
(lem.term:term-set-color 7 #xc0 #xc0 #xc0)
(lem.term:term-set-color 8 #x80 #x80 #x80)
(lem.term:term-set-color 9 #x00 #x00 #xff)
(lem.term:term-set-color 10 #x00 #xff #x00)
(lem.term:term-set-color 11 #x00 #xff #xff)
(lem.term:term-set-color 12 #xff #x00 #x00)
(lem.term:term-set-color 13 #xff #x00 #xff)
(lem.term:term-set-color 14 #xff #xff #x00)
(lem.term:term-set-color 15 #xff #xff #xff))
;; attribute setting
(when (or (eq (lem-ncurses::windows-term-type) :mintty)
;(eq (lem-ncurses::windows-term-type) :conemu)
;(eq (lem-ncurses::windows-term-type) :winterm)
(eq (lem-ncurses::windows-term-type) :cmd.exe)
)
(define-attribute modeline
;(t :foreground "white" :background "#404040")
(t :foreground "white" :background "#666666")
)
(define-attribute modeline-inactive
;(t :foreground "gray" :background "#303030")
;(t :foreground "gray" :background "#444444")
(t :foreground "gray" :background "#666666")
))
)
;; wide characters setting
#+(and win32 lem-ncurses)
(progn
;; initialize
;; (this progn part is required to enable *features* modification)
(defvar *conemu-font-is-ms-gothic* nil)
(defvar *wide-char-disp-table* nil)
(defvar *wide-char-cur-table* nil)
(eval-when (:compile-toplevel :load-toplevel :execute)
(when (find-package 'lem-base/string-width-utils)
(pushnew :new-lem-string-lib *features*))))
#+(and win32 lem-ncurses)
(progn
;; Type A : for ConEmu and cmd.exe
;; set wide characters table for display
;; (EastAsianWidth A F W + Emoji + UTF-16 surrogate pair characters (code>=#x10000)
;; are treated as wide characters)
(defun set-wide-char-disp-table-A ()
(setf *wide-char-disp-table*
(vector
'(#x000a1 #x000a1) '(#x000a4 #x000a4) '(#x000a7 #x000a8) '(#x000aa #x000aa)
'(#x000ad #x000ae) '(#x000b0 #x000b4) '(#x000b6 #x000ba) '(#x000bc #x000bf)
'(#x000c6 #x000c6) '(#x000d0 #x000d0) '(#x000d7 #x000d8) '(#x000de #x000e1)
'(#x000e6 #x000e6) '(#x000e8 #x000ea) '(#x000ec #x000ed) '(#x000f0 #x000f0)
'(#x000f2 #x000f3) '(#x000f7 #x000fa) '(#x000fc #x000fc) '(#x000fe #x000fe)
'(#x00101 #x00101) '(#x00111 #x00111) '(#x00113 #x00113) '(#x0011b #x0011b)
'(#x00126 #x00127) '(#x0012b #x0012b) '(#x00131 #x00133) '(#x00138 #x00138)
'(#x0013f #x00142) '(#x00144 #x00144) '(#x00148 #x0014b) '(#x0014d #x0014d)
'(#x00152 #x00153) '(#x00166 #x00167) '(#x0016b #x0016b) '(#x001ce #x001ce)
'(#x001d0 #x001d0) '(#x001d2 #x001d2) '(#x001d4 #x001d4) '(#x001d6 #x001d6)
'(#x001d8 #x001d8) '(#x001da #x001da) '(#x001dc #x001dc) '(#x00251 #x00251)
'(#x00261 #x00261) '(#x002c4 #x002c4) '(#x002c7 #x002c7) '(#x002c9 #x002cb)
'(#x002cd #x002cd) '(#x002d0 #x002d0) '(#x002d8 #x002db) '(#x002dd #x002dd)
'(#x002df #x002df) '(#x00300 #x0036f) '(#x00391 #x003a1) '(#x003a3 #x003a9)
'(#x003b1 #x003c1) '(#x003c3 #x003c9) '(#x00401 #x00401) '(#x00410 #x0044f)
'(#x00451 #x00451) '(#x01100 #x0115f) '(#x02010 #x02010) '(#x02013 #x02016)
'(#x02018 #x02019) '(#x0201c #x0201d) '(#x02020 #x02022) '(#x02024 #x02027)
'(#x02030 #x02030) '(#x02032 #x02033) '(#x02035 #x02035) '(#x0203b #x0203c)
'(#x0203e #x0203e) '(#x02049 #x02049) '(#x02074 #x02074) '(#x0207f #x0207f)
'(#x02081 #x02084) '(#x020ac #x020ac) '(#x02103 #x02103) '(#x02105 #x02105)
'(#x02109 #x02109) '(#x02113 #x02113) '(#x02116 #x02116) '(#x02121 #x02122)
'(#x02126 #x02126) '(#x0212b #x0212b) '(#x02139 #x02139) '(#x02153 #x02154)
'(#x0215b #x0215e) '(#x02160 #x0216b) '(#x02170 #x02179) '(#x02189 #x02189)
'(#x02190 #x02199) '(#x021a9 #x021aa) '(#x021b8 #x021b9) '(#x021d2 #x021d2)
'(#x021d4 #x021d4) '(#x021e7 #x021e7) '(#x02200 #x02200) '(#x02202 #x02203)
'(#x02207 #x02208) '(#x0220b #x0220b) '(#x0220f #x0220f) '(#x02211 #x02211)
'(#x02215 #x02215) '(#x0221a #x0221a) '(#x0221d #x02220) '(#x02223 #x02223)
'(#x02225 #x02225) '(#x02227 #x0222c) '(#x0222e #x0222e) '(#x02234 #x02237)
'(#x0223c #x0223d) '(#x02248 #x02248) '(#x0224c #x0224c) '(#x02252 #x02252)
'(#x02260 #x02261) '(#x02264 #x02267) '(#x0226a #x0226b) '(#x0226e #x0226f)
'(#x02282 #x02283) '(#x02286 #x02287) '(#x02295 #x02295) '(#x02299 #x02299)
'(#x022a5 #x022a5) '(#x022bf #x022bf) '(#x02312 #x02312) '(#x0231a #x0231b)
'(#x02328 #x0232a) '(#x023cf #x023cf) '(#x023e9 #x023f3) '(#x023f8 #x023fa)
'(#x02460 #x024e9) '(#x024eb #x0254b) '(#x02550 #x02573) '(#x02580 #x0258f)
'(#x02592 #x02595) '(#x025a0 #x025a1) '(#x025a3 #x025ab) '(#x025b2 #x025b3)
'(#x025b6 #x025b7) '(#x025bc #x025bd) '(#x025c0 #x025c1) '(#x025c6 #x025c8)
'(#x025cb #x025cb) '(#x025ce #x025d1) '(#x025e2 #x025e5) '(#x025ef #x025ef)
'(#x025fb #x025fe) '(#x02600 #x02606) '(#x02609 #x02609) '(#x0260e #x0260f)
'(#x02611 #x02611) '(#x02614 #x02615) '(#x02618 #x02618) '(#x0261c #x0261e)
'(#x02620 #x02620) '(#x02622 #x02623) '(#x02626 #x02626) '(#x0262a #x0262a)
'(#x0262e #x0262f) '(#x02638 #x0263a) '(#x02640 #x02640) '(#x02642 #x02642)
'(#x02648 #x02653) '(#x0265f #x02661) '(#x02663 #x0266a) '(#x0266c #x0266d)
'(#x0266f #x0266f) '(#x0267b #x0267b) '(#x0267e #x0267f) '(#x02692 #x02697)
'(#x02699 #x02699) '(#x0269b #x0269c) '(#x0269e #x026a1) '(#x026aa #x026ab)
'(#x026b0 #x026b1) '(#x026bd #x026bf) '(#x026c4 #x026e1) '(#x026e3 #x026e3)
'(#x026e8 #x026ff) '(#x02702 #x02702) '(#x02705 #x02705) '(#x02708 #x0270d)
'(#x0270f #x0270f) '(#x02712 #x02712) '(#x02714 #x02714) '(#x02716 #x02716)
'(#x0271d #x0271d) '(#x02721 #x02721) '(#x02728 #x02728) '(#x02733 #x02734)
'(#x0273d #x0273d) '(#x02744 #x02744) '(#x02747 #x02747) '(#x0274c #x0274c)
'(#x0274e #x0274e) '(#x02753 #x02755) '(#x02757 #x02757) '(#x02763 #x02764)
'(#x02776 #x0277f) '(#x02795 #x02797) '(#x027a1 #x027a1) '(#x027b0 #x027b0)
'(#x027bf #x027bf) '(#x02934 #x02935) '(#x02b05 #x02b07) '(#x02b1b #x02b1c)
'(#x02b50 #x02b50) '(#x02b55 #x02b59) '(#x02e80 #x02e99) '(#x02e9b #x02ef3)
'(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e) '(#x03041 #x03096)
'(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e) '(#x03190 #x031ba)
'(#x031c0 #x031e3) '(#x031f0 #x0321e) '(#x03220 #x032fe) '(#x03300 #x04dbf)
'(#x04e00 #x0a48c) '(#x0a490 #x0a4c6) '(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3)
'(#x0e000 #x0faff) '(#x0fe00 #x0fe19) '(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66)
'(#x0fe68 #x0fe6b) '(#x0ff01 #x0ff60) '(#x0ffe0 #x0ffe6) '(#x0fffd #x0fffd)
'(#x10000 #xeffff))
))
;; Type A : for ConEmu
;; set wide characters table for cursor movement
;; (EastAsianWidth A F W + Emoji are treated as wide characters)
(defun set-wide-char-cur-table-A ()
(setf *wide-char-cur-table*
(vector
'(#x000a1 #x000a1) '(#x000a4 #x000a4) '(#x000a7 #x000a8) '(#x000aa #x000aa)
'(#x000ad #x000ae) '(#x000b0 #x000b4) '(#x000b6 #x000ba) '(#x000bc #x000bf)
'(#x000c6 #x000c6) '(#x000d0 #x000d0) '(#x000d7 #x000d8) '(#x000de #x000e1)
'(#x000e6 #x000e6) '(#x000e8 #x000ea) '(#x000ec #x000ed) '(#x000f0 #x000f0)
'(#x000f2 #x000f3) '(#x000f7 #x000fa) '(#x000fc #x000fc) '(#x000fe #x000fe)
'(#x00101 #x00101) '(#x00111 #x00111) '(#x00113 #x00113) '(#x0011b #x0011b)
'(#x00126 #x00127) '(#x0012b #x0012b) '(#x00131 #x00133) '(#x00138 #x00138)
'(#x0013f #x00142) '(#x00144 #x00144) '(#x00148 #x0014b) '(#x0014d #x0014d)
'(#x00152 #x00153) '(#x00166 #x00167) '(#x0016b #x0016b) '(#x001ce #x001ce)
'(#x001d0 #x001d0) '(#x001d2 #x001d2) '(#x001d4 #x001d4) '(#x001d6 #x001d6)
'(#x001d8 #x001d8) '(#x001da #x001da) '(#x001dc #x001dc) '(#x00251 #x00251)
'(#x00261 #x00261) '(#x002c4 #x002c4) '(#x002c7 #x002c7) '(#x002c9 #x002cb)
'(#x002cd #x002cd) '(#x002d0 #x002d0) '(#x002d8 #x002db) '(#x002dd #x002dd)
'(#x002df #x002df) '(#x00300 #x0036f) '(#x00391 #x003a1) '(#x003a3 #x003a9)
'(#x003b1 #x003c1) '(#x003c3 #x003c9) '(#x00401 #x00401) '(#x00410 #x0044f)
'(#x00451 #x00451) '(#x01100 #x0115f) '(#x02010 #x02010) '(#x02013 #x02016)
'(#x02018 #x02019) '(#x0201c #x0201d) '(#x02020 #x02022) '(#x02024 #x02027)
'(#x02030 #x02030) '(#x02032 #x02033) '(#x02035 #x02035) '(#x0203b #x0203c)
'(#x0203e #x0203e) '(#x02049 #x02049) '(#x02074 #x02074) '(#x0207f #x0207f)
'(#x02081 #x02084) '(#x020ac #x020ac) '(#x02103 #x02103) '(#x02105 #x02105)
'(#x02109 #x02109) '(#x02113 #x02113) '(#x02116 #x02116) '(#x02121 #x02122)
'(#x02126 #x02126) '(#x0212b #x0212b) '(#x02139 #x02139) '(#x02153 #x02154)
'(#x0215b #x0215e) '(#x02160 #x0216b) '(#x02170 #x02179) '(#x02189 #x02189)
'(#x02190 #x02199) '(#x021a9 #x021aa) '(#x021b8 #x021b9) '(#x021d2 #x021d2)
'(#x021d4 #x021d4) '(#x021e7 #x021e7) '(#x02200 #x02200) '(#x02202 #x02203)
'(#x02207 #x02208) '(#x0220b #x0220b) '(#x0220f #x0220f) '(#x02211 #x02211)
'(#x02215 #x02215) '(#x0221a #x0221a) '(#x0221d #x02220) '(#x02223 #x02223)
'(#x02225 #x02225) '(#x02227 #x0222c) '(#x0222e #x0222e) '(#x02234 #x02237)
'(#x0223c #x0223d) '(#x02248 #x02248) '(#x0224c #x0224c) '(#x02252 #x02252)
'(#x02260 #x02261) '(#x02264 #x02267) '(#x0226a #x0226b) '(#x0226e #x0226f)
'(#x02282 #x02283) '(#x02286 #x02287) '(#x02295 #x02295) '(#x02299 #x02299)
'(#x022a5 #x022a5) '(#x022bf #x022bf) '(#x02312 #x02312) '(#x0231a #x0231b)
'(#x02328 #x0232a) '(#x023cf #x023cf) '(#x023e9 #x023f3) '(#x023f8 #x023fa)
'(#x02460 #x024e9) '(#x024eb #x0254b) '(#x02550 #x02573) '(#x02580 #x0258f)
'(#x02592 #x02595) '(#x025a0 #x025a1) '(#x025a3 #x025ab) '(#x025b2 #x025b3)
'(#x025b6 #x025b7) '(#x025bc #x025bd) '(#x025c0 #x025c1) '(#x025c6 #x025c8)
'(#x025cb #x025cb) '(#x025ce #x025d1) '(#x025e2 #x025e5) '(#x025ef #x025ef)
'(#x025fb #x025fe) '(#x02600 #x02606) '(#x02609 #x02609) '(#x0260e #x0260f)
'(#x02611 #x02611) '(#x02614 #x02615) '(#x02618 #x02618) '(#x0261c #x0261e)
'(#x02620 #x02620) '(#x02622 #x02623) '(#x02626 #x02626) '(#x0262a #x0262a)
'(#x0262e #x0262f) '(#x02638 #x0263a) '(#x02640 #x02640) '(#x02642 #x02642)
'(#x02648 #x02653) '(#x0265f #x02661) '(#x02663 #x0266a) '(#x0266c #x0266d)
'(#x0266f #x0266f) '(#x0267b #x0267b) '(#x0267e #x0267f) '(#x02692 #x02697)
'(#x02699 #x02699) '(#x0269b #x0269c) '(#x0269e #x026a1) '(#x026aa #x026ab)
'(#x026b0 #x026b1) '(#x026bd #x026bf) '(#x026c4 #x026e1) '(#x026e3 #x026e3)
'(#x026e8 #x026ff) '(#x02702 #x02702) '(#x02705 #x02705) '(#x02708 #x0270d)
'(#x0270f #x0270f) '(#x02712 #x02712) '(#x02714 #x02714) '(#x02716 #x02716)
'(#x0271d #x0271d) '(#x02721 #x02721) '(#x02728 #x02728) '(#x02733 #x02734)
'(#x0273d #x0273d) '(#x02744 #x02744) '(#x02747 #x02747) '(#x0274c #x0274c)
'(#x0274e #x0274e) '(#x02753 #x02755) '(#x02757 #x02757) '(#x02763 #x02764)
'(#x02776 #x0277f) '(#x02795 #x02797) '(#x027a1 #x027a1) '(#x027b0 #x027b0)
'(#x027bf #x027bf) '(#x02934 #x02935) '(#x02b05 #x02b07) '(#x02b1b #x02b1c)
'(#x02b50 #x02b50) '(#x02b55 #x02b59) '(#x02e80 #x02e99) '(#x02e9b #x02ef3)
'(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e) '(#x03041 #x03096)
'(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e) '(#x03190 #x031ba)
'(#x031c0 #x031e3) '(#x031f0 #x0321e) '(#x03220 #x032fe) '(#x03300 #x04dbf)
'(#x04e00 #x0a48c) '(#x0a490 #x0a4c6) '(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3)
'(#x0e000 #x0faff) '(#x0fe00 #x0fe19) '(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66)
'(#x0fe68 #x0fe6b) '(#x0ff01 #x0ff60) '(#x0ffe0 #x0ffe6) '(#x0fffd #x0fffd)
'(#x16fe0 #x16fe1) '(#x17000 #x187f1) '(#x18800 #x18af2) '(#x1b000 #x1b11e)
'(#x1b170 #x1b2fb) '(#x1f004 #x1f004) '(#x1f0cf #x1f0cf) '(#x1f100 #x1f10a)
'(#x1f110 #x1f12d) '(#x1f130 #x1f169) '(#x1f170 #x1f1ac) '(#x1f1e6 #x1f202)
'(#x1f210 #x1f23b) '(#x1f240 #x1f248) '(#x1f250 #x1f251) '(#x1f260 #x1f265)
'(#x1f300 #x1f321) '(#x1f324 #x1f393) '(#x1f396 #x1f397) '(#x1f399 #x1f39b)
'(#x1f39e #x1f3f0) '(#x1f3f3 #x1f3f5) '(#x1f3f7 #x1f4fd) '(#x1f4ff #x1f53d)
'(#x1f549 #x1f54e) '(#x1f550 #x1f567) '(#x1f56f #x1f570) '(#x1f573 #x1f57a)
'(#x1f587 #x1f587) '(#x1f58a #x1f58d) '(#x1f590 #x1f590) '(#x1f595 #x1f596)
'(#x1f5a4 #x1f5a5) '(#x1f5a8 #x1f5a8) '(#x1f5b1 #x1f5b2) '(#x1f5bc #x1f5bc)
'(#x1f5c2 #x1f5c4) '(#x1f5d1 #x1f5d3) '(#x1f5dc #x1f5de) '(#x1f5e1 #x1f5e1)
'(#x1f5e3 #x1f5e3) '(#x1f5e8 #x1f5e8) '(#x1f5ef #x1f5ef) '(#x1f5f3 #x1f5f3)
'(#x1f5fa #x1f64f) '(#x1f680 #x1f6c5) '(#x1f6cb #x1f6d2) '(#x1f6e0 #x1f6e5)
'(#x1f6e9 #x1f6e9) '(#x1f6eb #x1f6ec) '(#x1f6f0 #x1f6f0) '(#x1f6f3 #x1f6f9)
'(#x1f910 #x1f93e) '(#x1f940 #x1f970) '(#x1f973 #x1f976) '(#x1f97a #x1f97a)
'(#x1f97c #x1f9a2) '(#x1f9b0 #x1f9b9) '(#x1f9c0 #x1f9c2) '(#x1f9d0 #x1f9ff)
'(#x20000 #x2fffd) '(#x30000 #x3fffd) '(#xe0100 #xe01ef))
))
;; Type B : for mintty
;; set wide characters table for display
;; (EastAsianWidth F W + UTF-16 surrogate pair characters (code>=#x10000)
;; are treated as wide characters)
(defun set-wide-char-disp-table-B ()
(setf *wide-char-disp-table*
(vector
'(#x01100 #x0115f) '(#x0231a #x0231b) '(#x02329 #x0232a) '(#x023e9 #x023ec)
'(#x023f0 #x023f0) '(#x023f3 #x023f3) '(#x025fd #x025fe) '(#x02614 #x02615)
'(#x02648 #x02653) '(#x0267f #x0267f) '(#x02693 #x02693) '(#x026a1 #x026a1)
'(#x026aa #x026ab) '(#x026bd #x026be) '(#x026c4 #x026c5) '(#x026ce #x026ce)
'(#x026d4 #x026d4) '(#x026ea #x026ea) '(#x026f2 #x026f3) '(#x026f5 #x026f5)
'(#x026fa #x026fa) '(#x026fd #x026fd) '(#x02705 #x02705) '(#x0270a #x0270b)
'(#x02728 #x02728) '(#x0274c #x0274c) '(#x0274e #x0274e) '(#x02753 #x02755)
'(#x02757 #x02757) '(#x02795 #x02797) '(#x027b0 #x027b0) '(#x027bf #x027bf)
'(#x02b1b #x02b1c) '(#x02b50 #x02b50) '(#x02b55 #x02b55) '(#x02e80 #x02e99)
'(#x02e9b #x02ef3) '(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e)
'(#x03041 #x03096) '(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e)
'(#x03190 #x031ba) '(#x031c0 #x031e3) '(#x031f0 #x0321e) '(#x03220 #x03247)
'(#x03250 #x032fe) '(#x03300 #x04dbf) '(#x04e00 #x0a48c) '(#x0a490 #x0a4c6)
'(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3) '(#x0f900 #x0faff) '(#x0fe10 #x0fe19)
'(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66) '(#x0fe68 #x0fe6b) '(#x0ff01 #x0ff60)
'(#x0ffe0 #x0ffe6) '(#x10000 #xeffff))
))
;; Type B : for mintty
;; set wide characters table for cursor movement
;; (EastAsianWidth F W are treated as wide characters)
(defun set-wide-char-cur-table-B ()
(setf *wide-char-cur-table*
(vector
'(#x01100 #x0115f) '(#x0231a #x0231b) '(#x02329 #x0232a) '(#x023e9 #x023ec)
'(#x023f0 #x023f0) '(#x023f3 #x023f3) '(#x025fd #x025fe) '(#x02614 #x02615)
'(#x02648 #x02653) '(#x0267f #x0267f) '(#x02693 #x02693) '(#x026a1 #x026a1)
'(#x026aa #x026ab) '(#x026bd #x026be) '(#x026c4 #x026c5) '(#x026ce #x026ce)
'(#x026d4 #x026d4) '(#x026ea #x026ea) '(#x026f2 #x026f3) '(#x026f5 #x026f5)
'(#x026fa #x026fa) '(#x026fd #x026fd) '(#x02705 #x02705) '(#x0270a #x0270b)
'(#x02728 #x02728) '(#x0274c #x0274c) '(#x0274e #x0274e) '(#x02753 #x02755)
'(#x02757 #x02757) '(#x02795 #x02797) '(#x027b0 #x027b0) '(#x027bf #x027bf)
'(#x02b1b #x02b1c) '(#x02b50 #x02b50) '(#x02b55 #x02b55) '(#x02e80 #x02e99)
'(#x02e9b #x02ef3) '(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e)
'(#x03041 #x03096) '(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e)
'(#x03190 #x031ba) '(#x031c0 #x031e3) '(#x031f0 #x0321e) '(#x03220 #x03247)
'(#x03250 #x032fe) '(#x03300 #x04dbf) '(#x04e00 #x0a48c) '(#x0a490 #x0a4c6)
'(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3) '(#x0f900 #x0faff) '(#x0fe10 #x0fe19)
'(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66) '(#x0fe68 #x0fe6b) '(#x0ff01 #x0ff60)
'(#x0ffe0 #x0ffe6) '(#x16fe0 #x16fe1) '(#x17000 #x187f1) '(#x18800 #x18af2)
'(#x1b000 #x1b11e) '(#x1b170 #x1b2fb) '(#x1f004 #x1f004) '(#x1f0cf #x1f0cf)
'(#x1f18e #x1f18e) '(#x1f191 #x1f19a) '(#x1f200 #x1f202) '(#x1f210 #x1f23b)
'(#x1f240 #x1f248) '(#x1f250 #x1f251) '(#x1f260 #x1f265) '(#x1f300 #x1f320)
'(#x1f32d #x1f335) '(#x1f337 #x1f37c) '(#x1f37e #x1f393) '(#x1f3a0 #x1f3ca)
'(#x1f3cf #x1f3d3) '(#x1f3e0 #x1f3f0) '(#x1f3f4 #x1f3f4) '(#x1f3f8 #x1f43e)
'(#x1f440 #x1f440) '(#x1f442 #x1f4fc) '(#x1f4ff #x1f53d) '(#x1f54b #x1f54e)
'(#x1f550 #x1f567) '(#x1f57a #x1f57a) '(#x1f595 #x1f596) '(#x1f5a4 #x1f5a4)
'(#x1f5fb #x1f64f) '(#x1f680 #x1f6c5) '(#x1f6cc #x1f6cc) '(#x1f6d0 #x1f6d2)
'(#x1f6eb #x1f6ec) '(#x1f6f4 #x1f6f9) '(#x1f910 #x1f93e) '(#x1f940 #x1f970)
'(#x1f973 #x1f976) '(#x1f97a #x1f97a) '(#x1f97c #x1f9a2) '(#x1f9b0 #x1f9b9)
'(#x1f9c0 #x1f9c2) '(#x1f9d0 #x1f9ff) '(#x20000 #x2fffd) '(#x30000 #x3fffd))
))
;; Type C : for Windows Terminal (windows 10)
;; set wide characters table for display
;; (EastAsianWidth F W + Emoji + UTF-16 surrogate pair characters (code>=#x10000)
;; are treated as wide characters)
(defun set-wide-char-disp-table-C ()
(setf *wide-char-disp-table*
(vector
'(#x01100 #x0115f) '(#x0203c #x0203c) '(#x02049 #x02049) '(#x02122 #x02122)
'(#x02139 #x02139) '(#x02194 #x02199) '(#x021a9 #x021aa) '(#x0231a #x0231b)
'(#x02328 #x0232a) '(#x023cf #x023cf) '(#x023e9 #x023f3) '(#x023f8 #x023fa)
'(#x024c2 #x024c2) '(#x025aa #x025ab) '(#x025b6 #x025b6) '(#x025c0 #x025c0)
'(#x025fb #x025fe) '(#x02600 #x02604) '(#x0260e #x0260e) '(#x02611 #x02611)
'(#x02614 #x02615) '(#x02618 #x02618) '(#x0261d #x0261d) '(#x02620 #x02620)
'(#x02622 #x02623) '(#x02626 #x02626) '(#x0262a #x0262a) '(#x0262e #x0262f)
'(#x02638 #x0263a) '(#x02640 #x02640) '(#x02642 #x02642) '(#x02648 #x02653)
'(#x0265f #x02660) '(#x02663 #x02663) '(#x02665 #x02666) '(#x02668 #x02668)
'(#x0267b #x0267b) '(#x0267e #x0267f) '(#x02692 #x02697) '(#x02699 #x02699)
'(#x0269b #x0269c) '(#x026a0 #x026a1) '(#x026a7 #x026a7) '(#x026aa #x026ab)
'(#x026b0 #x026b1) '(#x026bd #x026be) '(#x026c4 #x026c5) '(#x026c8 #x026c8)
'(#x026ce #x026cf) '(#x026d1 #x026d1) '(#x026d3 #x026d4) '(#x026e9 #x026ea)
'(#x026f0 #x026f5) '(#x026f7 #x026fa) '(#x026fd #x026fd) '(#x02702 #x02702)
'(#x02705 #x02705) '(#x02708 #x0270d) '(#x0270f #x0270f) '(#x02712 #x02712)
'(#x02714 #x02714) '(#x02716 #x02716) '(#x0271d #x0271d) '(#x02721 #x02721)
'(#x02728 #x02728) '(#x02733 #x02734) '(#x02744 #x02744) '(#x02747 #x02747)
'(#x0274c #x0274c) '(#x0274e #x0274e) '(#x02753 #x02755) '(#x02757 #x02757)
'(#x02763 #x02764) '(#x02795 #x02797) '(#x027a1 #x027a1) '(#x027b0 #x027b0)
'(#x027bf #x027bf) '(#x02934 #x02935) '(#x02b05 #x02b07) '(#x02b1b #x02b1c)
'(#x02b50 #x02b50) '(#x02b55 #x02b55) '(#x02e80 #x02e99) '(#x02e9b #x02ef3)
'(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e) '(#x03041 #x03096)
'(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e) '(#x03190 #x031e3)
'(#x031f0 #x0321e) '(#x03220 #x03247) '(#x03250 #x04dbf) '(#x04e00 #x0a48c)
'(#x0a490 #x0a4c6) '(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3) '(#x0f900 #x0faff)
'(#x0fe10 #x0fe19) '(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66) '(#x0fe68 #x0fe6b)
'(#x0ff01 #x0ff60) '(#x0ffe0 #x0ffe6) '(#x10000 #xeffff))
))
;; Type C : for Windows Terminal (windows 10)
;; set wide characters table for cursor movement
;; (EastAsianWidth F W + Emoji are treated as wide characters)
(defun set-wide-char-cur-table-C ()
(setf *wide-char-cur-table*
(vector
'(#x01100 #x0115f) '(#x0203c #x0203c) '(#x02049 #x02049) '(#x02122 #x02122)
'(#x02139 #x02139) '(#x02194 #x02199) '(#x021a9 #x021aa) '(#x0231a #x0231b)
'(#x02328 #x0232a) '(#x023cf #x023cf) '(#x023e9 #x023f3) '(#x023f8 #x023fa)
'(#x024c2 #x024c2) '(#x025aa #x025ab) '(#x025b6 #x025b6) '(#x025c0 #x025c0)
'(#x025fb #x025fe) '(#x02600 #x02604) '(#x0260e #x0260e) '(#x02611 #x02611)
'(#x02614 #x02615) '(#x02618 #x02618) '(#x0261d #x0261d) '(#x02620 #x02620)
'(#x02622 #x02623) '(#x02626 #x02626) '(#x0262a #x0262a) '(#x0262e #x0262f)
'(#x02638 #x0263a) '(#x02640 #x02640) '(#x02642 #x02642) '(#x02648 #x02653)
'(#x0265f #x02660) '(#x02663 #x02663) '(#x02665 #x02666) '(#x02668 #x02668)
'(#x0267b #x0267b) '(#x0267e #x0267f) '(#x02692 #x02697) '(#x02699 #x02699)
'(#x0269b #x0269c) '(#x026a0 #x026a1) '(#x026a7 #x026a7) '(#x026aa #x026ab)
'(#x026b0 #x026b1) '(#x026bd #x026be) '(#x026c4 #x026c5) '(#x026c8 #x026c8)
'(#x026ce #x026cf) '(#x026d1 #x026d1) '(#x026d3 #x026d4) '(#x026e9 #x026ea)
'(#x026f0 #x026f5) '(#x026f7 #x026fa) '(#x026fd #x026fd) '(#x02702 #x02702)
'(#x02705 #x02705) '(#x02708 #x0270d) '(#x0270f #x0270f) '(#x02712 #x02712)
'(#x02714 #x02714) '(#x02716 #x02716) '(#x0271d #x0271d) '(#x02721 #x02721)
'(#x02728 #x02728) '(#x02733 #x02734) '(#x02744 #x02744) '(#x02747 #x02747)
'(#x0274c #x0274c) '(#x0274e #x0274e) '(#x02753 #x02755) '(#x02757 #x02757)
'(#x02763 #x02764) '(#x02795 #x02797) '(#x027a1 #x027a1) '(#x027b0 #x027b0)
'(#x027bf #x027bf) '(#x02934 #x02935) '(#x02b05 #x02b07) '(#x02b1b #x02b1c)
'(#x02b50 #x02b50) '(#x02b55 #x02b55) '(#x02e80 #x02e99) '(#x02e9b #x02ef3)
'(#x02f00 #x02fd5) '(#x02ff0 #x02ffb) '(#x03000 #x0303e) '(#x03041 #x03096)
'(#x03099 #x030ff) '(#x03105 #x0312f) '(#x03131 #x0318e) '(#x03190 #x031e3)
'(#x031f0 #x0321e) '(#x03220 #x03247) '(#x03250 #x04dbf) '(#x04e00 #x0a48c)
'(#x0a490 #x0a4c6) '(#x0a960 #x0a97c) '(#x0ac00 #x0d7a3) '(#x0f900 #x0faff)
'(#x0fe10 #x0fe19) '(#x0fe30 #x0fe52) '(#x0fe54 #x0fe66) '(#x0fe68 #x0fe6b)
'(#x0ff01 #x0ff60) '(#x0ffe0 #x0ffe6) '(#x16fe0 #x16fe4) '(#x16ff0 #x16ff1)
'(#x17000 #x187f7) '(#x18800 #x18cd5) '(#x18d00 #x18d08) '(#x1b000 #x1b11e)
'(#x1b150 #x1b152) '(#x1b164 #x1b167) '(#x1b170 #x1b2fb) '(#x1f004 #x1f004)
'(#x1f0cf #x1f0cf) '(#x1f170 #x1f171) '(#x1f17e #x1f17f) '(#x1f18e #x1f18e)
'(#x1f191 #x1f19a) '(#x1f1e6 #x1f202) '(#x1f210 #x1f23b) '(#x1f240 #x1f248)
'(#x1f250 #x1f251) '(#x1f260 #x1f265) '(#x1f300 #x1f321) '(#x1f324 #x1f393)
'(#x1f396 #x1f397) '(#x1f399 #x1f39b) '(#x1f39e #x1f3f0) '(#x1f3f3 #x1f3f5)
'(#x1f3f7 #x1f4fd) '(#x1f4ff #x1f53d) '(#x1f549 #x1f54e) '(#x1f550 #x1f567)
'(#x1f56f #x1f570) '(#x1f573 #x1f57a) '(#x1f587 #x1f587) '(#x1f58a #x1f58d)
'(#x1f590 #x1f590) '(#x1f595 #x1f596) '(#x1f5a4 #x1f5a5) '(#x1f5a8 #x1f5a8)
'(#x1f5b1 #x1f5b2) '(#x1f5bc #x1f5bc) '(#x1f5c2 #x1f5c4) '(#x1f5d1 #x1f5d3)
'(#x1f5dc #x1f5de) '(#x1f5e1 #x1f5e1) '(#x1f5e3 #x1f5e3) '(#x1f5e8 #x1f5e8)
'(#x1f5ef #x1f5ef) '(#x1f5f3 #x1f5f3) '(#x1f5fa #x1f64f) '(#x1f680 #x1f6c5)
'(#x1f6cb #x1f6d2) '(#x1f6d5 #x1f6d7) '(#x1f6e0 #x1f6e5) '(#x1f6e9 #x1f6e9)
'(#x1f6eb #x1f6ec) '(#x1f6f0 #x1f6f0) '(#x1f6f3 #x1f6fc) '(#x1f7e0 #x1f7eb)
'(#x1f90c #x1f93a) '(#x1f93c #x1f945) '(#x1f947 #x1f978) '(#x1f97a #x1f9cb)
'(#x1f9cd #x1f9ff) '(#x1fa70 #x1fa74) '(#x1fa78 #x1fa7a) '(#x1fa80 #x1fa86)
'(#x1fa90 #x1faa8) '(#x1fab0 #x1fab6) '(#x1fac0 #x1fac2) '(#x1fad0 #x1fad6)
'(#x20000 #x2fffd) '(#x30000 #x3fffd))
))
;; set wide characters table
(cond
;; for windows 10 (pdcurses-win10-jp is required)
((and (boundp 'lem-ncurses::*pdcurses-win10-jp*)
lem-ncurses::*pdcurses-win10-jp*)
(case (lem-ncurses::windows-term-type)
(:mintty
(set-wide-char-disp-table-A)
(set-wide-char-cur-table-A))
(:conemu
(set-wide-char-disp-table-A)
;(set-wide-char-cur-table-A)
)
(:winterm
(set-wide-char-disp-table-C)
(set-wide-char-cur-table-C))
(t
(set-wide-char-disp-table-A)
(set-wide-char-cur-table-A))))
;; for windows 8.1 or earlier
(t
(case (lem-ncurses::windows-term-type)
(:mintty
(set-wide-char-disp-table-B)
(set-wide-char-cur-table-B))
(:conemu
(cond
(*conemu-font-is-ms-gothic*
(set-wide-char-disp-table-A)
(set-wide-char-cur-table-A))
(t
(set-wide-char-disp-table-B)
(set-wide-char-cur-table-B))))
(t
(set-wide-char-disp-table-A)
;(set-wide-char-cur-table-A)
))))
;; set wide characters function
(progn
;; set wide characters function for display
(when *wide-char-disp-table*
;; remake binary search function
(#+sbcl sb-ext:without-package-locks #-sbcl progn
(handler-bind (#+sbcl(sb-kernel:redefinition-warning #'muffle-warning))
#-new-lem-string-lib
(lem-base::gen-binary-search-function 'lem-base::%binary-search
*wide-char-disp-table*)
#+new-lem-string-lib
(lem-base/string-width-utils::gen-binary-search-function
'lem-base/string-width-utils::%binary-search
*wide-char-disp-table*)
)))
;; set wide characters function for cursor movement
(when *wide-char-cur-table*
;; make binary search function
(progn
#-new-lem-string-lib
(lem-base::gen-binary-search-function 'wide-char-cursor-p
*wide-char-cur-table*)
#+new-lem-string-lib
(lem-base/string-width-utils::gen-binary-search-function
'wide-char-cursor-p
*wide-char-cur-table*)
)
;; set custom function to lem
(setf (lem-ncurses::windows-term-setting-cur-char-width
lem-ncurses::*windows-term-setting*)
(lambda (code)
;; check zero-width-space character (#\u200b)
(if (= code #x200b)
0
(if (wide-char-cursor-p code) 2 1))))))
)
;; -*- coding: utf-8 -*-
;;
;; lem_eaw_conv.scm
;; 2020-12-10 v1.08
;;
;; <内容>
;; Gauche を使用して、Lem エディタ用の文字幅データを生成するためのツールです。
;; EastAsianWidth.txt と emoji-data.txt が、本ファイルと同一フォルダに
;; 存在することを想定しています。
;; EastAsianWidth.txt と emoji-data.txt は、以下にあります。
;; https://unicode.org/Public/UNIDATA/EastAsianWidth.txt
;; https://unicode.org/Public/UNIDATA/emoji/emoji-data.txt
;;
;; <使い方>
;; gosh lem_eaw_conv.scm mode
;; mode 動作モード
;; =0:テスト用の文字幅データ(wide-test.txt)を生成する
;; =1:ConEmuの表示用の文字幅データ(wide-conemu.txt)を生成する
;; =2:ConEmuのカーソル用の文字幅データ(wide-conemu-cursor.txt)を生成する
;; =3:minttyの表示用の文字幅データ(wide-mintty.txt)を生成する
;; =4:minttyのカーソル用の文字幅データ(wide-mintty-cursor.txt)を生成する
;; =5:Windows Terminalの表示用の文字幅データ(wide-winterm.txt)を生成する
;; =6:Windows Terminalのカーソル用の文字幅データ(wide-winterm-cursor.txt)を生成する
;;
(use util.match)
;; EastAsianWidth ファイル (#f なら読み込まない)
(define east-asian-width-file "EastAsianWidth.txt")
;; emoji-data ファイル (#f なら読み込まない)
(define emoji-data-file "emoji-data.txt")
;; 結果データ ファイル (#f なら書き出さない)
(define result-data-file "wide-data.txt")
;; ワイド文字セレクタ設定 (EastAsianWidth の A F H N Na W から選択)
(define wide-type-selector '(F W))
;; ワイド文字範囲リストの追加設定 (#f なら追加しない)
;; (UTF-16 でサロゲートペアになる文字は、すべてワイド文字と判定しないと、
;; Windows コンソールの1行に収まらない (1文字で2セル使用するため))
(define wide-range-list-plus '((#x10000 . #xeffff)))
;; 結果データのインデント設定
(define result-data-indent 6)
;; 範囲の構造体 (実体はコンスセル)
;; start 範囲の開始点(整数)
;; end 範囲の終了点(整数)
(define (make-range start end) (cons start end))
(define range-start (getter-with-setter (lambda (r) (car r))
(lambda (r v) (set-car! r v))))
(define range-end (getter-with-setter (lambda (r) (cdr r))
(lambda (r v) (set-cdr! r v))))
;; 範囲のリストのソート
;; ・例. ((3 . 4) (1 . 2)) → ((1 . 2) (3 . 4))
;; ・開始点でソートする
(define (sort-range-list range-list)
(sort range-list < range-start))
;; 範囲のリストの圧縮
;; ・例. ((100 . 110) (111 . 120)) → ((100 . 120))
;; ・範囲のリストは、開始点でソート済みであること
(define (compress-range-list range-list)
(define result-range-list '())
(define r-last #f)
(for-each
(lambda (r-now)
;; 条件を満たせば、最後の範囲にマージする
(set! r-last (list-ref result-range-list 0 #f))
(if (and r-last
(<= (range-start r-now) (+ (range-end r-last) 1))
(<= (range-start r-last) (+ (range-end r-now) 1)))
(set-car! result-range-list
(make-range (min (range-start r-now) (range-start r-last))
(max (range-end r-now) (range-end r-last))))
(push! result-range-list r-now)))
range-list)
(reverse result-range-list))
;; 範囲のリストのマージ
;; ・例. ((100 . 110) (120 . 130) (140 . 150)) + ((130 . 140))
;; → ((100 . 110) (120 . 150))
;; ・範囲のリスト1と2は、開始点でソート済みであること
(define (merge-range-list range-list-1 range-list-2)
(define result-range-list '())
(define r-now #f)
(define r-last #f)
(cond
((null? range-list-1) range-list-2)
((null? range-list-2) range-list-1)
(else
(let loop ((r1 (car range-list-1))
(r2 (car range-list-2))
(rest1 range-list-1)
(rest2 range-list-2))
;; r1 と r2 のうち開始点の小さい方を選択
(cond
((and r1
(or (not r2)
(<= (range-start r1) (range-start r2))))
(set! r-now r1)
(set! rest1 (cdr rest1)))
(else
(set! r-now r2)
(set! rest2 (cdr rest2))))
;; 条件を満たせば、最後の範囲にマージする
(set! r-last (list-ref result-range-list 0 #f))
(if (and r-last
(<= (range-start r-now) (+ (range-end r-last) 1))
(<= (range-start r-last) (+ (range-end r-now) 1)))
(set-car! result-range-list
(make-range (min (range-start r-now) (range-start r-last))
(max (range-end r-now) (range-end r-last))))
(push! result-range-list r-now))
;; リストの残りをチェック
(if (and (null? rest1) (null? rest2))
(reverse result-range-list)
(loop (if (null? rest1) #f (car rest1))
(if (null? rest2) #f (car rest2))
rest1
rest2))))))
;; EastAsianWidth の読み込み
;; ・wide-type-selector で選択したものだけを読み込む
;; ・一部範囲を限定して読み込んでいるので注意
(define (read-east-asian-width)
(define result-range-list '())
(define (range-list-push! start end type)
(let ((start (string->number start 16))
(end (string->number end 16))
(type (string->symbol type)))
(when (and (memq type wide-type-selector)
(< start #xf0000)) ; 一部範囲を限定
(push! result-range-list (make-range start end)))))
(for-each
(lambda (line)
(rxmatch-case line
(#/^(\w+)\.\.(\w+)\s*;\s*(\w+)/ (#f start end type)
(range-list-push! start end type))
(#/^(\w+)\s*;\s*(\w+)/ (#f start type)
(range-list-push! start start type))))
(generator->lseq read-line))
(reverse result-range-list))
;; emoji-data の読み込み
;; ・プロパティが Emoji のものだけを読み込む
;; ・一部範囲を限定して読み込んでいるので注意
(define (read-emoji-data)
(define result-range-list '())
(define (range-list-push! start end type)
(let ((start (string->number start 16))
(end (string->number end 16))
(type (string->symbol type)))
(when (and (eq? type 'Emoji)
(>= start #x1000)) ; 一部範囲を限定
(push! result-range-list (make-range start end)))))
(for-each
(lambda (line)
(rxmatch-case line
(#/^(\w+)\.\.(\w+)\s*;\s*(\w+)/ (#f start end type)
(range-list-push! start end type))
(#/^(\w+)\s*;\s*(\w+)/ (#f start type)
(range-list-push! start start type))))
(generator->lseq read-line))
(reverse result-range-list))
;; 結果データの書き出し
(define (write-result-data range-list)
(define indent (make-string result-data-indent #\space))
(define range-count 0)
(format #t "~a(vector~%" indent)
(for-each
(lambda (r)
(cond ((= range-count 0)
(format #t "~a" indent))
((= (modulo range-count 4) 0)
(format #t "~%~a" indent)))
(format #t " '(#x~5,'0x #x~5,'0x)" (range-start r) (range-end r))
(inc! range-count))
range-list)
(format #t ")~%"))
;; ファイル変換
(define (convert-file)
(define result-range-list '())
;; EastAsianWidth の読み込み
(when east-asian-width-file
(let ((range-list '()))
(with-input-from-file east-asian-width-file
(lambda ()
(set! range-list (compress-range-list
(sort-range-list (read-east-asian-width))))))
(set! result-range-list (merge-range-list result-range-list range-list))))
;; emoji-data の読み込み
(when emoji-data-file
(let ((range-list '()))
(with-input-from-file emoji-data-file
(lambda ()
(set! range-list (compress-range-list
(sort-range-list (read-emoji-data))))))
(set! result-range-list (merge-range-list result-range-list range-list))))
;; ワイド文字範囲リストの追加設定をマージする
(when wide-range-list-plus
(set! result-range-list (merge-range-list result-range-list wide-range-list-plus)))
;; 結果データの書き出し
(when result-data-file
(with-output-to-file result-data-file
(lambda ()
(write-result-data result-range-list)))))
;; 使い方の表示
(define (usage out code)
(format out "Usage: gosh lem_eaw_conv.scm mode(=0-6)~%")
(exit code))
;; メイン処理
(define (main args)
(match args
((_ "0") ; テスト用
(set! east-asian-width-file "EastAsianWidth.txt")
(set! emoji-data-file "emoji-data.txt")
(set! result-data-file "wide-test.txt")
(set! wide-type-selector '(F W))
(set! wide-range-list-plus '((#x10000 . #xeffff)))
(set! result-data-indent 6)
(convert-file))
((_ "1") ; ConEmuの表示用
(set! result-data-file "wide-conemu.txt")
(set! wide-type-selector '(A F W))
(convert-file))
((_ "2") ; ConEmuのカーソル用
(set! result-data-file "wide-conemu-cursor.txt")
(set! wide-type-selector '(A F W))
(set! wide-range-list-plus #f)
(convert-file))
((_ "3") ; minttyの表示用
(set! emoji-data-file #f)
(set! result-data-file "wide-mintty.txt")
(set! wide-type-selector '(F W))
(convert-file))
((_ "4") ; minttyのカーソル用
(set! emoji-data-file #f)
(set! result-data-file "wide-mintty-cursor.txt")
(set! wide-type-selector '(F W))
(set! wide-range-list-plus #f)
(convert-file))
((_ "5") ; Windows Terminalの表示用
(set! result-data-file "wide-winterm.txt")
(set! wide-type-selector '(F W))
(convert-file))
((_ "6") ; Windows Terminalのカーソル用
(set! result-data-file "wide-winterm-cursor.txt")
(set! wide-type-selector '(F W))
(set! wide-range-list-plus #f)
(convert-file))
(_ (usage (current-error-port) 1)))
0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment