Vim: What's the difference between let and set?

:set is for setting options, :let for assigning a value to a variable.

It happens that the value for an option is linked to the name of the option prepended by a & (the &option-name construct then behaves very similar to "ordinary" variables). So, the following are equivalent:

:set  tw=40
:let &tw=40

But, for example, assigning 50 to the global variable foo (:let g:foo=50) cannot be achieved with a :set command (because g:foo is a variable and not an option).

Some options are boolean like. When setting these, no value is needed (as in :set noic and the opposite :set ic).


Set is a more user-friendly interface specialized for options

E.g.

:verbose set

to display all options in effect.

:set tw=40

Will work as a shorthand for set textwidth=40

:set wrap&

Will set the default value for option wrap

:set nowrap

Will unset the option

:set wrap!

Will toggle the option

Most importantly,

:setTab # to get tab completion!

Few of the above can (easily) be achieved with let.


:set only works with options, and sehe's answer showcases some good usage examples.

:let on the other hand can do almost everything that :set can do, plus more. It can assign a value to

  • a variable, e.g. let vi = 'vim'
  • an option, e.g. let &tw = 40
  • a register, e.g. let @a = $HOME . '/vimfiles'
  • an environment variable, e.g. let $NOTHING = 'NOTHING'

Another major difference is that the right hand side of :let is an expression, meaning you can do things like string concatenation (as seen in my register example above) and arithmetic operations (e.g. let &tw = 40 + 60). This also means that you have to quote the value if it's a string. :set on the other hand reads the value verbatim.

It's easier to use :set with options even though :let can also do most of it, Here are some comparison using sehe's examples ("n/a" means no way to do it with :let)

  • :verbose set vs n/a (don't think there's another way to list all options)
  • :set tw=40 vs :let &tw = 40 (yes, you can use the same shorthand in let too)
  • :set wrap& vs n/a
  • :set nowrap vs :let &wrap = 0 (for boolean options, 0 is false and 1 is true)
  • :set wrap! vs :let &wrap = !&wrap

A few more examples

  • print the value of an option: :set formatoptions? vs :echo &formatoptions (let doesn't print values, unlike set)
  • assigning to multiple options at the same time:

    :set et sw=4 sts=4 
    

    vs

    :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.

Tags:

Vim