2017年3月26日日曜日

[Emacs][Elisp]Hook

hook で定義されたアクションが実行される時に紐付けされた hook funcsion が実行される。例えば suspend-hook は Emacs が suspend される直前に実行される hook となる。
add-hook
add-hook 関数を使うことで定義済み hook 変数に関数を追加できる
(add-hook 'text-mode-hook 'turn-on-auto-fill)
text-mode の場合は disable truncate にする
(add-hook 'text-mode-hook
 (lambda() (setq truncate-lines nil)))

[Emacs][Elisp]HTTP 通信

scratch バッファで Elisp による HTTP 通信をしてみた
各命令の最後で Ctrl + j により実行
; TCP コネクション (localhost:80) をはる
; open-network-stream は返値に process 名を返してくるので、それを proc に格納する
(setq proc (open-network-stream "http-proc" "*test-http-buffer*" "localhost" 80))
#
; proc の状態を確認
(process-status proc)
open
; proc に対して送る coding を指定する
(set-process-coding-system proc 'binary 'binary)
nil
; proc に文字列を送る
(process-send-string
proc
(format(concat
"GET / HTTP/1.0\r\n"
"\r\n")))
nil
指定した *test-http-buffer* に結果が表示される
Process http-proc connection broken by remote peer
HTTP/1.1 200 OK
Date: Thu, 06 Aug 2009 13:59:44 GMT
Server: Apache/2.2.9 (Win32) DAV/2 mod_ssl/2.2.9 OpenSSL/0.9.8i mod_autoindex_color mod_python/3.3.1 Python/2.5.2 PHP/5.2.6
Last-Modified: Fri, 06 Mar 2009 23:42:57 GMT
ETag: "6000000000669-1bc-4647bd829e8db"
Accept-Ranges: bytes
Content-Length: 444
Connection: close
Content-Type: text/html
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8">
<title>Test page</title>
</head>
<body>
Hello, world
</body>
</html>
Process http-proc connection broken by remote peer

open-network-stream
open-network-stream NAME BUFFER-OR-NAME HOST SERVICE
TCP 接続を確立する
Table: open-network-stream の引数
引数内容
NAMEprocess 名を指定する
BUFFER-OR-NAMEこの TCP コネクションに割り付けられるバッファ名
HOST接続先ホスト
SERVICEネットワークサービス名 または ポート番号
process-status
process-status PROCESS-NAME
PROCESS-NAME で指定したプロセスの状態を返す
Table: process-status の引数
引数内容
PROCESS-NAMEプロセス名
Table: process-status の返値
返値意味
runプロセスは running 状態
stopプロセスは停止している、再開可能
exitプロセスは終了している
signalプロセスは fatal signal を受けた
openネットワークコネクションが open している
closedネットワークコネクションは close した
connectnon-blocking コネクション、完了待ち
failednon-blocking コネクション、失敗
listenネットワークサーバが listen 中
nil指定したプロセス名のプロセスは存在しない
set-process-coding-system
set-process-coding-system PROCESS &optional DECODING-SYSTEM ENCODING-SYSTEM
PROCESS で指定したプロセスとの output/input 用コーディングを指定する
Table: set-process-coding-system の引数
引数 内容
PROCESSプロセス名
DECODING-SYSTEMプロセスからの output コーディング
ENCODING-SYSTEMプロセスへの input コーディング
process-send-string
process-send-string PROCESS STRING
プロセスに対して文字列を送る
Table: process-send-string の引数
引数 内容
PROCESSプロセス名
STRING文字列

[Emacs][Elisp]プロセス

プロセス実行
start-process

プロセスの状態を監視
フォーマット
set-process-sentinel process sentinel
process が Finished, exited abnormally など特定のイベント状態になった場合に sentinel で渡した命令を実行する
(defun ls-test ()
  (interactive)
  (defun msg-me (process event)
  (princ
    (format "Process: %s had the event [%s]" process event)))
    (set-process-sentinel
    (start-process "ls" "*ls*" "ls" "-a")
    'msg-me)
  )

(defun ls-test2 ()
  (interactive)
  (set-process-sentinel
    (start-process "ls" "*ls*" "ls" "-a")
    (lambda (process event)
    (princ
      (format "Process: %s had the event [%s]" process event)))
    )
  )

*ls*
.
..
COPYING
addpm.exe
cmdproxy.exe
ctags.exe
ddeclient.exe
digest-doc.exe
ebrowse.exe
emacs.exe
emacsclient.exe
emacsclientw.exe
etags.exe
hexl.exe
movemail.exe
runemacs.exe
sorted-doc.exe
*Messages*
Process: ls<1> had the event [finished
]

[Emacs][Elisp]region 指定

(defun dosomething-region (pmin pmax)
  (interactive "r")
  (message "pmin:%d pmax:%d" pmin pmax)
)
region を選択して M-x dosomething-region を実行すると *Messages* バッファに以下のように表示される
pmin:405 pmax:423
interactive に "r" を渡すと選択した region の開始位置、終了位置が引数に格納される。

[Emacs][Elisp]HTTP Post の elisp を interactive 対応

POST 先のサーバ、渡すパラメータ (First name, Last name) を入力することができるようになる
(defun http-post (server fname lname)
  (interactive "sServer:\nsFirst name:\nsLast name:")
  (setq proc (open-network-stream "http-proc" "*http-buffer*" server 80))
  (set-process-coding-system proc 'binary 'binary)
  (setq content-len
    (+ (+ (+ (length "fname=") (length fname)) (length "&lname=")) (length lname)))
  (process-send-string
    proc
    (format (concat
    "POST /test.php HTTP/1.0\r\n"
    "Content-Type: application/x-www-form-urlencoded\r\n"
    "Content-Length: "
    (number-to-string content-len)
    "\r\n"
    "\r\n"
    "fname="
    fname
    "&lname="
    lname))))

[Emacs][Elisp]入力された文字列の長さを表示する

length 関数を使用して入力された文字列を表示する関数
(defun string-length (str)
  (interactive "sInput a string:")
  (setq len (length str))
  (message "String: %s (%d)" str len))
M-x string-length を実行すると mini-buffer に文字列の入力を求めるメッセージが表示される。文字列を入力すると入力した文字列とその文字数を表示する
String: hello (5)

[Emacs][Elisp]interactive 関数

コマンド実行時に質問してきてくれる interactive な関数の定義
(interactive "sWhat is your name: ")
これを実行すると mini-buffer に What is your name: と表示される。そこで文字列を入力すると結果が表示される
(interactive "sWhat your name: ")
("hoge")
数字を入力させる場合は下記のように n を先頭につける
(interactive "nInput your favorite number: ")
(5)
関数を定義して M-x 関数名 で実行すると mini-buffer に interactive で値を入力して渡すことができる
(defun add (a b)
  (interactive "nFirst argument:\nnSecond argument:")
  (setq ans (+ a b))
  (message "Ans: %d" ans))

add
M-x add を実行すると First argument:, Second argument: と mini-buffer に表示され、数値を入力する。計算結果は mini-buffer に出力される