Estou tentando escrever um modo principal que destaque seqüências de caracteres triplas. Aqui está um exemplo mínimo reproduzível:
(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))
No entanto, isso leva a um comportamento realmente bizarro ao modificar o buffer. Aqui está o meu conteúdo do buffer:
dodgy when we put a newline after babel
"""
a
"
babel
"""
x = 1
M-x demo-mode
dá realce correto:
mas pressionar enter de repente dá o seguinte:
O que estou fazendo errado?
Não tenho uma solução, mas notei o mesmo problema com a continuação de itálico e negrito nas linhas em modo org.
—
Emacs usuário
O primeiro problema é que você está colocando a sintaxe em todos os caracteres da string, enquanto isso deve ser feito apenas para o primeiro e o último caracteres da cerca. Você pode verificar se o Emacs trata cada par de sua suposta string como um sexp, ou seja, uma única string, via
—
politza 23/06
forward-sexp
.
O segundo problema é que você não pode realmente combinar as cordas da maneira que imagina. Isso funcionaria apenas se a pesquisa fosse garantida para iniciar fora de qualquer sequência já presente no buffer. Afinal, você está combinando pares: um triplo inicia uma sequência se, e somente se, é precedida por um número par de outras triplas. Felizmente,
—
politza 23/06
syntax-ppss
acompanha isso. Veja como é feito python.el
.
@politza Estou admirado com suas habilidades no elisp! Muito obrigado :). Suas correções foram suficientes para que meu código funcionasse (veja a resposta abaixo), para que eu possa corrigir o bug no modo julia que me levou a isso.
—
Wilfred Hughes