openlang

Мой init поменял fill-column ровно в одном буфере

(setq fill-column 72) годами лежал у меня в init, и только сейчас выяснилось, что M-q в свежем буфере по-прежнему переносит на 70. (В *scratch* переносит на 72, отсюда и самообман.)

fill-column автоматически становится локальной для буфера. Если задать такую переменную через setq, значение по умолчанию не меняется. Создаётся локальное значение в том буфере, который текущий, когда строка выполняется. Во время init это обычно *scratch*, так что 72 получил *scratch*, а все остальные буферы начинали с нетронутого значения по умолчанию.

(setq fill-column 72)          ; local to the current buffer only
(setq-default fill-column 72)  ; the value new buffers start with

C-h v fill-column прямо в тексте справки пишет "Automatically becomes buffer-local when set". Эта фраза попадалась мне раз десять, но со своим init в голове не связывалась. Теперь прохожу остальной файл в поисках той же ошибки.

Разговор продолжается 8

Следуя доводам
  1. Ссылка на ответ

    Прежде чем чинить, посчитайте. Это даёт число буферов, у которых своё значение.

    (seq-count (lambda (b) (local-variable-p 'fill-column b))
               (buffer-list))

    Если ответ 1, виновата строка в init. Если больше, ещё что-то задаёт её локально, и эти буферы setq-default тоже не изменит.

  2. Ссылка на ответ

    Я держу это в голове через два вопроса по порядку. Сначала, какое значение читает новый буфер? Значение по умолчанию, значит, init должен задавать именно его. Потом, у каких буферов уже есть локальное значение? Они его сохраняют, что бы потом ни говорило значение по умолчанию. Это похоже на атрибут класса и атрибут экземпляра в Python, где setq-default задаёт атрибут класса, а setq для автоматически локальной переменной присваивает экземпляру.

  3. Ссылка на ответ

    Аналогия держится для fill-column и ломается на соседней переменной. Возьмите обычную переменную, которую никто не помечал через make-variable-buffer-local. Если в текущем буфере нет локального значения, setq задаёт глобальное, и его видят все буферы. В Python присваивание через экземпляр всегда попадает в экземпляр. Так что поведёт ли себя setq как self.x = 1 или как Cls.x = 1, зависит от объявления где-то в другом месте исходников, и как раз о такой тихой хитрости мне бы хотелось, чтобы буфер справки продолжал громко напоминать.

  4. Ссылка на ответ

    Одно замечание о границах исправления. setq-default задаёт значение по умолчанию и не трогает уже существующие локальные значения. Он исправляет буферы, созданные после выполнения строки init, а буфер, у которого уже есть локальный fill-column, здесь *scratch*, сохраняет то, что дал ему прежний setq или режим. Чтобы получить чистый результат в работающем сеансе, устаревшее локальное значение нужно убрать через kill-local-variable в соответствующем буфере.

  5. Ссылка на ответ

    То же самое случилось со мной в буфере сообщения коммита. M-q переносил там на 70, а в *scratch* на 72, и я долго винил режим коммита, у которого локального значения не было вовсе.

  6. Ссылка на ответ

    Запуск дал 3, а не 1. *scratch* из-за строки init и ещё два буфера, где мой хук режима делал обычный setq. C-h v в одном из них тоже показывает расклад, локальное значение этого буфера и рядом глобальное, и это быстрее подсчёта, когда уже подозреваешь конкретный буфер. Хуки теперь используют setq-local, так что намерение записано там, где всё происходит.

  7. Ссылка на ответ

    Справедливо, и буфер справки действительно кричит, но только когда сам туда пойдёшь. В коде мой ответ - setq-local (он сначала делает переменную локальной, а потом задаёт её, что бы ни говорило объявление), и читателю объявление знать вообще не нужно. В init побуферные переменные теперь идут через setq-default, у остальных остался обычный setq, а рядом со странными стоит короткий комментарий.

  8. Ссылка на ответ

    Это вылезло во время проверки, только с другой стороны. Выполняю (setq-default fill-column 80) из *scratch*, чтобы посмотреть эффект, а сам *scratch* остаётся на 72 из-за локального значения, которое ему дал init. M-x kill-local-variable там, и он сразу становится 80. (Перезапуск тоже помог бы, но открытых буферов было слишком много, чтобы хотеть этого.)

Другие стороны того же вопроса

  1. Зависший тест лучше читать по дампу, а не по print

    Раньше при зависшем тесте рука сама тянулась расставить fmt.Println и запустить заново. Сейчас делаю иначе. Ставлю короткий т…

    Ответы 9go
  2. SilentlyContinue как On Error Resume Next с другим написанием

    После унаследованных рабочих книг дошло дело до унаследованных скриптов PowerShell, и там нашёлся старый знакомый в новом пал…

    Ответы 0powershell
  3. Обновляемость значит, что раскладка хранилища останется навсегда

    Слышат «прокси» и думают, что проблема неизменяемости исчезла. Она переехала. Прокси хранит состояние и пересылает вызовы чер…

    Ответы 3solidity