Come posso rilevare se il personaggio attuale è un personaggio di commento per quella modalità principale?


12

Sto lavorando a questa piccola funzione che porta la riga successiva alla riga corrente. Voglio aggiungere una funzionalità in modo che se la riga corrente è un commento di riga e la riga successiva è anche un commento di riga, i caratteri del commento vengono rimossi dopo l'azione "pull-up".

Esempio:

Prima

;; comment 1▮
;; comment 2

chiamata M-x modi/pull-up-line

Dopo

;; comment 1▮comment 2

Nota che i ;;personaggi vengono rimossi prima comment 2.

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      (while (looking-at "/\\|;\\|#")
        (delete-forward-char 1))
      (when (looking-at "\\s-")
        (delete-forward-char 1)))))

La funzione di cui sopra funziona, ma per il momento, a prescindere dal maggiore-mode, si prenderà in considerazione /o ;o #come un carattere di commento: (looking-at "/\\|;\\|#").

Vorrei rendere questa linea più intelligente; specifico della modalità principale.

Soluzione

Grazie alla soluzione di @ericstokes, credo che il seguito ora copra tutti i miei casi d'uso :)

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      ;; Delete all comment-start or space characters
      (while (looking-at (concat "\\s<" ; comment-start char as per syntax table
                                 "\\|" (substring comment-start 0 1) ; first char of `comment-start'
                                 "\\|" "\\s-")) ; extra spaces
        (delete-forward-char 1)))))

Vuoi che sia abbastanza intelligente da gestire diversi caratteri di inizio e fine dei commenti e commenti multi-carattere (ad es. C /* ... */)?
— erikstokes

No, era tutto ciò di cui avevo bisogno. Grazie!
— Kaushal Modi,

@erikstokes Per curiosità, come gestiresti i commenti in stile C?
— Pradhan,

Questa soluzione funziona anche con i commenti su più righe, non è necessario eseguire operazioni speciali perché non è necessario eliminare alcun carattere quando si uniscono commenti su più righe.
— Kaushal Modi,

2
@Pradhan Ci sono le stringhe comment-starte comment-endche sono impostate su "/ *" e "* /" in c-mode(ma non c++-mode). E c'è c-comment-start-regexpche corrisponde a entrambi gli stili. Stai eliminando i caratteri finali e quindi l'inizio dopo l'adesione. Ma penso che la mia soluzione sarebbe quella di uncomment-region, join-linela comment-regione lasciare Emacs preoccuparsi di ciò che carattere di commento è ciò.
— erikstokes,

Risposte:


12

È possibile verificare se il carattere corrente è un commento di carattere utilizzando la tabella sintassi: (looking-at "\\s<"). La regexp \\s<corrisponderà a qualsiasi personaggio con la sintassi "comment start"; \\s>corrisponderà a quelli con sintassi "fine commento".

Un'altra opzione è la variabile comment-start, che è la stringa inserita da comment-dwime dagli amici. In genere è impostato sul carattere iniziale del commento più uno spazio.


2

C'è una soluzione molto più semplice , per favore studia il mio codice su https://github.com/redguardtoo/evil-nerd-commenter/blob/master/evil-nerd-commenter.el

Non copierò / incollerò tutto il codice qui. ma qui ci sono i punti chiave:

  • il commento ha la sua faccia font, cerca font-lock-comment-face e font-lock-comment-delimitatore-face nel mio codice

  • utilizzare la propria API di Emacs per decommentare la seconda riga, quindi unirla alla prima riga

Dovrebbe funzionare su tutte le principali modalità sensibili.

Questo trucco non è stato inventato da me. In realtà proviene dal codice di Emacs, (più specificamente, flyspell). Quindi la soluzione dovrebbe supportare qualsiasi supporto flyspell per le modalità principali


3
Per evidenziare qualcosa come un commento, richiede che la tabella della sintassi sia configurata in modo appropriato, quindi dubito che sia più intelligente dell'alternativa di guardare la sintassi.
— Wasamasa,

Ho imparato questo trucco leggendo il codice di Emacs (in realtà è flyspell), come ho documentato nel mio codice.
— chen bin,

0

Se stai cercando questa funzione per il codice lisp (Elisp, Clojure, Scheme e Common Lisp), allora dovresti provare lispy , una funzione chiamata lispy-fillfa questo tipo di cose.

Se stai cercando questa funzione per un'altra lingua, allora dovresti rebox2 (verificato per Ce Python), una funzione chiamata rebox-fillo un'altra funzione chiamata rebox-dwimfare questo tipo di cose.

Sono entrambi fantastici pacchetti, e non sono in conflitto tra loro poiché sono usati per diverse modalità principali, e sono entrambi ( lispy-fille rebox-dwim) legati M-q, piuttosto puliti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.