在注释和文档字符串中使用更短的文本宽度

31 投票
2 回答
3824 浏览
提问于 2025-04-16 06:07

来自强大的 PEP 8

[P]lease limit all lines to a maximum of 79 characters. For flowing long blocks of text (docstrings or comments), limiting the length to 72 characters is recommended.

在用Vim编辑Python代码时,我把我的 textwidth 设置为79,这样当我输入的代码行超过79个字符时,Vim会自动换行。但是在注释和文档字符串中,我需要把文本限制在72个字符以内。

有没有办法让Vim在我写注释或文档字符串时自动把 textwidth 设置为72,然后在我完成后再改回79呢?

2 个回答

7

这个被接受的回答非常好!不过,它并没有支持我习惯的评论格式化/编辑方式:我会先进行编辑,然后使用 gqj 命令,这个命令的意思是“重新格式化当前行和下一行”。接着我按 '.' 键来重复这个操作,直到每一行都处理完(这个命令会自动把光标移动到下一行)。我对 vim 的脚本语言不太熟悉,所以可能有人能在这个被接受的回答中添加对这个功能的支持。与此同时,我做了一个小调整,把功能键 F6 映射为将文本宽度改为 72,格式化当前行,然后再把文本宽度改回 79。

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

现在,当我在文档字符串中时,我只需进行编辑,按下 (ESC),然后不断按 F6,直到所有行都格式化好为止。

我把我的映射命令和被接受的回答中的脚本添加到了我的 .vim/after/ftplugin/python.vim 文件里。

18

我之前从来没有做过Vim脚本,但根据这个关于在C语言中做类似事情的问题这个检查你当前是否在注释中的技巧,我拼凑了一个解决方案。

默认情况下,这个解决方案使用PEP8建议的宽度:普通行是79个字符,注释是72个字符。不过,你可以通过设置g: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

撰写回答