Vim: Какая разница между let и set?

Какая разница между let и set в редакторе vim?

Я всегда задавался вопросом, почему они оба существуют?

Кроме того, мне было бы интересно услышать его исторический фон.

Ответ 1

:set предназначен для установки параметров :let для назначения значения переменной.

Бывает так, что значение для опции связано с именем опции, предшествующей & (конструкция &option-name тогда ведет себя очень похоже на "обычные" переменные). Итак, следующие эквиваленты:

:set  tw=40
:let &tw=40

Но, например, присвоение 50 глобальной переменной foo (:let g:foo=50) не может быть достигнуто с помощью команды :set (поскольку g: foo - это переменная, а не опция).

Некоторые параметры имеют логическое значение. При их настройке не требуется значение (как в :set noic и наоборот :set ic).

Ответ 2

Set - это более удобный интерфейс, специализированный для опций

например.

:verbose set

чтобы отобразить все действующие параметры.

:set tw=40

Будет работать как сокращение для set textwidth=40

:set wrap&

Будет установлено значение по умолчанию для опции wrap

:set nowrap

Отсоедините опцию

:set wrap!

Переключает опцию

Самое главное,

:set Tab #, чтобы получить вкладку!

Немногие из вышеперечисленных могут (легко) быть достигнуты с помощью let.

Ответ 3

Расширяя то, что люди писали о :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>

Ответ 4

Это очень просто. Как сказали люди set для опций и работает лучше из-за ограничения. Также set - это историческая команда, которую используют все версии vi для установки своих опций. Большинство (всех?) Других версий vi не имеют let.

Но, возможно, самое главное, что set работает во всех версиях vim, команда let может быть опущена при компиляции vim. Стандартные сборки tiny и small делают это.

Если он отсутствует let, вы получите сообщение об ошибке:
E319: Sorry, the command is not available in this version

Примечание: if и endif не реализованы ни в vim.tiny, но в этом случае команды не выдают ошибку, вместо этого все между двумя командами пропускается INCLUDING else.

Ответ 5

:set работает только с параметрами, а отдать ответ демонстрирует несколько хороших примеров использования.

:let, с другой стороны, может делать почти все, что может сделать :set, и многое другое. Он может назначить значение

  • переменная, например. let vi = 'vim'
  • вариант, например. let &tw = 40
  • регистр, например. let @a = $HOME . '/vimfiles'
  • переменная среды, например. let $NOTHING = 'NOTHING'

Другое существенное отличие состоит в том, что правая часть :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 vs :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 
    

    vs

    :let [&et, &sw, &sts] = [0, 4, 4]
    
  • установить глобальную опцию: setglobal et vs let &g:et = 1

  • установить локальную опцию: setlocal et vs let &l:et = 1

Подробнее см. :h :set и :h :let


TL;DR

:set работает только с параметрами, но синтаксис намного проще. :let работает не только с параметрами, но и с переменными, регистрами и переменными среды. В отличие от :set, правая часть :let является выражением.