;;; lisp file for xyzzy ver0.2.2.234
;;; recent-delete-file.l ver.0.1.1.2 // crayonzen [2006-04-28]00:27:36(+0900)

;;; 最近閉じたファイルをファイルのメニューに追加します。
;;;１： .xyzzy または siteinit.l に
;;;     (load-library "recent-delete-file")

;;; アンインストール
;;;１： 「最近閉じたファイル」のヒストリ変数そのものを削除します。
;;;      M-x: recent-delete-file-unregister
;;;２： .xyzzy または siteinit.l に書いたロード文をコメントアウトか削除して~%xyzzyを終了させます。

(provide "recent-delete-file")

(in-package "editor")

(export '(recent-delete-file-add-history-to-menu
	  recent-menu-history-max
	  recent-clear-minibuffer-file-name-history
	  recent-clear-delete-file-history
	  *recent-delete-file-history*
	  recent-delete-file-unregister
	  ))

;;;ヒストリ
(define-history-variable *recent-delete-file-history* nil)

;;;保存するヒストリの最大値
;;;history.l:16:(defvar *save-history* 200)
;;;minibuf.l:38:(defvar *minibuffer-maximum-history-count* 200)
(defvar *delete-file-history-max* 100)

;;;ed::add-lru-menuを上書き表示変更
;;;メニュー表示数は共通設定に依存
;;;app-menu.l:29:(defvar *menu-history-max* 9)

;;;メニューに表示するファイルの履歴の数を変更 default 9 (0~16)
;(setq *menu-history-max* 34)
;;;メニューに表示されるファイルパスの長さを変更 default 40
;(setq *menu-display-length* 40)

;;;メニューに表示するファイルの履歴の数を変更 (0~ )
(defun recent-menu-history-max (n)
  (interactive "nmax: ")
  (if (>= n 0)
      (progn
	(setq *menu-history-max* n)
	(add-file-history-to-menu)
	(recent-delete-file-add-history-to-menu)
	(refresh-screen t)))
  )

;;;履歴を削除
(defun recent-clear-minibuffer-file-name-history ()
  (interactive)
  (when (no-or-yes-p "「最近使ったファイル」の履歴を削除しますか？")
    (setq *minibuffer-file-name-history* nil)
    (add-file-history-to-menu) ;;refresh menu popup
    (refresh-screen t)
    )
  )

(defun recent-clear-delete-file-history ()
  (interactive)
  (when (no-or-yes-p "「最近閉じたファイル」の履歴を削除しますか？")
    (setq *recent-delete-file-history* nil)
    (recent-delete-file-add-history-to-menu)
    (refresh-screen t)
    )
  )

;;;ポップアップメニュー
(defvar *recent-delete-file-popup-menu* nil)

(defun recent-delete-file-add-to-history (filename)
  (if (get-buffer-file-name filename)
      (progn
	(add-history (get-buffer-file-name filename) '*recent-delete-file-history*)
	(setq exceed (- (length *recent-delete-file-history*) *delete-file-history-max*))
	(if (> exceed 0)
	    (setq *recent-delete-file-history* (nbutlast *recent-delete-file-history* exceed)))
	(recent-delete-file-add-history-to-menu) ;;refresh popup menu
	(refresh-screen t)
	))
  t)

(defun init-recent-delete-file-history-menu ()
  (or *recent-delete-file-popup-menu*
      (setq *recent-delete-file-popup-menu* (create-popup-menu ':recent-delete-file-popup)))
  )

;;;フック
(add-hook '*delete-buffer-hook* 'recent-delete-file-add-to-history)

(add-hook '*init-app-menus-hook*
	  #'(lambda ()
	      (when (setq menu (get-menu *app-menu* 'ed::file))
		(init-recent-delete-file-history-menu)
		(recent-delete-file-add-history-to-menu)
		(insert-popup-menu menu 18 *recent-delete-file-popup-menu* "最近閉じたﾌｧｲﾙ(&B)")
		)
	      )
	  )

;*menu-history-max* def9 max16 // 35
;*menu-display-length* def40 // 60

(defun ed::add-lru-menu (menu files fn)
  (when (menup menu)
    (while (delete-menu menu 0 t))

    ;;    (let (bufferlist)
    ;;      (dolist (item (buffer-list) bufferlist)
    ;;	(setq pathnamebuf (get-buffer-file-name item))
    ;;	(if pathnamebuf
    ;;	    (push pathnamebuf bufferlist)))
;buffer-name
    (sit-for .3)
    (do ((file files (cdr file))
	 (count 1))
	((or (null file)
	     (> count *menu-history-max*))
	 t)
      (unless (wild-pathname-p (car file))
	(let ((filename (namestring (car file))))
	  (insert-menu-item menu (1- count) nil
			    (format nil "&~:(~35r~): ~a"
				    (rem count 36)
				    (quote-string
				     ;(concat (if (find filename bufferlist :test #'equalp)
				     (concat (if (find-buffer (file-namestring filename))
						 "● "
					       (if (file-exist-p filename)
						   "○ "
						 "× "))
					     (file-namestring filename)
					     (if (= 0 *menu-display-length*)
						 ""
					       " __ ")
					     (abbreviate-display-string
					      (directory-namestring filename) *menu-display-length* t)
					     )
				     #\& #\&))
			    (funcall fn filename)))
	(incf count)))
    ;)
    )
  )

(defun recent-delete-file-add-history-to-menu ()
  (when (menup *app-menu*)
    (ed::add-lru-menu *recent-delete-file-popup-menu*
		      *recent-delete-file-history*
		      #'(lambda (filename)
			  #'(lambda ()
			      (interactive)
			      (find-file filename)
			      (add-history filename '*minibuffer-file-name-history*)
			      ))))
  )

;;;アンインストール
(defun recent-delete-file-unregister ()
  (interactive)
  (when (no-or-yes-p "ｱﾝｲﾝｽﾄｰﾙ~%「最近閉じたﾌｧｲﾙ」のﾋｽﾄﾘ変数そのものを削除します。")
    (let ((history-variables
	   '(*recent-delete-file-history*
	     )))
      (dolist (variable history-variables)
	(unregister-history-variable variable)))
    (message "deleted - unregister recent-delete-file : *recent-delete-file-history*"))
  )
