On Github ncaq / symbolword-mode-presentation
まず言っておくことがあります
これはゲームじゃないです,
ゲームは完成しませんでした.
ごめんなさい
と言うと,
Emacs用の,いわゆる拡張機能です.
テキストエディタの1種です.
私はEmacsを便利に常用していたのですが,少し気に入らないことがありました. それは,「単語」の句切りです.
+=の手前にカーソルがあることに注目してください,
ここでM-dに割り当てられた,「単語削除」コマンドを押すと,
このように,+=だけを消したくても,
;のところまで削られてしまいます.
英文の,「単語」の区切りはそれで良いのかもしれませんが,
プログラムを書いている時に,
こんな単語の区切りで嬉しいことなど何もありません.
そこで,改善をすることにしました.
プログラマの3大美徳は,'(怠惰 短気 傲慢)
Emacsには大きな特徴があります.
それは,Emacs自身が,Emacsで動くEmacs Lispで実装されているという事です.
最低限の所をC言語で実装し,他を動的実行言語で実装することで,大きな柔軟性を手に入れています.
さらに,全てのキーバインドには関数を割り当てられます.
つまり,単語関連の機能を自作してしまえば,自分の思い通りの単語移動が出来るという事です.
さて,この機能を実現するのには,一体何が必要なのか. まずこれを考えてみる.
単語の区切りを判別する 区切りまで{移動,削除}する.判別する関数がこれです.
(defun div-symbolword-forward (currstr nextstr) "単語を分けるか?" (let ((currtype (unicode-block-type currstr)) (nexttype (unicode-block-type nextstr))) (cond ((eq nexttype 'space) nil);次が空白の時は単語を分けない ((not (equal-syntax currstr nextstr)) t);違う意味の文字なら分ける ((and (not (or (cl-find currtype *latin*) (cl-find nexttype *latin*)));ラテン文字以外で, (not (eq currtype nexttype))) t);Unicode的に違う文字であるなら分ける ((and;自分が小文字で,次が大文字である時分ける (eq currtype 'downcase) (eq nexttype 'upcase)) t))))lispの高い表現力が, 極めて短いコードで定義を示すことに役だっています. ここで紹介しておくと,lispにはcond式というものがあり,
(cond ((exp1) t) ((exp2) nil) ((exp3) t))
(or (exp1) (and (not (exp2)) (exp3)))上と下の式は等価なものとなっています.
(defun div-symbolword-forward-and (currstr nextstr) "単語を分けるか?" (let ((currtype (unicode-block-type currstr)) (nexttype (unicode-block-type nextstr))) (and (not (eq nexttype 'space));次が空白の時は単語を分けない (or (not (equal-syntax currstr nextstr));違う意味の文字なら分ける (and (not (or (cl-find currtype *latin*) (cl-find nexttype *latin*)));ラテン文字以外で, (not (eq currtype nexttype)));Unicode的に違う文字であるなら分ける (and;自分が小文字で,次が大文字である時分ける (eq currtype 'downcase) (eq nexttype 'upcase))))))cond式を使ったものに比べると, だいぶ分かり辛くなっていますね… (lisperによってはこっちのほうが良いと言うかもしれません,実際,私はこっちを使っています.) condは,式が上から評価されてるのを分かり易くする働きがあります.
(defun kill-symbolword () (interactive) (c-hungry-delete-forward) (kill-forward-chars (kill-symbolword-size (get-str-from-buffer) 1))) (defun kill-symbolword-size (curr num) (let ((next (get-str-from-buffer-dif num))) (if (not (div-symbolword-forward curr next)) (kill-symbolword-size next (incf num)) num)))