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

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))))))
  • 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. – Eugene Beresovsky Jul 29 '15 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 '15 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) – Eugene Beresovsky Jul 30 '15 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. – Kaushal Modi Aug 29 '15 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 '15 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.