2010-10-26 57 views
26

短文本宽度从强大PEP 8Vim的:使用在注释和文档字符串

[P]租用期限所有线路为最多79个字符。为了流动长文本块(文档或注释),建议将长度限制为72个字符。

当编辑在Vim的Python代码,我把我的textwidth到79,而当我打的字符数限制的Vim自动换行的Python代码排长对我来说。

但是在评论和文档字符串中,我需要将文本换成72个字符。有什么办法让Vim自动将textwidth设置为72,当我处于评论或文档字符串中时,并在完成后将其设置回来?

+3

非常类似的问题:http://stackoverflow.com/questions/3475072/vim-different-textwidth-for-multiline-c-comments – adw 2010-10-26 20:29:43

回答

14

所以,我从来没有做过任何Vim脚本编写,但基于this question about doing something similar in Cthis tip for checking if you're currently in a comment,我已经在一起解决了一个问题。

默认情况下,使用的79个字符正常线路和72个字符征求意见的PEP8,建议宽度,但是你可以通过letg:python_normal_text_widthg:python_comment_text_width变量,分别覆盖它们。 (我个人用78个字符换行)

把这个宝贝放在你的.vimrc你应该很好走。我可能会在稍后将其封装为插件。

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

使用CursorMoved *组对性能有任何明显的影响吗?我使用类似的方法,但选择使用'InsertEnter'au组而不是CursorMoved *。 CursorMoved肯定是更细粒度的,但'InsertEnter'对我来说足够精细,而且被调用的次数要少得多。只是想提及它作为一个选项,并且还要检查您是否注意到“CursorMoved”的任何性能问题。 – 2010-10-27 03:51:34

+0

@Herbert Sitz我没有注意到使用CursorMoved的任何性能问题。它使得这个脚本更加自然(例如)重新格式化现有的文档字符串,或者像我一样,你是Vim的新手,并且在插入模式下仍然移动很多。但是使用InsertEnter肯定会捕获常见用途,并使用更少的资源。 – 2010-10-27 19:04:03

+1

这太棒了;谢谢你把它放在一起。我注意到,在我的vim设置中,当我在字符串文字中时,synIDattr调用的结果是“常量”,而不是“字符串”。我必须将其作为我vimrc中的一个选项进行比较。 – adrian 2011-09-15 22:25:37

4

接受的答案很好!但是,它并不支持我对格式化/编辑注释的习惯:我编辑并使用gqj命令,本质上是“重新组合下一行的当前行”。然后我打了'。'为每一行重复该操作(命令本身将光标移至下一行)。我不太了解vim脚本语言,因此有人可能会将此支持添加到接受的答案中。在此期间,我所做的是图个功能键(F6)的文本宽度更改为72,格式化线,然后更改文本宽度回79

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

现在,当我在我docstring,我只需进行编辑(ESC),然后重复按F6,直到所有行都格式正确。

我将我的地图命令和接受的答案脚本添加到了我的.vim/after/ftplugin/python.vim。