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)))