2010-10-26 17 views
26

Dalla possente PEP 8:Vim: utilizzare più breve textwidth nei commenti e docstring

[P] limite di locazione tutte le linee ad un massimo di 79 caratteri. Per il flusso di lunghi blocchi di testo (docstring o commenti), si consiglia di limitare la lunghezza a 72 caratteri.

Quando si modifica il codice Python in Vim, ho impostato la mia textwidth-79, e Vim avvolge automaticamente lunghe linee di codice Python per me quando ho colpito il limite di caratteri.

Ma nei commenti e nelle docstring, ho bisogno di racchiudere il testo a 72 caratteri. C'è un modo per far sì che Vim imposti automaticamente il numero da textwidth a 72 quando sono in un commento o in una docstring, e lo rimandi quando ho finito?

+3

Domanda molto simile: http://stackoverflow.com/questions/3475072/vim-different-textwidth-for-multiline-c-comments – adw

risposta

14

Quindi, non ho mai fatto nessuno script Vim, ma basato su this question about doing something similar in C e this tip for checking if you're currently in a comment, ho violato una soluzione.

Per impostazione predefinita, utilizza le larghezze PEP8-suggerito di 79 caratteri per linee normali e 72 caratteri per i commenti, ma li si può ignorare da let ting g:python_normal_text_width o g:python_comment_text_width variabili, rispettivamente. (Personalmente, mi avvolgo linee normali a 78 caratteri.)

Goccia questo bambino nel vostro Vimrc e si dovrebbe essere a posto. Potrei impacchettare questo come un plugin più tardi.

function! GetPythonTextWidth() 
    if !exists('g:python_normal_text_width') 
     let normal_text_width = 79 
    else 
     let normal_text_width = g:python_normal_text_width 
    endif 

    if !exists('g:python_comment_text_width') 
     let comment_text_width = 72 
    else 
     let comment_text_width = g:python_comment_text_width 
    endif 

    let cur_syntax = synIDattr(synIDtrans(synID(line("."), col("."), 0)), "name") 
    if cur_syntax == "Comment" 
     return comment_text_width 
    elseif cur_syntax == "String" 
     " Check to see if we're in a docstring 
     let lnum = line(".") 
     while lnum >= 1 && (synIDattr(synIDtrans(synID(lnum, col([lnum, "$"]) - 1, 0)), "name") == "String" || match(getline(lnum), '\v^\s*$') > -1) 
      if match(getline(lnum), "\\('''\\|\"\"\"\\)") > -1 
       " Assume that any longstring is a docstring 
       return comment_text_width 
      endif 
      let lnum -= 1 
     endwhile 
    endif 

    return normal_text_width 
endfunction 

augroup pep8 
    au! 
    autocmd CursorMoved,CursorMovedI * :if &ft == 'python' | :exe 'setlocal textwidth='.GetPythonTextWidth() | :endif 
augroup END 
+3

C'è qualche effetto notevole sulle prestazioni dall'uso dei gruppi CursorMoved *? Io uso un metodo simile, ma ho scelto di usare il gruppo "InsertEnter" piuttosto che CursorMoved *. CursorMoved è decisamente più a grana fine, ma "InsertEnter" era abbastanza grande per me e viene chiamato molto meno spesso. Volevo solo menzionarlo come opzione, e anche per verificare se si notano problemi di prestazioni con "CursorMoved". –

+0

@Herbert Sitz Non ho notato problemi di prestazioni con CursorMoved. Rende questo script più naturale per (ad esempio) riformattando le docstring esistenti, o se, come me, sei nuovo a Vim e ti muovi ancora molto mentre sei in modalità di inserimento. Tuttavia, l'utilizzo di InsertEnter catturerà sicuramente gli usi comuni e utilizzerà meno risorse. –

+1

Questo è fantastico; grazie per averlo messo insieme Ho notato che nel mio setup di vim, la chiamata synIDattr risulta in "Constant", non in "String", quando sono in una stringa letterale. Ho dovuto confrontarmi con questo come opzione nel mio vimrc. – adrian

4

La risposta accettata è eccezionale! Tuttavia, non supporta l'abitudine che ho per la formattazione/modifica dei commenti: eseguo le mie modifiche e quindi utilizzo il comando gqj, che è essenzialmente "riformattare la riga corrente combinata con la successiva". Poi ho colpito '.' per ripetere quello per ogni linea (il comando stesso porta il cursore alla riga successiva). Non conosco molto bene il linguaggio di scripting vim, quindi qualcuno potrebbe essere in grado di aggiungere supporto per questo alla risposta accettata. Nel frattempo, quello che ho fatto è la mappa un tasto funzione (F6) per cambiare il textwidth a 72, formattare la linea e quindi modificare il textwidth di nuovo a 79.

nmap <F6> :set textwidth=72<CR>gqj:set textwidth=79<CR> 

Ora, quando mi trovo in una docstring, faccio solo la modifica, (ESC) e poi premo F6 ripetutamente fino a quando tutte le linee sono formattate correttamente.

Ho aggiunto il mio comando map e lo script di risposta accettato al mio .vim/after/ftplugin/python.vim.