Vim: let 和 set 有什么区别?

在 vim 编辑器中,letset有什么区别?

我一直想知道为什么他们两个都存在?

还有,我很想听听它的历史背景。

41224 次浏览

Set 是一个更加用户友好的专门用于选项的界面

例如。

:verbose set

显示所有有效的选项。

:set tw=40

将作为 set textwidth=40的速记

:set wrap&

将为选项 wrap设置 违约

:set nowrap

将取消设置选项

:set wrap!

切换的选项

最重要的是,

:setTab # 获得选项卡完成!

使用 let很少能够(容易地)实现上述目标。

:set用于设置 选择:let用于为 变量赋值。

一个选项的值恰好链接到 &预先设置的选项的名称(&option-name构造的行为非常类似于“普通”变量)。因此,以下是等价的:

:set  tw=40
:let &tw=40

但是,例如,使用 :set命令无法将50赋给全局变量 foo (:let g:foo=50)(因为 g: foo 是一个变量,而不是一个选项)。

有些选项类似于布尔值。当设置这些选项时,不需要任何值(如在 :set noic和相反的 :set ic中)。

扩展了人们关于 :let的文章,我注意到它可以用来给一个选项赋值,这是 :set不能做的。例如,该函数使用 let将全局变量 orig_tw中的值分配给 textwidth选项:

" Toggle Autowrap
" Default of 72 but can be overridden by tw settings in other vimrc files
let g:orig_tw = 72
function Toggle_autowrap_mode()
if &textwidth == 0
" Must use let instead of set here in order for g:orig_tw to be
" evaluated properly
let &textwidth = g:orig_tw
echo "Autowrap mode on tw=" . &textwidth
else
let g:orig_tw = &textwidth
set textwidth=0
echo "Autowrap mode off tw=" . &textwidth
endif
endfunction


noremap _A :call Toggle_autowrap_mode()<CR>

很简单。
正如人们所说的那样,set是一种选择,由于它的局限性,它的效果更好。此外,set是历史命令,所有版本的 vi都使用这个命令来设置它们的选项。大部分(全部?)其他版本的 vi没有 let

但是可能最重要的是,set可以在所有版本的 vim上工作,在编译 vim时可以省略 let命令。标准的 tinysmall构建可以做到这一点。

如果缺少 let,则返回错误:
E319: Sorry, the command is not available in this version

注意: ifendifvim.tiny中都没有实现,但是在这种情况下,命令不会给出错误,而是跳过了这两个命令之间的所有内容,包括 else

:set只能使用选项,而 这就是答案展示了一些很好的使用示例。

另一方面,:let可以做几乎所有 :set可以做的事情,加上更多。它可以将值赋给

  • 一个变量,例如 let vi = 'vim'
  • 选择权,例如 let &tw = 40
  • 寄存器,例如 let @a = $HOME . '/vimfiles'
  • 环境变量,例如:

另一个主要区别是 :let的右侧是 表情,这意味着您可以执行字符串串联(如上面的寄存器示例所示)和算术操作(如 let &tw = 40 + 60)。这也意味着,如果值是字符串,则必须引用它。另一方面,:set逐字读取值。

使用带选项的 :set更容易,尽管 :let也可以完成大部分工作,下面是使用 看看这些例子的一些比较(“ n/a”意味着没有办法完成 :let)

  • :verbose set vs n/a (不要认为还有其他列出所有选项的方法)
  • :set tw=40 vs :let &tw = 40(是的,你也可以在 let中使用相同的速记法)
  • :set wrap& vs n/a
  • :set nowrap:let &wrap = 0(对于布尔选项,0为 false,1为 true)
  • :set wrap! vs :let &wrap = !&wrap

再举几个例子

  • 打印选项的值: :set formatoptions? vs :echo &formatoptions(let不打印值,不像 set)
  • 同时分配给多个选项:

    :set et sw=4 sts=4
    

    :let [&et, &sw, &sts] = [0, 4, 4]
    
  • set global option: setglobal et vs let &g:et = 1

  • set local option: setlocal et vs let &l:et = 1

See :h :set and :h :let for more details


tl;dr

:set only works with options but the syntax is much simpler. :let works with not just options but also variables, registers, and environment variables. Unlike :set, the right hand side of :let is an expression.