Vim: commento automatico in una nuova riga


9

Vim inserisce automaticamente un commento quando inizio una nuova riga da una riga commentata, perché ho impostato formatoptions=tcroql. Ad esempio (il cursore è *):

// this is a comment*

e dopo aver colpito <Enter>(modalità inserimento) o o(modalità normale) mi rimane:

// this is a comment
// *

Questa funzione è molto utile quando si scrivono lunghi commenti a più righe, ma spesso voglio solo un commento a riga singola. Ora, se voglio terminare la serie di commenti, ho diverse opzioni:

  • colpire <Esc>S
  • colpito <BS>tre volte

Entrambi offrono tre sequenze di tasti, prese insieme a <Enter>ciò significano quattro sequenze di tasti per una nuova linea, che penso sia troppo. Idealmente, vorrei solo colpire <Enter>una seconda volta per essere lasciato con:

// this is a comment
*

È importante che la soluzione funzioni anche con diversi livelli di rientro, ad es

int main(void) {
    // this is a comment*
}

colpire <Enter>

int main(void) {
    // this is a comment
    // *
}

colpire <Enter>

int main(void) {
    // this is a comment
    *
}

Penso di aver visto questa funzione in alcuni editor di testo alcuni anni fa, ma non ricordo quale fosse. Qualcuno è a conoscenza di una soluzione che farà questo per me in Vim? Anche i puntatori nella giusta direzione su come implementare la mia soluzione sono i benvenuti.


3
È possibile utilizzare ctrl-u in modalità inserimento per eliminare i marcatori di commento inseriti automaticamente in un accordo chiave.
Etan Reisner,

1
@EtanReisner in realtà è meglio, ma ancora una battitura di tasto troppo per me dato che è un caso d'uso così comune :)
Patrick Oscity

Hai suggerito di voler poter premere nuovamente Invio per ottenere il comportamento desiderato ma ctrl-u è troppo? Potresti provare a mappare <enter> <enter> in modalità insert per eseguire automaticamente il ctrl-u per te, ma ciò introdurrebbe un ritardo se premi mai <enter> solo una volta (senza colpire nient'altro).
Etan Reisner,

Bene, inoltre, dovrebbe attivarsi solo se la riga commentata è vuota. È inoltre inaccettabile un ritardo notevole quando si preme <Invio>.
Patrick Oscity,

Ritarderò solo se non premerai nessun altro tasto credo poiché Vim dovrà aspettare per assicurarsi che non stai ancora programmando di premere un altro tasto. Potresti usare una funzione per eseguire anche quel controllo, anche se potrebbe non essere particolarmente semplice.
Etan Reisner,

Risposte:


4

Prova questo:

function! EnterEnter()
  if getline(".") =~ '^\s*\(//\|#\|"\)\s*$'
    return "\<C-u>"
  else
    return "\<CR>"
  endif
endfunction

imap <expr> <CR> EnterEnter()

Grazie sembra fantastico! Proverò quando torno a casa. Conosci un modo per estendere la regex per abbinare il linguaggio dei marcatori di commento in modo indipendente? Le informazioni dovrebbero essere lì nei file di sintassi o qualcosa del genere. Forse posso sfruttare la funzione di sintassi per questo ...
Patrick Oscity,

Voglio dire in C dovrebbe corrispondere a // e / * e * (commenti su più
righe

Ovviamente, questa funzione non è affatto generica. Vedi :h 'comment'e :h format-comment'.
romainl

Funzione modificata per funzionare con il #rubino e il "vimscript oltre al classico //. Non ha davvero senso fare nulla per i *commenti multilinea in stile C perché deve finire */comunque.
romainl

Hmm, forse <CR><CR>potrebbe essere usato per finire il commento multilinea ...
Romainl

3

Ho esteso la risposta di @ romainl al lavoro con linguaggi arbitrari generando la regex da Vim &commentstring:

function! s:IsOnlyComment(getlineArg)
  let commentRegex='^\s*'.substitute(&commentstring,'%s','\\s*','').'$'
  return strlen(matchstr(getline(a:getlineArg), commentRegex)) > 0
endfunction

function! SmartEnter()
  if s:IsOnlyComment('.')
    return "\<Esc>S"
  else
    return "\<CR>"
  endif
endfunction

inoremap <expr> <CR> SmartEnter()

Tuttavia, non riesco a rimappare <CR>affatto, questo non funzionerà. Per ora, uso <CR><CR>fino a quando questo problema non sarà risolto.


1
Perché <Esc>S? <C-u>fa lo stesso senza uscire dalla modalità di inserimento. Comunque, ho avuto una funzione personalizzata che ha fatto un sacco di cose <CR>e l'ho rinominata SmartEnter()proprio ieri dopo aver pubblicato la mia risposta ;-). Inoltre non sono sicuro che &commentstringsia la scelta giusta in quanto generalmente contiene solo una forma e può essere "linewise" o "blockwise" ( /*%s*/in C, //%sin Javascript, ecc.).
romainl

2

Rimuovi r da 'formatoptions. Ecco cosa fa quell'opzione. Disattivarlo significa che non farai mai vim farlo per te, il che significa che dovrai aggiungere i marcatori di commento principali quando li vuoi davvero ma questo è il compromesso.


2
Voglio davvero che Vim aggiunga i marcatori di commento per me, adoro questo. Ma voglio anche un modo rapido per uscire dal commento. Grazie per la tua risposta però.
Patrick Oscity,

Per il comando 'o' in modalità normale, è necessario rimuovere 'r' daformatoptions
idoneo il
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.