:set is used for internal options and handles the types of the option. It allows things like inversion of boolean options (e.g.
:set invpaste) adding and removing settings from a list (e.g.
:let, on the other hand, allows access to a plethora of changeable things in vim, including regular variables, options, registers, etc. and the value being set is the result of evaluating an expression, instead of a simple value like with
:set, which means
:let gives you access to math, string manipulation, and functions.
For example, you can
:let &dictionary=/tmp/myfile to set the option
/tmp/myfile (thus modifying the same option shown above in the
You can set a global variable with
:let g:myvar=42. The prefix you asked about provides scope. Doorknob's answer covers the scoping very well.
:let @a="Some text" to change the contents of register a to contain
Some text, which you could later paste with
"ap for example.
:let $PATH = $PATH . ":/home/me/bin" to append your own bin directory to the
PATH environment variable, which is passed to any external commands executed by Vim (this works for any environment variable).
let has some pretty powerful abilities (like
:let $MYFILE = @% to set an environment variable to the filename of the current buffer), it doesn't know that a setting is a boolean, so it doesn't offer nice accesses or error checking like
In the end, it's about using the best tool for the job. If you want to simply modify an option,
:set is your tool. If you want to move information around between registers, options, variables, or base your value on the result of an expression, then
:let is your tool.
Although you explicitly asked about Vim, another thing to note is that
:set is more common in the vi/Vim families, where
:let is less common (for example, nvi doesn't have a
let command, and viemu doesn't provide access to registers via