Top / Elisp / 関数リファレンス

Elisp

http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=reference%20function

はじめに

Emacs Lisp を書く時に,「これはどうすればいいんだったか...」ということが あります.

そんな Emacs Lisp を書く時に役立つ (かもしれない) ヒントを書いていくページです.

思いついたのがあれば,どんどん追加してください.間違ってるところがあったら,こっ そり直してください.小人さん歓迎です.

目次

ファイルとディレクトリ

ファイルサイズを調べる

(nth 7 (file-attributes "~/.emacs"))

で分かる.file-attributes については http://www.bookshelf.jp/cgi-bin/goto.cgi?file=elisp21&node=File%20Attributes リファレンスマニュアル を参照のこと.

ディレクトリの場所

いろんなディレクトリを知るための変数たち.

  • data-directory -> g:/unix/Meadow2/2.00/etc/
  • exec-directory -> g:/unix/Meadow2/2.00/bin/
  • temporary-file-directory -> d:/home/tmp/
  • exec-path -> PATH

実行ファイルの存在確認

以下でできる.

(locate-library "bash.exe" nil exec-path)

Emacs Lisp ファイルの確認だけなら,

(locate-library "gnus")

でいい.これで,実行ファイル名やElispのファイル名が返ってくる.

プロセスの終了を見張る

必ず決まった文字で終了するなら,

(while (re-search-forward "end" nil t)
  ;; 0.5 秒待つ
  (sit-for 0.5))

でもいいかもしれん.番兵を使う方がスマートか.

(defvar pukiwiki-download-running nil)
(defun pukiwiki-download-sentinel (proc str)
  (setq pukiwiki-download-running nil))

てなものを用意しておいて,

(set-process-sentinel proc 'pukiwiki-download-sentinel)
(process-send-string
 connection
 (concat
  (concat "GET " path
          " HTTP/1.0\r\n"
          (concat "Host: " server "\r\n")
          "Connection: close\r\n"
          "Content-type: application/x-www-form-urlencoded\r\n"
          "\r\n")))
;; プロセスが終わるまで待つ
(while pukiwiki-download-running
  (sit-for 1))

のようにプロセスに番兵をつけておく.プロセスの状態が変化すると番兵が呼ばれる.こ の場合は,番兵が呼ばれると pukiwiki-download-running が nil になり,終了したこと を確認している.

ファイルのダウンロード

pukiwiki-mode で悩んだもの.

(pukiwiki-http-download "http://www/nat0303009.jpg" "~/test.jpg")

でファイルをダウンロードできる.適当なのでおかしいところもあるかも.

(setq http-proxy-server "proxy.server")
(setq http-proxy-port 8080)
(defvar pukiwiki-download-running nil)
(defun pukiwiki-download-sentinel (proc str)
  (setq pukiwiki-download-running nil))

(defun pukiwiki-http-download (url filename)
  "Fetch via HTTP and save to the filename."
  (message "Downloading file...")
  (let (connection server port path buf str len
                   (coding-system-for-write 'binary)
                   (coding-system-for-read 'binary))
    (setq pukiwiki-download-running t)
    (string-match
     "^http://\\([^/:]+\\)\\(:\\([0-9]+\\)\\)?\\(/.*$\\)" url)
    (setq server (match-string 1 url)
          port (string-to-int (or (match-string 3 url) "80"))
          path (if http-proxy-server url (match-string 4 url)))
    (save-excursion
      (setq buf (get-buffer-create
                 (concat "*result from " server "*")))
      (set-buffer buf)
      (erase-buffer)
      (setq connection
           (open-network-stream
            (concat "*request to " server "*")
            buf
            (or http-proxy-server server)
            (or http-proxy-port port)))
      (set-process-coding-system connection 'binary 'binary)
      (set-process-sentinel connection
                            'pukiwiki-download-sentinel)
      (process-send-string
       connection
       (concat
        (concat
         "GET " path
         " HTTP/1.0\r\n"
         (concat "Host: " server "\r\n")
         "Connection: close\r\n"
         "Content-type: application/x-www-form-urlencoded\r\n"
         "\r\n")))
      (goto-char (point-min))
      (while pukiwiki-download-running
        (sit-for 1)))
    (set-buffer buf)
    (goto-char (point-min))
    ;; header の後に移動
    (re-search-forward "\r\n\r?\n" nil t)
    (write-region
     (point) (point-max) filename))
  (message "Downloading file... done!"))

関数を変数として定義

http://d.hatena.ne.jp/hikigaeru/20040304#p1 より

(let* ((str "")
       (hoge #'(lambda(lst)
                 (if (null lst)
                     (setq str (concat str "だー!!"))
                   (setq str (concat str (car lst)))
                   (funcall hoge (cdr lst))))))
  (funcall hoge '("イチ " "ニー " "サン ")))
=>"イチ ニー サン だー!!"

わざわざ定義するほどでもない関数を使いたい時に使う.

ミニバッファ関連

メッセージをスクロール

emacs-w3m-ML より

From: Masatake YAMATO
Subject: [emacs-w3m:07770] Re: Restricting the width of the title
Message-Id: <20050303.203045.161492614.jet@gyve.org>
少いスペースを使って長い文字列をユーザに提示するための、ゴミコードを
持っているのですが、万が一にも役に立ちそうだったら使って下さい。添付
しているコードをevalしてみて下さい。
;; message-with-bouncing
;; message-with-rolling
;; Characters other than alphabet are not supported.
(require 'cl)
(defvar eyecatch-default-internval 0.05)
(defvar eyecatch-border-internval 1.0)

   (defface eyecatch-red '((((class color)) (:foreground "red"))) "")
   (defface eyecatch-orange '((((class color)) (:foreground "orange"))) "")
   (defface eyecatch-yellow '((((class color)) (:foreground "yellow"))) "")
   (defface eyecatch-green  '((((class color)) (:foreground "green"))) "")
   (defface eyecatch-blue   '((((class color)) (:foreground "blue"))) "")
   (defface eyecatch-purple '((((class color)) (:foreground "purple"))) "")
   (defface eyecatch-black '((((class color)) (:foreground "black"))) "")

(defvar eyecatch-faces 
  [eyecatch-black
;  eyecatch-red    
;   eyecatch-orange 
;   eyecatch-yellow 
;   eyecatch-green  
;   eyecatch-blue   
;   eyecatch-purple
    ]) 

(defun here-tooltip (text)
  (require 'tooltip)
  (require 'avoid)
  (let* ((P (mouse-avoidance-point-position))
    (frame (car P))
    (x (cadr P))
    (y (cddr P))
    (oP (mouse-position))
    (oframe (car oP))
    (ox     (cadr oP))
    (oy     (cddr oP)))
    (set-mouse-position frame x y)
    (tooltip-show text)
    (set-mouse-position frame (1+ x) y)))

(defun here-tooltip (text)
  (message text))

(defun message-with-bouncing (text)
  (let* ((width (- (window-width (minibuffer-window))
          (+ 1 (length "[<] ") (length " [>]"))))
    (tl (length text))
    (steps (- tl width))
    j
    (flag t))
  (if (< tl width)
      (message "%s" (eyecatch-put-text-color text))
    (while flag
      (dotimes (i steps)
   (message "%s" (format "[<] %s [ ]" 
                 (eyecatch-put-text-color (substring text i (+ i width)))))
   (unless (setq flag (sit-for (if (eq i 0) 
                   eyecatch-border-internval
                     eyecatch-default-internval)))
     (return)))
      (if flag
     (dotimes (i steps)
       (setq j (- steps i))
       (message "%s"
            (format "[ ] %s [>]" 
                (eyecatch-put-text-color
                 (substring text j (+ j width)))))
       (unless (setq flag (sit-for (if (eq i 0) 
                   eyecatch-border-internval
                     eyecatch-default-internval)))
         (return))
       ))
      (garbage-collect)
      ))))

(defun message-with-rolling (text)
  (setq text (concat "  <Message>: " text "            "))
  (let* ((width (- (window-width (minibuffer-window))
          (+ 1 (length "[<] "))))
    (tl (length text))
    (normal-range (- tl width))
    j
    (flag t))
  (if (< tl width)
      (here-tooltip (format "%s" text))
    (while flag
      (dotimes (i tl)
   (if (< i normal-range)
       (message "%s" (format "[<] %s" 
                 (eyecatch-put-text-color (substring text i (+ i width)))))
     (message "%s" (format "[<] %s" 
               (eyecatch-put-text-color (concat (substring text i) 
                                (substring text 0 (- (+ i width) tl)))))))
   (unless (setq flag (sit-for (if (eq i 0) 
                   eyecatch-border-internval
                   eyecatch-default-internval)))
     (return)))
      (garbage-collect)
      ))))

(defun eyecatch-put-text-color (text)
  (let ((cl (length eyecatch-faces))
   c)
    (dotimes (i (length text))
      (setq c (aref eyecatch-faces (mod i cl)))
      (put-text-property i (1+ i) 'face c text)))
  text)

;;(message-with-bouncing "!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") 

(message-with-bouncing
 (concat "GNU, which stands for Gnu's Not Unix, is the name for the complete "
    "Unix-compatible software system which I am writing so that I can give it "
    "away free to everyone who can use it.(1) Several other volunteers are "
    "helping me.  Contributions of time, money, programs and equipment are "
    "greatly needed. "))

(message-with-rolling
 (concat "Changes in Emacs 25.4: (1) New C interpreter written in emacs lisp is introduced. "
    " (2) Edebug can debug compiled C code directly."
    " (3) Accelerator pedal and brake pedal are supported as modifier keys(A-x and B-x in short)."))

日付けと時間

3日前の日付けを得る

2ちゃんねるより

From: [453] 名無しさん@お腹いっぱい。 <sage>
Date: 2005/05/02(月) 22:11:39
(【叩かれて】Emacs Lisp道場【強くなれ】)


今日の日付2005-05-02から一日前とか二日前の日付をゲットする
うまい方法ある?なんか普通にプログラムすると、汚くなりそうなので

に対して

From: [307] デフォルトの名無しさん <sage>
Date: 04/01/05 16:37
(Emacs Lisp 2)


(apply (lambda (s min h d mon y dow dst zone)
         (format-time-string "%Y-%m/%d"
           (encode-time s min h (- d 3) mon y)))
       (decode-time))

みたいなのとか、かな…

書き込み

カーソル位置の文字コードを識別

松下 (2003-06-26 (木) 11:22:00)

C-x = とすると,

Char: 〜 (0150301, 53441, 0xd0c1, file ...) point=26 of 604 (4%) column 2 


という結果が得られる.

http://cgi.netlaputa.ne.jp/~kose/diary/?200303b&to=200303153#200303153

より,

(global-set-key "\C-c=" 'what-charset)

(defun what-charset ()
  (interactive)
  (prin1 (find-charset-region
          (if mark-active
              (region-beginning)
            (point))
          (if mark-active
              (region-end)
            (1+ (point))))))

カーソル位置がコメントが文字列かを判断する

松下 (2003-06-26 (木) 10:37:27)

expand.elより
以下のようなコードで,現在のカーソル位置がコメントか文字列かを判断できる.どちらでもなければ,nil になる.

(defun expand-in-literal ()
  "Test if we are in a comment or in a string."
  (save-excursion
    (let* ((lim (or (save-excursion
                      (beginning-of-defun)
                      (point))
                    (point-min)))
           (here (point))
           (state (parse-partial-sexp lim (point))))
      (cond
       ((nth 3 state) 'string)
       ((nth 4 state) 'comment)
       (t nil)))))

ASCII コードを知る

松下 (2003-06-19 (木) 12:30:26)

scratch バッファで

(read-char)


を評価し,キーを入力する.すると,「C-x」なら「24」という風に得られる.


リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: Fri, 28 Dec 2007 17:21:41 JST (3557d)