0

occur is an interactive compiled Lisp function in ‘replace.el’. The definition is as follows:

(defun occur (regexp &optional nlines region)
  (interactive
   (nconc (occur-read-primary-args)
          (and (use-region-p) (list (region-bounds)))))
  (let* ((start (and (caar region) (max (caar region) (point-min))))
         (end (and (cdar region) (min (cdar region) (point-max))))
         (in-region-p (or start end)))
    (when in-region-p
      (or start (setq start (point-min)))
      (or end (setq end (point-max))))
    (let ((occur--region-start start)
          (occur--region-end end)
          (occur--matches-threshold
           (and in-region-p
                (line-number-at-pos (min start end))))
          (occur--orig-line
           (line-number-at-pos (point)))
          (occur--orig-line-str
           (buffer-substring-no-properties
            (line-beginning-position)
            (line-end-position))))
      (save-excursion ; If no matches `occur-1' doesn't restore the point.
        (and in-region-p (narrow-to-region start end))
        (occur-1 regexp nlines (list (current-buffer)))
        (and in-region-p (widen))))))

When the above function is invoked, the user is prompted to input a regexp for searching.

What I want is to make a new function myoccur by hard-coding a regexp in the above function and make it non-interactive, so that I can conveniently invoke it. If a wrapper over the original occur can make it non-interactive, that would also be great. How should I do?

Drew
  • 75,699
  • 9
  • 109
  • 225
Youjun Hu
  • 121
  • 4
  • https://emacs.stackexchange.com/tags/elisp/info – Drew Jan 24 '21 at 18:15
  • I'm pretty sure this question is a duplicate, but I don't have time now to search for that. Hopefully someone else will find the duplicate. If found, this should be closed as a duplicate. – Drew Jan 24 '21 at 18:17
  • 1
    This question comes close: https://emacs.stackexchange.com/questions/3555/what-is-the-difference-between-a-function-and-a-command. The answer is to just call the command as an ordinary function, providing whatever arguments it needs. – Drew Jan 24 '21 at 18:31
  • 1
    Does this answer your question? [How to call an interactive function and pass arguments to it from within Elisp?](https://emacs.stackexchange.com/questions/59458/how-to-call-an-interactive-function-and-pass-arguments-to-it-from-within-elisp) – Drew Jan 24 '21 at 18:33
  • Also: https://emacs.stackexchange.com/questions/23951/how-to-find-non-interactive-function-equivalents-of-elisp-interactive-functions – Drew Jan 24 '21 at 18:39
  • Also: https://emacs.stackexchange.com/q/5457/105 – Drew Jan 24 '21 at 18:42
  • The following answers my question: https://stackoverflow.com/questions/18733310/in-emacs-is-there-a-way-to-call-interactive-function-non-interactively-from-ini – Youjun Hu Jan 25 '21 at 00:53

1 Answers1

2

I finally found a solution:

(global-set-key (kbd "C-x j") (lambda () (interactive) (occur "regexp" nil)))

I also found that \ needs to be escaped by another \ in the regexp, which is different from the regexp inputted in interactive mode. For example, to match all functions and subroutines defined in a Fortran code, the regexp should be:

^ *\\(\\(subroutine\\)\\|\\(function\\)\\)

while in the interactive mode, the regexp is:

^ *\(\(subroutine\)\|\(function\)\)

Update: The reason is that, which I found at emacs website, the string syntax for a backslash is \\

Youjun Hu
  • 121
  • 4