emacs-devel
[Top][All Lists]
Advanced

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

Re: collect-string


From: Tak Ota
Subject: Re: collect-string
Date: Thu, 2 Dec 2010 17:03:51 -0800

Thanks Stefan.

Thu, 2 Dec 2010 06:16:16 -0800: Stefan Monnier <address@hidden> wrote:

> >> > Now I am convinced.  How about the change below?
> >> Could you send it as a context patch?
> > How about this?
> 
> IIUC the new arg `collect' overrides `lines' in the sense that when
> collect is non-nil lines is simply unused.  So I suggest to just use
> a single argument instead (`lines') and simply give additional semantics
> to values that weren't supported until now.
> E.g. if (numberp lines) then do as before, but if (consp lines) then
> only keep the actual match, where (car lines) could specify which
> submatch to keep.

Very good point.  It made the change much cleaner.

> 
> >     (list (read-regexp "List lines matching regexp"
> >                  (car regexp-history))
> >     (when current-prefix-arg
> > !     (prefix-numeric-value current-prefix-arg))
> > !   (and current-prefix-arg
> > !        (listp current-prefix-arg)
> > !        (setq last-collect-number
> > !              (read-number "Collect" last-collect-number)))))
> 
> I recommend you first check (with regexp-opt-depth) whether there is
> a submatch, and if not, don't `read-number'.  It's likely to be a very
> common case.

Another excellent suggestion.

> 
> > !     (if collect
> > !   (with-current-buffer occur-buf
> > !     (fundamental-mode)
> > !     (let ((inhibit-read-only t)
> > !           (buffer-undo-list t))
> > !       (erase-buffer)
> > !       (while active-bufs
> > !         (with-current-buffer (car active-bufs)
> > !           (save-excursion
> > !             (goto-char (point-min))
> > !             (while (re-search-forward regexp nil t)
> > !               (let ((str (match-string collect)))
> > !                 (if str
> > !                     (with-current-buffer occur-buf
> > !                       (insert str)
> > !                       (or (zerop (current-column))
> > !                           (insert "\n"))))))))
> > !         (setq active-bufs (cdr active-bufs))))
> > !     (display-buffer occur-buf))
> > !       (with-current-buffer occur-buf
> > !   (occur-mode)
> > !   (let ((inhibit-read-only t)
> > !         ;; Don't generate undo entries for creation of the initial 
> > contents.
> > !         (buffer-undo-list t))
> > !     (erase-buffer)
> > !     (let ((count (occur-engine
> > !                   regexp active-bufs occur-buf
> > !                   (or nlines list-matching-lines-default-context-lines)
> > !                   (if (and case-fold-search search-upper-case)
> > !                       (isearch-no-upper-case-p regexp t)
> > !                     case-fold-search)
> > !                   list-matching-lines-buffer-name-face
> > !                   nil list-matching-lines-face
> > !                   (not (eq occur-excluded-properties t)))))
> > !       (let* ((bufcount (length active-bufs))
> > !              (diff (- (length bufs) bufcount)))
> > !         (message "Searched %d buffer%s%s; %s match%s for `%s'"
> > !                  bufcount (if (= bufcount 1) "" "s")
> > !                  (if (zerop diff) "" (format " (%d killed)" diff))
> > !                  (if (zerop count) "no" (format "%d" count))
> > !                  (if (= count 1) "" "es")
> > !                  regexp))
> > !       (setq occur-revert-arguments (list regexp nlines bufs))
> > !       (if (= count 0)
> > !           (kill-buffer occur-buf)
> > !         (display-buffer occur-buf)
> > !         (setq next-error-last-buffer occur-buf)
> > !         (setq buffer-read-only t)
> > !         (set-buffer-modified-p nil)
> > !         (run-hooks 'occur-hook))))))))
> 
> The "if collect" test should probably not be placed so far out: the
> `collect' case should output the same message, run the same hooks, etc
> as the non-collect case.

How about this?  See below.

-Tak

*** ../../../d/pub/emacs/emacs-23.2.90/lisp/replace.el  Thu Dec  2 16:33:19 2010
--- replace.el  Thu Dec  2 17:00:42 2010
***************
*** 527,532 ****
--- 527,536 ----
  Maximum length of the history list is determined by the value
  of `history-length', which see.")
  
+ (defvar occur-collect-submatch-history '("1")
+   "The history of list of parenthesized expression numbers as a
+   string in occur's collect operation")
+ 
  (defun read-regexp (prompt &optional default-value)
    "Read regexp as a string using the regexp history and some useful defaults.
  Prompt for a regular expression with PROMPT (without a colon and
***************
*** 1028,1037 ****
        (nreverse result))))
  
  (defun occur-read-primary-args ()
!   (list (read-regexp "List lines matching regexp"
!                    (car regexp-history))
!       (when current-prefix-arg
!         (prefix-numeric-value current-prefix-arg))))
  
  (defun occur-rename-buffer (&optional unique-p interactive-p)
    "Rename the current *Occur* buffer to *Occur: original-buffer-name*.
--- 1032,1058 ----
        (nreverse result))))
  
  (defun occur-read-primary-args ()
!   (let ((regexp)
!       (do-collect (consp current-prefix-arg)))
!     (list (setq regexp
!               (read-regexp (if do-collect
!                                "Collect strings matching regexp"
!                              "List lines matching regexp")
!                            (car regexp-history)))
!         (if do-collect
!             (if (zerop (regexp-opt-depth regexp))
!                 ;; no subexpression so collect entire the match
!                 '(0)
!               ;; construct a list of subexpression integers
!               (mapcar 'string-to-number
!                       (split-string
!                        (let ((default (car occur-collect-submatch-history)))
!                          (read-from-minibuffer
!                           (format "Subexpressions to collect (default %s): " 
default)
!                           "" nil nil 'occur-collect-submatch-history default)
!                          (car occur-collect-submatch-history)))))
!           (when current-prefix-arg
!             (prefix-numeric-value current-prefix-arg))))))
  
  (defun occur-rename-buffer (&optional unique-p interactive-p)
    "Rename the current *Occur* buffer to *Occur: original-buffer-name*.
***************
*** 1064,1070 ****
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
  
  If REGEXP contains upper case characters (excluding those preceded by `\\')
! and `search-upper-case' is non-nil, the matching is case-sensitive."
    (interactive (occur-read-primary-args))
    (occur-1 regexp nlines (list (current-buffer))))
  
--- 1085,1101 ----
  \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
  
  If REGEXP contains upper case characters (excluding those preceded by `\\')
! and `search-upper-case' is non-nil, the matching is case-sensitive.
! 
! When NLINES is a list of integers or when the function is called
! interactively with prefix argument without a number (`C-u' alone
! as prefix) the matching strings are collected into the `*Occur*'
! buffer.  The parenthesized match strings in REGEXP indicated by
! the integers in NLINES are collected.  For example, providing
! \"defun \\(\\S +\\)\" for REGEXP and (1) for NLINES collects all
! the function names in a lisp program.  When there is no
! parenthesized subexpressions in REGEXP the entire match is
! collected."
    (interactive (occur-read-primary-args))
    (occur-1 regexp nlines (list (current-buffer))))
  
***************
*** 1146,1165 ****
      (setq occur-buf (get-buffer-create buf-name))
  
      (with-current-buffer occur-buf
!       (occur-mode)
        (let ((inhibit-read-only t)
            ;; Don't generate undo entries for creation of the initial contents.
            (buffer-undo-list t))
        (erase-buffer)
!       (let ((count (occur-engine
!                     regexp active-bufs occur-buf
!                     (or nlines list-matching-lines-default-context-lines)
!                     (if (and case-fold-search search-upper-case)
!                         (isearch-no-upper-case-p regexp t)
!                       case-fold-search)
!                     list-matching-lines-buffer-name-face
!                     nil list-matching-lines-face
!                     (not (eq occur-excluded-properties t)))))
          (let* ((bufcount (length active-bufs))
                 (diff (- (length bufs) bufcount)))
            (message "Searched %d buffer%s%s; %s match%s for `%s'"
--- 1177,1226 ----
      (setq occur-buf (get-buffer-create buf-name))
  
      (with-current-buffer occur-buf
!       (if (consp nlines)
!         (fundamental-mode) ;; for collect opeartion
!       (occur-mode))
        (let ((inhibit-read-only t)
            ;; Don't generate undo entries for creation of the initial contents.
            (buffer-undo-list t))
        (erase-buffer)
!       (let ((count
!              (if (consp nlines)
!                    ;; nlines is a list of subexpression integers to collect
!                  (let ((bufs active-bufs)
!                        (count 0))
!                    (while bufs
!                      (with-current-buffer (car bufs)
!                        (save-excursion
!                          (goto-char (point-min))
!                          (while (re-search-forward regexp nil t)
!                              ;; insert the mached subexpressions in a line
!                            (let ((first-subexp t))
!                              (mapc
!                               (lambda (subexp)
!                                 (let ((str (match-string subexp)))
!                                   (if str
!                                       (with-current-buffer occur-buf
!                                         (if first-subexp
!                                             (setq first-subexp nil)
!                                           (insert " ")) ;; delimiter
!                                         (insert str)))))
!                               nlines)
!                              (setq count (1+ count)))
!                            (with-current-buffer occur-buf
!                              (or (zerop (current-column))
!                                  (insert "\n"))))))
!                        (setq bufs (cdr bufs)))
!                      count)
!                (occur-engine
!                 regexp active-bufs occur-buf
!                 (or nlines list-matching-lines-default-context-lines)
!                 (if (and case-fold-search search-upper-case)
!                     (isearch-no-upper-case-p regexp t)
!                   case-fold-search)
!                 list-matching-lines-buffer-name-face
!                 nil list-matching-lines-face
!                 (not (eq occur-excluded-properties t))))))
          (let* ((bufcount (length active-bufs))
                 (diff (- (length bufs) bufcount)))
            (message "Searched %d buffer%s%s; %s match%s for `%s'"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]