Perbedaan antara setq dan setq-default di Emacs Lisp

89

Saya punya pertanyaan tentang Emacs Lisp. Apa perbedaan antara setq dan setq-default ?

Tutorial mengatakan setq berlaku di buffer lokal sementara setq-default memengaruhi semua buffer.

Misalnya, jika saya menulis (setq a-var a-vars-value) di init.el , saya temukan setelah memulai Emacs dan membuka buffer baru, a-var juga ada di sana dan nilainya adalah nilai -vars . Saya pikir itu tidak seharusnya ada di sana. Sepertinya tidak ada perbedaan antara setq dan setq-default .

Apakah ada yang salah dengan pemahaman saya?

Sebagai contoh:

  1. Saya menulis (setq halo 123) di file init.el , dan saya menjalankan emacs abuffer di shell, lalu saya memasukkan "hello Cx Ce" , itu menunjukkan "123". Hal yang sama terjadi ketika saya menjalankan ini di semua buffer baru.

  2. Saya menulis (setq tab-width 4) di file init.el. Ketika saya menjalankan Cx Ce lebar-tab , itu menunjukkan "8" (Mode saat ini adalah 'Teks'). Namun, ketika saya menggunakan (setq-default tab-width 4) , itu menunjukkan "4". Saya tidak bisa menjelaskan fenomena ini.

ruanhao
sumber

Jawaban:

102

Beberapa variabel di Emacs adalah "buffer-local", yang berarti bahwa setiap buffer diizinkan untuk memiliki nilai terpisah untuk variabel tersebut yang menggantikan default global. tab-widthadalah contoh yang baik dari variabel buffer-local.

Jika suatu variabel adalah buffer-local, maka setqset nilai lokalnya di buffer saat ini dan setq-defaultset nilai default global.

Jika variabel tidak buffer-lokal, kemudian setqdan setq-defaultmelakukan hal yang sama.

Dalam kasus Anda 2, (setq tab-width 4)setel nilai buffer-lokal tab-widthke 4 di buffer saat ini, biarkan nilai default global tab-widthmasih 8, jadi ketika Anda mengevaluasi tab-widthdi buffer lain yang tidak memiliki nilai lokal, Anda melihat 8. Kemudian, ketika Anda menyetel nilai default ke 4, buffer tersebut mengambilnya, karena masih tidak memiliki nilai lokal.

dfan
sumber
ketika I (set tab-width 4), dan mengevaluasinya, selalu 8 di setiap buffer. Saya tidak tahu kenapa. Sepertinya itu tidak berpengaruh. Tetapi ketika saya menggunakan (sets-default tab-width 4), itu berlaku di setiap buffer. Saya juga tidak tahu kenapa :(
ruanhao
(setq tab-width 4)berlaku di buffer tempat Anda mengevaluasi ekspresi; jika Anda mengevaluasinya di *scratch*buffer, maka periksa nilainya di buffer itu.
tripleee
1
tab-widthadalah variabel buffer-local. Jadi ketika Anda (setq tab-width 4), itu hanya diatur ke 4 di buffer saat ini. Semua buffer lainnya mempertahankan tab-widthdefault global, 8. Saat Anda (setq-default tab-width 4)mengubah default global tab-widthmenjadi 4, jadi sekarang setiap buffer yang belum didefinisikan tab-widthmemiliki default baru tersebut.
dfan
3
Iya. Lihat daftar Urutan Tindakan emacs saat Memulai . Membaca file init adalah langkah 12, dan memunculkan buffer awal adalah langkah 23.
dfan
1
@ruanhao Jika Anda (setq tab-width 4) di init.el, maka itu hanya akan berlaku untuk buffer itu (init.el). Jika Anda ingin perubahan ini diterapkan ke semua buffer baru, maka (setq-default tab-width 4) akan melakukannya. Selain itu, jika Anda ingin membuat mode untuk jenis file tertentu, Anda mungkin ingin menggunakan (setq tab-width 4) agar tidak menimpa default global.
Hemm