;;; lisp file for xyzzy ver0.2.2.233 or ver0.2.2.234
;;; grepsd.l ver0.0.0.4 // crayonzen [2006-06-18]10:05:47(+0900)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require "dialogs")
(require "grep")
;(require "grepd")
(require "search")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(provide "grepsd")

(in-package "editor")

(export '(grep-search-dialog
	  grep-search
	  *all-search*
	  fgrep-buffer-search
	  grep-buffer-search
	  ))

(defvar *all-search* nil)
(register-history-variable '(*all-search*))
;;define-history-variable

(defun grep-search (pattern regexp all)
  (interactive)
  (if regexp
      (progn
	(setq *last-search-regexp* pattern)
	(setq *last-grep-regexp* pattern)
	(if all
	    (grep1 (compile-regexp pattern *case-fold-search*) nil)
	  (grep1 (compile-regexp pattern *case-fold-search*) t)
	  ))
    (progn
      (setq *last-search-string* pattern)
      (setq *last-fgrep-pattern* pattern)
      (if all
	  (grep1 pattern nil)
	(grep1 pattern t)
	))
    )
  )

(defvar *grep-search-dialog-template*
  '(dialog 0 0 242 95
    (:caption "GrepBuffer")
    (:font 9 "MS UI Gothic")
    (:control
     (:static nil "検索(&S):" #x50020000 7 10 28 8)
     (:combobox search nil #x50210842 39 8 140 96)
     (:button case-fold "大文字小文字を区別する(&C)" #x50010006 39 27 96 10)
     (:button word "単語単位で検索する(&W)" #x50010003 39 40 83 10)
     (:button regexp "正規表現(&E)" #x50010003 39 53 52 10)
     (:button escseq "エスケープシーケンスを理解しろ(&Y)" #x50010003 39 66 107 10)
     (:button all "全てのバッファ検索(&A)" #x50010003 39 79 101 10)
     (:button IDOK "検索(&S)" #x50010001 185 7 50 14)
     (:button IDCANCEL "キャンセル" #x50010000 185 41 50 14))))

(defun grep-search-dialog ()
  (interactive)
  (multiple-value-bind (result data)
      (let ((string (or (selection-start-end (start end)
			  (buffer-substring start end))
			(if *regexp-search*
			    *last-search-regexp*
			  *last-search-string*))))
	(dialog-box *grep-search-dialog-template*
		    (list (cons 'search *minibuffer-search-string-history*)
			  (cons 'case-fold (cfs2dialog *case-fold-search*))
			  (cons 'word *word-search*)
			  (cons 'regexp *regexp-search*)
			  (cons 'search (if (eq (cdr *last-search-string-pair*)
						string)
					    (car *last-search-string-pair*)
					  string))
			  (cons 'escseq *understand-escape-sequences*)
			  (cons 'all *all-search*)
			  )
		    '((word :disable (regexp))
		      (search :non-null "検索文字列を入力して" :enable (IDOK)))))
    (when result
      (let ((string (cdr (assoc 'search data))))
	(when string
	  (add-history string '*minibuffer-search-string-history*)
	  (setq *case-fold-search* (dialog2cfs (cdr (assoc 'case-fold data))))
	  (setq *word-search* (cdr (assoc 'word data)))
	  (setq *regexp-search* (cdr (assoc 'regexp data)))
	  (setq *all-search* (cdr (assoc 'all data)))
	  (setq *understand-escape-sequences* (cdr (assoc 'escseq data)))
	  (if *understand-escape-sequences*
	      (setq *last-search-string-pair*
		    (cons string
			  (setq string (decode-escape-sequence
					string *regexp-search*))))
	    (setq *last-search-string-pair* nil))
	  (grep-search string (and (null *word-search*) *regexp-search*) *all-search*)
	  )))))

(defun cfs2dialog (x)
  (cond ((null x) t)
	((eq x :smart) :disable)
	(t nil)))

;;+grep buffer search
(defun fgrep-buffer-search (pattern &optional (arg t))
  (interactive "sfgrep search-string: "
	:default0 (if (get-selection-type)
				  (buffer-substring (selection-mark) (selection-point))
				ed::*last-search-string*) :history0 'search)
  (setq *last-search-string* pattern)
  (grep1 pattern arg))

(defun grep-buffer-search (regexp &optional (arg t))
  (interactive "sgrep search-regexp: " :default0 *last-search-regexp* :history0 'search)
  (setq *last-search-regexp* regexp)
  (grep1 (compile-regexp regexp *case-fold-search*) arg))
