[xyzzy:06322] 初めまして and 添削願い
- Subject: [xyzzy:06322] 初めまして and 添削願い
- From: quarto <quarto@xxxxxxxxxxxx>
- X-mailer: Becky! ver. 2.00.03
初めまして。quarto といいます。
以下のようなものを書いていたのですが、いろいろと分からないところが出て
きました。
1. xf-reload の最初で、
a: xf-dir の最後に "/" が無かったら付け加える
b: xf-dir が存在しなかったらプロンプトを出して、xf-dir を入力しても
らい、throw で a に戻る。
という処理をしたいんですが、どうも a に戻らずそのまま下へ抜けているみた
いです。これじゃ困るんで、今度は catch を削って throw しているところで
xf-reload を呼ぼうとしたら b から抜けれなくなってしまいました。どこがだ
めなんでしょう。
2. minibuffer って 1 行分しか使えないんですか ? ミニバッファをがばっと
広げて色々使おうと思っているんですが、
(minibuffer-prompt "~A~%~A" "Hello" "World!!")
とかやっても改行しないので
3. 属性を調べているところ (xf-get-file-attr) ですが、そもそもこの結果は
正しいのでしょうか。logand #xfff のやっていることがわかんないです。
(logand #xfff (get-file-attributes x)) で色々ファイルを調べて
R: 1 H: 2 A: 32 D: 16 こういうことなのかな、と思ってでっち上げたんですが。
ほかにも外部変数と局所変数の使い分け、ソートの馬鹿さ加減など気になると
ころがあるので、問題点を教えてもらえるとありがたいです。
以下のコードを試す時は 1. のような問題があるので xf-dir に正しいパスを
設定してください。あとは ESC x xf-info-mode すればとりあえず動きます。
やる前に save-winconf しておいた方がいいと思います。
-----------------------------------------------------
;;; -*- Mode: Lisp; Package: EDITOR -*-
;; buffer とか mode とかを書いた
;; ちょこっとエラー処理をつけた
;; フック
(defvar *xf-info-mode-hook* nil)
(defvar *xf-mode-hook* nil)
;; キーマップ
(defvar *xf-info-mode-map* nil)
(unless *xf-info-mode-map*
(setq *xf-info-mode-map* (make-sparse-keymap)))
(defvar *xf-mode-map* nil)
(unless *xf-mode-map*
(setq *xf-mode-map* (make-sparse-keymap)))
;; buffer 作ったり
(defun xf-info-mode ()
(interactive)
(switch-to-buffer "xF-info")
(kill-all-local-variables)
(setq buffer-mode 'xf-info-mode)
(setq mode-name "xF-info")
(use-keymap *xf-info-mode-map*)
(make-local-variable 'need-not-save)
(setq need-not-save t)
(make-local-variable 'auto-save)
(setq auto-save nil)
(set-local-window-flags (selected-buffer)
*window-flag-line-number* nil)
(set-local-window-flags (selected-buffer)
*window-flag-vscroll-bar* nil)
(set-local-window-flags (selected-buffer)
*window-flag-eof* nil)
(set-local-window-flags (selected-buffer)
*window-flag-hscroll-bar* nil)
(set-local-window-flags (selected-buffer)
*window-flag-mode-line* nil)
(set-local-window-flags (selected-buffer)
*window-flag-cursor-line* nil)
(run-hooks '*xf-info-mode-hook*)
(make-xf-mode))
(defun make-xf-mode ()
(shrink-window 4)
(split-window 6)
(other-window)
(xf-mode))
(defun xf-mode ()
(interactive)
(switch-to-buffer "xF")
(kill-all-local-variables)
(setq buffer-mode 'xf-mode)
(setq mode-name "xF")
(use-keymap *xf-mode-map*)
(make-local-variable 'neet-not-save)
(setq need-not-save t)
(make-local-variable 'auto-save)
(setq auto-save nil)
(set-local-window-flags (selected-buffer)
*window-flag-line-number* nil)
(set-local-window-flags (selected-buffer)
*window-flag-vscroll-bar* nil)
(set-local-window-flags (selected-buffer)
*window-flag-eof* nil)
(set-local-window-flags (selected-buffer)
*window-flag-hscroll-bar* nil)
(set-local-window-flags (selected-buffer)
*window-flag-mode-line* nil)
(set-local-window-flags (selected-buffer)
*window-flag-cursor-line* t)
(run-hooks '*xf-mode-hook*)
(xf-refresh)
(test1 xf-table))
;; とりあえずの設定
(setq xf-save-cur nil)
(setq xf-IDX nil)
(setq xf-dir "d:/aaaaa")
;; 1 から優先的に上に表示する
(setq xf-ext-num-1 '(".lzh" ".zip" ".tar" ".gz" ".tgz" ".tar" ".bz2" ".cab" ".rar"))
(setq xf-ext-num-2 '(".exe" ".com" ".cmd" ".pif" ".bat"))
(setq xf-ext-num-3 '(".hlp" ".chm"))
(setq xf-ext-num-4 '(".txt"))
(setq xf-ext-num-5 '(".l" ".el" ".ini" ".crc" ".lst" ".log"))
(setq xf-ext-num-6 '(".jpg" ".png" ".bmp" ".gif" ".psd" ".tiff" ".tga" ".pcx"))
(setq xf-ext-num-7 '(".html" ".htm" ".shtml"))
(setq xf-ext-num-8 '(".dll" ".bpl"))
;;;;; 本体
; directory 内の情報を収めたリストを構築する
(defun xf-refresh ()
(setq xf-table nil)
(setq xf-mark-list nil)
(setq default-directory xf-dir)
(catch 'START
; xf-dir の最後に "/" が無いなら付け加える
(if (not (string-matchp "/$" xf-dir))
(setq xf-dir (concat xf-dir "/")))
; xf-dir が存在しないときの処理
(if (not (file-exist-p xf-dir)) (xf-dir-is-not-found)))
(let* (
(N 0)
(IDX 0)
(LIST (directory xf-dir))
(LEN (length LIST)))
(while (< N LEN)
(catch 'NEXT
(let* (
(FILE (nth N LIST))
(PASS (concat xf-dir FILE)))
(xf-get-file-attr PASS)
(xf-get-file-size PASS)
(xf-get-name-and-ext (pathname-type PASS) FILE)
(let* (
(NAME xf-file-name)
(EXT xf-file-ext)
(SIZE xf-file-size)
(TIME
(format-date-string "%Y/%m/%d %H:%M:%S" (file-write-time PASS)))
(ATTR xf-file-attr)
(EXT-N (xf-get-ext-number EXT ATTR)))
(incf IDX)
(setq xf-table
(append
xf-table
(list
(append
(list NAME EXT SIZE TIME ATTR EXT-N)))))))
(incf N)))
(xf-file-sort LEN)))
; (if (numberp xf-save-cur)(setq xf-IDX xf-save-cur))))
; ディレクトリが存在しなかったときの処理
; ミニバッファの使い方がわかんない
(defun xf-dir-is-not-found ()
(minibuffer-prompt "~A にアクセスできません。" xf-dir)
(sleep-for 2)
(loop
(setq xf-dir (read-string "Directory >> "))
(throw 'START t)))
; 属性を得る。この処理あってんのかなぁ
(defun xf-get-file-attr (x)
(setq xf-file-attr "")
(let ((num (logand #xfff (get-file-attributes x))))
(if (zerop num)
(setq xf-file-attr "----")
(progn
(if (member (floor (/ num 10)) '(1 4 5))
(setq xf-file-attr (concat "D" xf-file-attr))
(setq xf-file-attr (concat "-" xf-file-attr)))
(if (>= num 32)
(setq xf-file-attr (concat "A" xf-file-attr))
(setq xf-file-attr (concat "-" xf-file-attr)))
(if (member num '(2 3 18 19 34 35 50 51))
(setq xf-file-attr (concat "H" xf-file-attr))
(setq xf-file-attr (concat "-" xf-file-attr)))
(if (oddp num)
(setq xf-file-attr (concat "R" xf-file-attr))
(setq xf-file-attr (concat "-" xf-file-attr)))))))
; サイズを入れる。directory なら "<DIR>" を入れる
(defun xf-get-file-size (x)
(setq xf-file-size (file-length x))
(if (and (= xf-file-size 0)
(file-directory-p x))
(setq xf-file-size "<DIR>")))
;
(defun xf-get-name-and-ext (l n)
(setq xf-file-ext l)
(setq xf-file-name n)
(if (stringp l)
; "xyzzy.exe" から "." + "exe" をひいて "xyzzy" を得る
(let ((m (1- (- (length n) (length l)))))
(setq xf-file-name (substring n 0 m))
(setq xf-file-ext (concat "." xf-file-ext)))
(progn
; 拡張子がなかったら""を入れる
(setq xf-file-ext "")
; フォルダ名の"/"をとる
(setq xf-file-name
(car (split-string xf-file-name #\/))))))
;; 拡張子によって返す値を決める
; 適当に :test #'string-matchp ってやったら動いた
(defun xf-get-ext-number (l m)
(cond
((string-matchp "D" m) 0)
((member l xf-ext-num-1 :test #'string-matchp) 1)
((member l xf-ext-num-2 :test #'string-matchp) 2)
((member l xf-ext-num-3 :test #'string-matchp) 3)
((member l xf-ext-num-4 :test #'string-matchp) 4)
((member l xf-ext-num-5 :test #'string-matchp) 5)
((member l xf-ext-num-6 :test #'string-matchp) 6)
((member l xf-ext-num-7 :test #'string-matchp) 7)
((member l xf-ext-num-8 :test #'string-matchp) 8)
(t 9)))
; バブルソートのつもり
(defun xf-file-sort (c)
(let ((a 0)
(b 0))
(while (< a (1- c))
; a を引くのはでかいのは後ろへ行くので比べる必要はないから
(while (< b (- (1- c) a))
(cond
; 隣り合ったりすとの要素内の EXT-N を比較
((> (nth 5 (nth b xf-table)) (nth 5 (nth (1+ b) xf-table)))
(cond
(; table の先頭で逆になっていた場合(butlast が nil を返しちゃうので)
(zerop b)
(setq xf-table
; 単純に、ひっくり返したのと残りのリストをくっつける
(append
(list (nth 1 xf-table) (nth 0 xf-table))
(nthcdr 2 xf-table)))
(incf b))
(t
(setq xf-table
(append
(append
; 比べている要素を含むリスト同士の前方のリストと
(butlast xf-table (- c b))
; 比較しているリストをひっくり返したのと
(list (nth (1+ b) xf-table) (nth b xf-table)))
; 残りのリストをくっつける
(nthcdr (+ 2 b) xf-table)))
(incf b))))
(t (incf b))))
(setq b 0)
(incf a))))
; テスト表示用
(defun test1 (r)
(save-excursion
(with-output-to-selected-buffer
(dolist (p r)
(if (integerp (nth 2 p))
(format t "~%~A ~10@A~5@A~10D~22A~6A"
(nth 5 p) (nth 0 p) (nth 1 p) (nth 2 p) (nth 3 p) (nth 4 p))
(format t "~%~A ~10@A~5@A~10A~22A~6A"
(nth 5 p) (nth 0 p) (nth 1 p) (nth 2 p) (nth 3 p) (nth 4 p))))))
(forward-line 1))