I have a file, myfile.txt, whose content is:

(query-replace "foo" "Hello" nil (point-min) (poin-max))

and this function:

(defun comment-string-from-file ()
  (let ((STRING (with-temp-buffer 
           (insert-file-contents "myfile.txt")

    (when (string-match (regexp-quote STRING) (buffer-string))
      (let ((b (copy-marker (match-beginning 0)))
        (e (copy-marker (match-end 0))))

    (comment-region b e)))))

This function works and, if present, comments, in the current buffer, the string:

"(query-replace \"foo\" \"Hello\" nil (point-min) (poin-max))"

Now I'd like to do the same thing looping over a file that contains a list of strings, separated by 2 newlines, e.g.

(query-replace "foo" "Hello" nil (point-min) (poin-max))

(query-replace "bar" "World" nil (point-min) (poin-max))

(insert "foo\n")

(insert "bar\n")

Alternatively, and this should be my first choice, I could use an arbitrary string boundary to allow newlines in my strings, e.g..

♦(query-replace "foo" 
           "Hello" nil (point-min) (poin-max))♦

♦(query-replace "bar" 
           "World" nil (point-min) (poin-max))♦

♦(insert "foo\n")♦

♦(insert "bar\n")♦

The idea is that I don't want to use any kind of escaping in the source file.

How can I do it?

  • This feels a bit convoluted, and I'm not sure I understand correctly what the output is supposed to be. I can see that the input is the contents of myfile.txt, but can you please show the resulting contents of the output buffer (as you would like it to appear)?
    – phils
    Mar 2, 2020 at 21:23
  • Ah, I see now. myfile.txt is a set of patterns, and you want to match those patterns in the current buffer (whatever that is), and comment out the matching regions.
    – phils
    Mar 2, 2020 at 21:28
  • @phils Yes. I want to comment the matching regions. I'll use it in temp-buffer. I need it to "filter" a file to ignoring/inhibiting some regions to be executed.
    – Gabriele
    Mar 2, 2020 at 21:37

1 Answer 1


The following Elisp function covers all your use-cases. You can choose two newlines as separator regexp sep. That is the default. Or you can also choose some other character as separator regexp, such as . Empty strings between two separators are removed from the list string-list of regexps matching patterns to be commented-out. So your alternative pattern file syntax should work.

The patterns are combined to one regexp through regexp-opt. You can comment all occurrences of the patterns by calling comment-string-from-file with prefix arg. Otherwise only the first occurrence of each pattern is replaced (such as your code example indicates).

(require 'cl-lib)
(defun comment-string-from-file (file &optional sep all)
  "Read patterns separated by SEP from FILE, comment out matching regions.
Comment all matches if ALL is non-nil.
Comment only first one if ALL is nil."
  (interactive "fPattern file: \nsSeparator regexp: \nP")
  (unless sep
    (setq sep "\n\n+"))
  (let* ((string (with-temp-buffer
                   (insert-file-contents file)
         (string-list (cl-remove-if
                       (lambda (str)
                         (string-match "\\`[[:space:]\n]*\\'" str))
                       (split-string string sep)))
         (re (regexp-opt string-list)))
      (goto-char (point-min))
      (while (and
              (re-search-forward re nil t))
        (let ((match (match-string 0)))
           (match-beginning 0)
           (match-end 0))
          (unless all
            (setq string-list (cl-remove match string-list :test #'string-equal)
                  re (regexp-opt string-list))))))))
  • Thank you. I'll study it carefully! Do I need a common lisp package?
    – Gabriele
    Mar 2, 2020 at 23:39
  • @GabrieleNicolardi I have added (require 'cl-lib). That is all you need from cl.
    – Tobias
    Mar 2, 2020 at 23:43
  • [[:space:]\n] could probably also be [[:blank:]], and (lambda (str) (string-match ...)) could probably be #'string-blank-p from subr-x.el.
    – Basil
    Mar 3, 2020 at 10:34
  • @Basil No, [[:blank:]] matches horizontal whitespace. Newline is explicitly excluded: unicode.org/reports/tr18/tr18-19.html#blank
    – Tobias
    Mar 3, 2020 at 10:53
  • @Tobias Oops, right you are. In that case shouldn't you also include \r, as per string-blank-p?
    – Basil
    Mar 3, 2020 at 11:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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