[Date Prev] [Date Index] [Date Next]
[Thread Prev] [Thread Index] [Thread Next]

[xyzzy:06322] 初めまして and 添削願い



初めまして。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))

Index Home