2010-10-26 13 views
26

Desde el poderoso PEP 8:Vim: Use textwidth más corto en los comentarios y docstrings

[P] límite de arrendamiento todas las líneas hasta un máximo de 79 caracteres. Para el flujo de bloques largos de texto (cadenas de texto o comentarios), se recomienda limitar la longitud a 72 caracteres.

Al editar el código Python en Vim, volví mi textwidth a 79, y Vim ajusta automáticamente largas líneas de código Python para mí cuando me golpeó el límite de caracteres.

Pero en los comentarios y las cadenas de texto, necesito ajustar el texto a 72 caracteres. ¿Hay alguna manera de hacer que Vim configure automáticamente textwidth en 72 cuando estoy en un comentario o docstring, y volver a configurarlo cuando termine?

+3

Pregunta muy similar: http://stackoverflow.com/questions/3475072/vim-different-textwidth-for-multiline-c-comments – adw

Respuesta

14

Por lo tanto, nunca he hecho ningún script Vim antes, pero basado en this question about doing something similar in C y this tip for checking if you're currently in a comment, he pirateado una solución.

Por defecto, este utiliza el ancho de PEP8-sugerido de 79 caracteres para las líneas normales y 72 caracteres para los comentarios, pero se los puede sustituir por let ting g:python_normal_text_width o g:python_comment_text_width las variables, respectivamente. (Personalmente, envuelvo las líneas normales a 78 caracteres.)

Deje caer a este bebé en su .vimrc y ya estará listo para empezar. Puedo empaquetar esto como un complemento más adelante.

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

¿Hay algún efecto notable en el rendimiento del uso de los grupos CursorMoved *? Utilizo un método similar, pero elegí usar el grupo au 'InsertEnter' en lugar de CursorMoved *. CursorMoved es definitivamente más refinado, pero 'InsertEnter' fue lo suficientemente fino para mí y se llama con mucha menos frecuencia. Solo quería mencionarlo como una opción, y también para verificar si nota algún problema de rendimiento con 'CursorMoved'. –

+0

@Herbert Sitz No he notado ningún problema de rendimiento con CursorMoved. Hace que este script sea más natural para (por ejemplo) reformatear las cadenas de documentos existentes, o si, como yo, eres nuevo en Vim y aún te mueves mucho mientras estás en el modo de inserción. Pero el uso de InsertEnter definitivamente atrapará los usos comunes y utilizará menos recursos. –

+1

Esto es increíble; Gracias por ponerlo junto. Me di cuenta de que en mi configuración de vim, la llamada synIDattr da como resultado "Constante", no "Cadena", cuando estoy en una cadena literal. Tuve que comparar contra eso como una opción en mi vimrc. – adrian

4

¡La respuesta aceptada es genial! Sin embargo, no es compatible con el hábito que tengo para formatear/editar comentarios: realizo mis ediciones y luego uso el comando gqj, que es esencialmente "reformatear la línea actual combinada con la siguiente". Luego presiono '.' para repetir eso para cada línea (el comando mismo avanza el cursor a la siguiente línea). No sé muy bien el lenguaje de scripting vim, por lo que alguien puede agregar soporte para esto a la respuesta aceptada. Mientras tanto, lo que he hecho es asignar una tecla de función (F6) para cambiar el textwidth a 72, formatear la línea y luego cambiar el textwidth de nuevo a 79.

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

Ahora, cuando estoy en una docstring, solo hago la edición, (ESC) y luego presiono F6 repetidamente hasta que todas las líneas estén formateadas apropiadamente.

Agregué mi comando de mapa y el script de respuesta aceptado a mi .vim/after/ftplugin/python.vim.

Cuestiones relacionadas