Ich versuche, einen Dur-Modus zu schreiben, der dreifach zitierte Zeichenfolgen hervorhebt. Hier ist ein minimal reproduzierbares Beispiel:
(defconst demo-triple-quoted-string-regex
(rx "\"\"\""
;; After the delimiter, we're a sequence of
;; non-backslashes or blackslashes paired with something.
(*? (or (not (any "\\"))
(seq "\\" anything)))
"\"\"\""))
(defun demo-stringify-triple-quote ()
"Put `syntax-table' property on triple-quoted strings."
(let* ((string-literal (match-string 0))
(string-start-pos (- (point) (length string-literal)))
(string-end-pos (point)))
(unless (nth 4 (syntax-ppss)) ;; not inside comment
(put-text-property string-start-pos string-end-pos
'syntax-table (string-to-syntax "|")))))
(defconst demo-syntax-propertize-function
(syntax-propertize-rules
(demo-triple-quoted-string-regex
(0 (ignore (demo-stringify-triple-quote))))))
(define-derived-mode demo-mode prog-mode "Demo"
"Major mode showing stack overflow question."
(set (make-local-variable 'font-lock-defaults) '(()))
(set (make-local-variable 'syntax-propertize-function)
demo-syntax-propertize-function))
Dies führt jedoch zu einem wirklich bizarren Verhalten beim Ändern des Puffers. Hier ist mein Pufferinhalt:
dodgy when we put a newline after babel
"""
a
"
babel
"""
x = 1
M-x demo-mode
gibt die richtige Hervorhebung:
Wenn Sie jedoch plötzlich die Eingabetaste drücken, wird Folgendes angezeigt:
Was mache ich falsch?
font-lock
syntax-highlighting
Wilfred Hughes
quelle
quelle
forward-sexp
.syntax-ppss
verfolgt dies. Schauen Sie sich an, wie es gemacht wirdpython.el
.Antworten:
Dank Politza und
python-syntax-stringify
mit Edebug habe ich das geschafft. Die Änderungen waren:|
sollte nur auf das erste und letzte Zeichen in der dreifach zitierten Zeichenfolge angewendet werden.Arbeitscode:
quelle
ppss
imlet*
und verwenden diesen Wert dann nie?