Làm thế nào để kiểm tra xem một bộ đệm đang truy cập một tập tin?


9

Tôi muốn kiểm tra xem một số bộ đệm (giả sử, hiện tại) có đang truy cập một tệp hay không. Tôi có thể nói:

(if (buffer-file-name) ...)

nhưng nó có vẻ không thanh lịch lắm - điều tôi quan tâm chỉ là giá trị boolean, không phải tên thật của bộ đệm trong câu hỏi. Nếu buffer-file-namehàm được viết bằng Elisp, tôi có thể xem xét nguồn của nó để tìm hiểu xem nó sử dụng cái gì - nhưng nó được viết bằng C, và trong khi tôi có thể cài đặt các nguồn Emacs, tôi sợ rằng tôi sẽ không tìm thấy tên elisp cho chức năng kiểm tra những gì tôi sau đó dù sao đi nữa.

Những gì tôi cần là tôi muốn tạo một thư mục dựa trên tên của tệp bộ đệm hiện tại và hiện tại tôi đang thực hiện ít nhiều điều này:

(make-directory (if (buffer-file-name) (file-name-base) "default-dir"))

Vì vậy, cách Elisp-idiomatic để làm điều này là gì?


2
Không chắc chắn lý do tại sao bạn phản đối việc sử dụng buffer-file-namethực sự, đó là cách đúng đắn để làm điều đó (nếu bạn thực sự muốn t, hãy làm (and (buffer-file-name) t)nhưng đó là IMO xấu hơn). Việc thực hiện của nó là đọc filenametrường của cấu trúc đệm C, dù sao không thể truy cập trực tiếp từ Elisp. Cuối cùng, nó chỉ là một con trỏ là null hoặc không.
Sigma

Chà, nếu đây là cách đúng đắn, điều đó tốt với tôi. Như tôi đã nói - tôi không biết việc triển khai C và thông thường nói rằng việc hỏi tên tệp khi tôi chỉ muốn biết liệu có bất kỳ điều gì có thể là dư thừa hay không.
mbork

Và tôi đồng ý rằng (and (buffer-file-name) t)trông lạ.
mbork

Nếu bạn không nghĩ rằng đó (if (buffer-file-name) ... )là thanh lịch, thì bạn đã không được mã hóa trong thời gian dài. Nó chỉ trở nên xấu hơn từ đây.
nispio

Câu trả lời:


12

Tôi cho rằng việc sử dụng của bạn là đặc biệt thành ngữ, vì tên của bộ đệm là một giá trị boolean hoàn toàn phù hợp theo đúng nghĩa của nó. Trích dẫn từ hướng dẫn :

Có một khía cạnh quan trọng đối với bài kiểm tra sự thật trong một biểu thức if. Cho đến nay, chúng ta đã nói về 'true' và` false 'là các giá trị của các vị từ như thể chúng là các loại đối tượng Emps Lisp mới. Thực tế, 'false' chỉ là người bạn cũ của chúng ta nil. Bất cứ điều gì khác, bất cứ điều gì khác, tất cả mọi thứ đều là 'đúng'.

Để biết thêm, hãy kiểm tra mã cho clone-buffer. Tôi hy vọng bạn sẽ thấy như sau:

(interactive
 (progn
   (if buffer-file-name
       (error "Cannot clone a file-visiting buffer"))
...

Lưu ý rằng điều này đang kiểm tra ràng buộc biến buffer-file-namethay vì gọi hàm không có đối số (buffer-file-name), nhưng cả hai phải luôn hành xử giống nhau.


8

Bạn có thể sử dụng (buffer-file-name)(với đối số bộ đệm tùy chọn) hoặc biến bộ đệm cục buffer-file-namebộ. Cả hai đánh giá đến cùng một giá trị cho một bộ đệm nhất định.

Tuy nhiên, đó cách thành ngữ để làm điều này trong Elisp, vì vậy mã của bạn vẫn ổn. Nếu bạn rất muốn, bạn luôn có thể tạo một buffer-has-file-phàm bao bọc.


Cảm ơn. Có sự khác biệt đáng kể nào để chọn hàm hoặc biến không?
mbork

1
Tôi không nghĩ vậy. Nếu bạn cần chỉ ra đối số bộ đệm thì (buffer-file-name BUFFER)chắc chắn sẽ đẹp hơn (with-current-buffer BUFFER buffer-file-name), nhưng nếu không thì tôi không nghĩ vấn đề nào bạn sử dụng (và như hàm được viết bằng C, tôi nghi ngờ có sự khác biệt về hiệu năng).
phils

3

Chỉ cần sử dụng buffer-file-name. Trong Lisp chúng ta thường sử dụng một nilgiá trị không có nghĩa là đúng .

Lần duy nhất bạn có thể muốn tránh điều này là nếu chức năng tốn kém hoặc có tác dụng phụ không mong muốn.


Tôi hiểu rồi. Tôi biết rằng bất cứ điều gì không phải nillà sự thật, tôi chỉ nghĩ rằng việc lấy tên khi tôi chỉ muốn biết liệu có bất kỳ tên nào tồn tại là "tốn kém" hay không - nhưng dường như không phải vậy.
mbork

1

Từ chương "Danh sách đệm" của tài liệu:

Danh sách được trả về bởi danh sách đệm được xây dựng cụ thể; nó không phải là cấu trúc dữ liệu Emacs nội bộ và việc sửa đổi nó không ảnh hưởng đến thứ tự bộ đệm.

Vì vậy, bạn phải tìm một cách để tìm kiếm trong danh sách các bộ đệm trực tiếp. Đây là một:

  (if (string-match-p (regexp-quote "My buffer name") (format "%s" (buffer-list)))
      (message "Open")
    (message "Not open"))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.