4

Is there an easy way to search for other occurences of a selected rectangle, regardless of the column at which the pattern starts?

As an example, when searching for the 4x2 text block in lines 1+2 in the sample below, it would result in two matches: one for lines 4+5, one for lines 7+8

1 qwer
2 asdf
3
4   qwer
5   asdf
6
7     qwer
8     asdf

1 Answer 1

1

I didn't find any easy way to do what you want, but make a my-rectangle-forward-search command myself, I am not sure what can I do when find a matching rectangle, so I just use message-box to indicate start/end poing and content of the found rectangle.

(require 'subr-x)                       ; Require Emacs 24.4+

(defun my-rectangle-equal (start1 end1 start2 end2)
  "Return t if two rectangle have identical contents."
  (when-let ((r1-lines (extract-rectangle start1 end1))
             (r2-lines (extract-rectangle start2 end2))
             (r1-line-number (length r1-lines) )
             (r2-line-number (length r2-lines) ))
    (when (and (= r1-line-number r2-line-number)
               (> r1-line-number 0))
      (setq counter 0)
      (catch 'my--break
        (while (< counter r1-line-number)
          (unless (string-equal (elt r1-lines counter)
                                (elt r2-lines counter))
            (throw 'my--break nil))
          (setq counter (1+ counter)))
        t))))

(defun my-rectangle-dialog (start end)
  (interactive "r")
  (message-box (format
                "The content in [%d, %d] rectangle is: \n%s"
                start end
                (mapconcat #'identity (extract-rectangle start end) "\n"))))

(defun my-rectangle-forward-search (start end)
  "Search forward from point for the region-rectangle."
  (interactive "r")
  (when-let ((lines (extract-rectangle start end))
             (line-number (length lines))
             (first-line (car lines)))
    (save-excursion
      (deactivate-mark)     
      (let (-start -end)
        ;; (goto-char end)
        (while (re-search-forward first-line nil 'noerror)
          (setq -start (- (point) (length first-line)))
          (line-move-visual (1- line-number))
          (setq -end (point))
          ;; Do something on rectangle just find
          (my-rectangle-dialog -start -end))))))
5
  • Thanks. I haven't tried to look into the code yet, but when calling my-rectangle-forward-search via M-x, I get the following error: my-rectangle-forward-search: Symbol's function definition is void: when-let. Jul 29, 2015 at 22:32
  • when-let comes from subr-x.el, which requires at least Emacs 24.4. I should call (require subr-x)` before using that macro, will fix.
    – xuchunyang
    Jul 30, 2015 at 3:59
  • Still no luck. Will try to see if there's something wrong with my setup (GNU Emacs 24.5.1 (x86_64-pc-linux-gnu, GTK+ Version 3.16.4) of 2015-06-29 on trouble, modified by Debian) Jul 30, 2015 at 6:24
  • @xuchunyang when-let was added in emacs 25.x. It's still in the master branch only, not yet in any stable release. Aug 29, 2015 at 19:42
  • @kaushalmodi You're right, dash.el's -when-let* can be used here for the same purpose, besides, the code also looks buggy. I think I have to update it when I have time.
    – xuchunyang
    Aug 29, 2015 at 20:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.