1

I have a custom mode to highlight my log files. In it, I attempt to highlight strings that are surrounded by double quotes("[^"]*"). In the files, there are sometimes lines with an odd number of double quotes. This results in many lines being treated as a string, up to the next line with a double quote.

The mode is defined by

(defun my--one-line-string-p (limit)
  "Match strings, but do not cross line boundaries"

  (when (search-forward "\"" limit 'no-error)
    (backward-char 1)
    (let ((end (min limit
                  (save-excursion
                    (end-of-line)
                    (point)))))
      (when
          (search-forward-regexp "\"[^\"]*\"" end 'no-error)
;;        (message "Found match from %d to %d" (match-beginning 0) (match-end 0))
        t
        )))
  )


(defvar my-log-file-mode-font-lock-defaults
  `((
     ("\\[WARN *\\].*" . font-lock-warning-face)
     ("\\[ERROR *\\].*" . 'my-error-face)
     (my--one-line-string-p . font-lock-string-face)
     ("{[^}
]+}" . font-lock-builtin-face)
     ("\\[akka://[^]]+\\]" . font-lock-doc-face)
     ("\\([a-zA-Z0-9]+\\)=\\([-a-zA-Z0-9:]+\\)"
      (1 font-lock-variable-name-face)
      (2 font-lock-constant-face))
     )))
;; log file mode
(define-derived-mode my-log-file-mode fundamental-mode
  "Log"
  "Major mode for viewing log files"

  (setq font-lock-defaults my-log-file-mode-font-lock-defaults)
)

font-lock-multiline is nil in the buffer.

font-lock-keywords is

 (t
 (("\\[WARN *\\].*" . font-lock-warning-face)
  ("\\[ERROR *\\].*" quote my-error-face)
  (my--one-line-string-p . font-lock-string-face)
  ("{[^}\n]+}" . font-lock-builtin-face)
  ("\\[akka://[^]]+\\]" . font-lock-doc-face)
  ("\\([a-zA-Z0-9]+\\)=\\([-a-zA-Z0-9:]+\\)"
   (1 font-lock-variable-name-face)
   (2 font-lock-constant-face)))
 ("\\[WARN *\\].*"
  (0 font-lock-warning-face))
 ("\\[ERROR *\\].*"
  (0 'my-error-face))
 (my--one-line-string-p
  (0 font-lock-string-face))
 ("{[^}\n]+}"
  (0 font-lock-builtin-face))
 ("\\[akka://[^]]+\\]"
  (0 font-lock-doc-face))
 ("\\([a-zA-Z0-9]+\\)=\\([-a-zA-Z0-9:]+\\)"
  (1 font-lock-variable-name-face)
  (2 font-lock-constant-face)))

It looks like an line with an unmatched double quote should not trigger highlighting, but it does.

I have these minor modes:

Enabled minor modes: Auto-Composition Auto-Compression Auto-Encryption Blink-Cursor Desktop-Save Diff-Auto-Refine Ede Electric-Indent File-Name-Shadow Flycheck Flycheck-Color-Mode-Line Font-Lock Global-Ede Global-Flycheck Global-Font-Lock Global-Semantic-Decoration Global-Semantic-Highlight-Func Global-Semantic-Idle-Breadcrumbs Global-Semantic-Idle-Completions Global-Semantic-Idle-Local-Symbol-Highlight Global-Semantic-Idle-Scheduler Global-Semantic-Idle-Summary Global-Semantic-Stickyfunc Global-Semanticdb Jdee-Etrace Line-Number Menu-Bar Mode-Icons Mouse-Wheel Pallet Schrute Semantic Shell-Dirtrack Show-Paren Tool-Bar Tooltip Which-Function Yas Yas-Global

Is there some other variable that I need to set to prevent multi-line string highlighting?

1

If you want to prevent multi-line matching then include \n (newline character) in the characters to exclude: "[^"\n]*".

  • my--one-line-string was effectively doing that already. Even with that change, something else is still highlighting the multi-line strings. I suspect that something is hightlighting the buffer based on syntax, but I do not know what. – Troy Daniels Nov 4 '16 at 22:13
0

The solution is to disable syntactical highlighting. Even though the regular expression suggested by Drew and the function that I originally had used only match a single line string, the syntax table will find multi-line strings.

To disable this, you need to set font-lock-keywords-only in the buffer. The way to do this that works is as the second element of font-lock-defaults.

(defvar my-log-file-mode-font-lock-defaults
  `((
     ("\\[WARN *\\].*" . font-lock-warning-face)
     ("\\[ERROR *\\].*" . 'my-error-face)
     (my--one-line-string-p . font-lock-string-face)
     ("{[^}
]+}" . font-lock-builtin-face)
     ("\\[akka://[^]]+\\]" . font-lock-doc-face)
     ("\\([a-zA-Z0-9]+\\)=\\([-a-zA-Z0-9:]+\\)"
      (1 font-lock-variable-name-face)
      (2 font-lock-constant-face))
     )
     t ;; <---- This is the addition
))

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.