ndtp 経過

関数の定義は symbol-function で取り出せました。

以下の例では、関数 b の中で関数 a を退避し、関数 a を書き換えた上で実行しています。その後、関数 a の定義を退避させたものに戻してあります。*1

(defun a () 'a)
(defun b ()
  (let ((old-definition (symbol-function #'a)))
    (unwind-protect
        (progn
          (defun a () 'b)
          (a))
      (fset 'a old-definition))))
(b) ;; => b
(a) ;; => a

しかし ndtp.el からこれを用いても、検索語を含む辞書の一覧までは出るものの、辞書を選択する段で "Lookup BUG!! Report to the mailing list" と表示されて結果を得られませんでした。

試みに relay.el に記載されている ad-return-value を書き換える方法にしてみましたが、結果変わらず(流れは違うものの、ほぼ同じ事をしているので変わる筈もないのですが……)。

よくよくサーバ側のログを読むと、同時接続許可数を越えているため接続できない事がわかりました。*2

実際、同時接続許可数を増やしたところ、語の意味まで表示できるようになりました。
ただ、一度の検索で 10 も 15 も process を作ってしまうのが気掛りですが……。また、その分動作も非常に緩慢です。

以下が現在のコードです。

;; based on
;; http://deisui.bug.org/%7Eueno/memo/emacs-ssh.html
;; http://triaez.kaisei.org/%7Ekaoru/ssh/emacs-ssh.html
;; http://www.meadowy.org/~gotoh/lisp/relay.el

(defun open-ssh-stream-internal (&rest plist)
  (let ((name (or (plist-get plist :name) name))
	(buffer (or (plist-get plist :buffer) buffer))
	(host (or (plist-get plist :host) host))
	(service (or (plist-get plist :service) service))
	(process-connection-type nil))
    (start-process-shell-command
     name buffer
     (or (plist-get plist :ssh) "ssh")
     (or (plist-get plist :sshflags) "-Caxq")
     (plist-get plist :relay)
     (or (plist-get plist :command) "nc -w 60")
     host (format "%s" service))))

(defun open-ssh-stream (name buffer host service)
  (open-ssh-stream-internal :relay "nobody.example.net"
			    :name name
			    :buffer buffer
			    :host host
			    :service service))

(defadvice open-network-stream (around relay (name buffer host service)
				       activate)
  "Open network stream with relaying."
  (let
      ((hosts (list "localhost" "hostname.localdomain" "nobody.example.net"))
       (services (list 25 143 2010 6667)))

    (if (and (member host hosts)
	     (member service services))
	(setq ad-return-value
	      (open-ssh-stream name buffer host service))
      ad-do-it)))

これで対象のホストネームかつ対象のポートの場合のみ、ssh + netcat 経由で遣り取りするようになります。*3

なお ndtp 以外は十分な速度が出ています。

後は ndtp でも port forward 時と同じくらいの速度が出せるようにするだけです……が、先は長そうな気がしています。まずは ndtp.el および lookup-el の流れを正しく読み解いていくことでしょうか。

*1:この方法とサンプルコードは id:Topia 師が教示くださったものを基にしています。いつもいつもありがとうございます。

*2:ssh で port forward させている時には問題なかったので、想定していませんでした。

*3:今は smtp, imap4, ndtp, irc ですね ;-)