Sự khác biệt giữa init và config trong gói sử dụng


16

Tôi có một cấu hình như thế này:

(use-package html-mode
  :mode "\\.html\\'"
  :config
  (progn
    (add-hook 'html-mode-hook 'turn-off-auto-fill)))

Bây giờ khi tôi đi và truy cập một tệp HTML, tôi quan sát thấy auto-fillnó không bị tắt. Nhưng nếu tôi sử dụng :initthay vì :config, auto-fillbị tắt. Vì vậy, câu hỏi của tôi là khi các lệnh được :configthực hiện?

Câu trả lời:


16

Chúng khác nhau nếu gói bị hoãn, tức là không được tải cho đến khi cần. Trong trường hợp đó :initsẽ được thực thi tại thời điểm tệp emacs của bạn được đọc lần đầu tiên, nhưng :configsẽ được thực thi tại thời điểm gói thực sự được tải.

Trong ví dụ của bạn, việc sử dụng modengầm định tải gói. Bạn đã cấu hình gói được tải lần đầu tiên khi truy cập tệp html.

Bạn có thể sử dụng :demandđể đảm bảo gói luôn được tải khi khởi động, nhưng nhiều khả năng những gì bạn muốn làm ở đây là đưa hook của bạn vào :init.

Từ chuỗi tài liệu:

:init Code to run when `use-package' form evals.

Vì bạn đang đặt tệp này vào tệp người dùng của bạn, điều đó có nghĩa là nó sẽ chạy khi khởi động.

:config Runs if and when package loads.

Vì vậy, không chạy cho đến khi gói thực sự được tải ..

:defer Defer loading of package -- automatic if :commands, :bind, :bind*,  :mode or :interpreter are used.

Lưu ý danh sách những thứ tự động làm cho một gói bị hoãn lại. Về cơ bản nếu bạn cho biết use-packagecác điều kiện mà bạn cần gói này, thì nó giả định rằng bạn không muốn tải nó cho đến khi những điều kiện đó phát sinh.

:demand Prevent deferred loading in all cases.

Đảm bảo gói được tải khi khởi động, bất kể các tùy chọn khác bạn đã chỉ định.

Cập nhật

Xem lại điều này dựa trên những nhận xét gần đây ... Những gì tôi nói ở trên hoàn toàn đúng, nhưng tôi không nghĩ nó trả lời đúng câu hỏi. Vấn đề gốc ở đây thực sự html-modekhông phải là một gói, mà là một chế độ được xác định bởi gói sgml-mode. Điều này hoạt động như mong đợi đối với tôi:

(use-package sgml-mode
  :mode ("\\.html\\'" . html-mode)
  :config (add-hook 'html-mode-hook 'turn-off-auto-fill))

Trong ví dụ ban đầu, :configbiểu thức không bao giờ được đánh giá vì một gói có tên html-modekhông bao giờ được tải. Di chuyển cùng một biểu thức để :inithoạt động vì mã init luôn được đánh giá, bất kể gói có được tải hay không.



@npostavs Cảm ơn, đáng chú ý. Bản thân tôi chưa chuyển sang sử dụng gói 2.0. Đối với một điều, tôi sử dụng :idlekhá rộng rãi và chưa nhìn vào tác động của ": nhàn rỗi đã bị xóa".
glucas 30/03/2015

1
Tôi vẫn không hiểu tại sao, khi anh ta truy cập tệp HTML và kích hoạt gói để tải, auto-fillkhông bị tắt, tức là mã cấu hình không chạy. Tôi có cùng một vấn đề.
Ken Williams

@KenWilliams Vấn đề của bạn là với chế độ html? Tôi nghĩ vấn đề thực sự ở đây html-modekhông phải là một gói. Ít nhất trong phiên bản Emacs hiện tại của tôi, html-modeđược xác định trong gói sgml-mode. Vì vậy, nếu bạn bảo use-packagephải làm gì đó khi gói có tên html-modeđược tải thì mã đó không bao giờ chạy vì không có gói nào được tải. Bạn cần đặt thiết lập chế độ html trong một (use-package sgml-mode ....).
glucas

Xin lỗi - vấn đề của tôi là với org-mode, không html-mode. Một vấn đề tương tự là gói được gọi org-mode, nhưng gói ELPA được gọi org. Có lẽ đó là nhầm lẫn nó (hoặc tôi)?
Ken Williams

7

Ví dụ này làm cho tôi dễ dàng hiểu được sự khác biệt giữa :init:config. Hãy lấy một ví dụ về ace-windowgói (nhưng đây có thể là bất kỳ gói nào). Đặt cái này trong init.eltập tin của bạn :

(use-package ace-window
  :ensure t
  :defer t
  :config
  (progn
    (message "ace window: hello world")))

Bây giờ hãy mở emacs của bạn và xem trong *Messages*bộ đệm để xem có hello worldtin nhắn nào không . Bạn sẽ không thể tìm thấy bất kỳ vì gói bị hoãn. Bây giờ thay đổi từ configthành init:

(use-package ace-window
  :ensure t
  :defer t
  :init
  (progn
    (message "ace window: hello world")))

Bây giờ đóng và mở lại emacs và kiểm tra *Messages*bộ đệm. Bạn sẽ thấy thông báo ace window: hello worldvì mã được chạy bất kể khi nào :initđược đưa ra. Trong trường hợp của confignó sẽ chỉ chạy khi gói đó được tải.


Điều đó giúp, chỉ là một câu hỏi phụ, sự khác biệt giữa từ khóa :init:prefacedựa trên ví dụ của bạn là gì?
tiến sĩ

@doctorate: :prefaceđược chạy ngay cả khi gói trong câu hỏi bị vô hiệu hóa trong khi :initchỉ chạy khi gói được bật.
bbenne10
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.