3

I want to write a function that uses a selected region and counts the number of left and right bracketing marks (whether (), {}, [], <>).

I have started with this

    (defun veak-count (region-start region-end)
      "todo
    Interactive functions enable them to be called using `M-x`"
      (interactive "r")  ; gets region start and end
    
      (message "Counting bracketing marks ...")
      (save-excursion
        (let (count)
          (setq count 0)
          (goto-char region-start)
    
          (while (and (< (point) region-end)
              (re-search-forward "\(" region-end t))
            (setq count (1+ count))) ))))


I then updated to use `count-matches`, but selecting the following line, gives 0 as count.

    (global-set-key (kbd "[")  'skeleton-pair-insert-maybe)

--------

 (defun veak-count (region-start region-end)
      "Count the `{` characters in the region.
REGION-START and REGION-END are the region limits."
      (interactive "r")
      (save-excursion
        (let ( (count (count-matches "\(" (point) region-end)) )
          (message "%d" count) )))


Dilna
  • 1,173
  • 3
  • 10

2 Answers2

2

Use M-x count-matches to count matches for a regexp that specifies each char you want to count.

E.g M-x count-matches ( counts the number of ( chars in the region.

If you want to check for matching delimiter counts (e.g. ( matching )) then just use count-matches in a function you define, that checks for both.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • How can I make a regex string if I want to search for `(`. – Dilna Mar 10 '22 at 11:42
  • `"("` is a regexp string that matches `(`. Because parens are common in Lisp, Emacs regexps require escaping them to use them as regexp grouping constructs `"\("`. – Drew Mar 10 '22 at 14:57
  • I do not think I require `(narrow-to-region start end)` in the code. You think using it is better? – Dilna Mar 10 '22 at 15:09
  • Right. I just edited the answer to remove that. `count-matches` already looks only in the active region. – Drew Mar 10 '22 at 15:26
  • Would the code be good for getting the count as I have done it ? Would I need more things? – Dilna Mar 10 '22 at 15:44
  • Does it do what you want? If so, fine. (This isn't really a discussion site.) – Drew Mar 10 '22 at 16:20
0

A few fixes/optimizations to what you have (untested):

    (defun veak-count (region-start region-end)
      "Count open-parens between REGION-START and REGION-END."
      (interactive "r")  ; gets region start and end
      (message "Counting bracketing marks ...")
      (save-excursion
        (let ((count 0))
          (goto-char region-start)
          (while (and (< (point) region-end)
                      (search-forward "(" region-end t))
                      ;; or for parens, brackets and braces:
                      ;; (re-search-forward "[([{]" region-end t))
            (cl-incf count))))))
Phil Hudson
  • 1,651
  • 10
  • 13
  • I would like to have separate counts, count for number of `[`, count for number of `{`, count for number of `{`. I think I should pass the opening parens, bracket and brace as a function parameter. Still not sure if this would be good when using `(interactive "r")`. – Dilna Mar 16 '22 at 06:09
  • That sounds to me like exactly the right approach. – Phil Hudson Mar 17 '22 at 09:49
  • How can I adapt it to count both the opening and closing parentheses? The output would then be two numbers. – Dilna Mar 17 '22 at 12:49
  • Can one colour the output when using `message` ? – Dilna Mar 17 '22 at 13:09