Emacsdaemon và Emacsclient trên Mac


25

HĐH: OS X 10.9.5, Mavericks

GNU Emacs 24.3.1 (x86_64-apple-darwin13.1.0, Phiên bản Carbon 1.6.0 AppKit 1265.19) của 2014-04-03 trên Rainers-MacBook-Pro-3.local

Tôi đã cài đặt emacs thông qua homebrew từ railcat và nó hoạt động độc đáo - không có khiếu nại. Tôi không sử dụng emacs trong thiết bị đầu cuối và tôi thường khởi động nó thông qua Ứng dụng.

Như tôi đã nói - tôi hạnh phúc cho đến nay.

Tôi chỉ có một điều mà tôi đã không quản lý để làm đúng (hoạt động tốt trong linux trước đây), đó là:

  1. nhận daemon emacs bắt đầu khi đăng nhập
  2. sử dụng emacsclient để mở
  3. đóng emacsdaemon và lưu tệp al khi đăng xuất

Bất kỳ công thức nấu ăn nào có thể giúp tôi thiết lập điều này?

Đã thêm thông tin

Để bắt đầu một daemon emacs khi đăng nhập

Tôi đã tạo một Ứng dụng tự động thực thi lệnh bash

/usr/local/bin/emacs --daemon

và thêm nó vào các mục Đăng nhập hoạt động độc đáo.

Sử dụng daemon từ thiết bị đầu cuối

Tôi có thể sử dụng daemon emacs bằng cách sử dụng

emacsclient .bashrc

sẽ mở .bashrc trong phiên cuối của emacs.

Sử dụng từ GUI

Bây giờ vẫn là câu hỏi: làm thế nào tôi có thể sử dụng nó từ GUI?

Vì tôi hiểu emacsclient, tôi không thể mở emacsclient trừ khi tôi chỉ định một tệp để mở.

Tôi muốn mở GUI emacsclient và mở tất cả các tệp đã được mở trước đó ? Điều này có thể không?

Tôi phát hiện ra rằng tôi có thể sử dụng

emacsclient -c

trong một thiết bị đầu cuối để làm những gì tôi muốn - nhưng tôi có thể làm tương tự cho GUI không?


Tôi không hiểu "từ GUI" nghĩa là gì ở đây. Nó có thể có nghĩa là "nhấp đúp chuột vào một tệp trong Finder" hoặc một cái gì đó hoàn toàn khác.
tarsius

Sử dụng Trình khởi chạy ứng dụng (ví dụ: qua Spotlight)
Rainer

Trình khởi chạy ứng dụng có cho phép chọn tệp không (sau đó được mở bằng ứng dụng mặc định cho loại tệp). Hay chỉ "Ứng dụng"? emacsclientkhông phải là một ứng dụng liên quan đến OS X, chỉ Emacslà (và chỉ khi nó được cài đặt theo cách đó). Tại sao bạn không sử dụng các ràng buộc khóa hệ thống để chọn một ứng dụng / cửa sổ mở? (Sẽ không hoạt động nếu Emacs được khởi động ở chế độ daemon và chưa có khung ("cửa sổ")).
tarsius

Tôi đã định nghĩa một ứng dụng có tên Emacsclient để khởi chạy emacsclient - vì vậy ứng dụng Emacsclient ở đó. Tôi rõ ràng có thể chuyển sang một cá thể emacs đang chạy - nhưng điều này nằm ngoài mục đích, nhìn vào quy trình làm việc được mô tả ở trên.
Rainer

1
Câu hỏi này gần như hữu ích hơn câu trả lời của nó :)
Roy Truelove

Câu trả lời:


6

Tôi thực sự không phiền khi Emacs.app luôn chạy, nhưng thực tế là tôi không thể đóng cửa sổ mà không vô tình giết chết máy chủ Emacs thật khó chịu. Và ngay cả khi bạn cố gắng hết sức để giết khung hình cuối cùng, nó vẫn không cho phép bạn: "Cố gắng xóa khung hình hiển thị hoặc biểu tượng duy nhất". ... Vì vậy, chúng tôi gian lận.

Giải pháp này chỉ ẩn Emacs (như Command+ h) khi bạn cố đóng cửa sổ cuối cùng bằng cách nhấp vào nút đóng.

Thêm phần sau vào init Emacs của bạn ở đâu đó:

(defadvice handle-delete-frame (around my-handle-delete-frame-advice activate)
  "Hide Emacs instead of closing the last frame"
  (let ((frame   (posn-window (event-start event)))
        (numfrs  (length (frame-list))))
    (if (> numfrs 1)
      ad-do-it
      (do-applescript "tell application \"System Events\" to tell process \"Emacs\" to set visible to false"))))

Và thêm Emacs vào "Người dùng & Nhóm> Mục đăng nhập" và nhấp vào hộp kiểm "Ẩn".

Emacs init của bạn cũng cần gọi (start-server)ở đâu đó.

Tôi đang sử dụng emacsclienttrình bao bọc này để đưa Emacs lên phía trước:

#!/bin/sh
osascript -e 'tell application "Emacs" to activate'
exec emacsclient "$@"

Các vấn đề:

  • Kích hoạt / bỏ ẩn Emacs mang tất cả các cửa sổ ra phía trước. Điều này hơi khó chịu.
  • Nhấp vào biểu tượng Emacs trong Dock dường như đôi khi tạo ngẫu nhiên một cửa sổ mới. Nhưng không phải lúc nào cũng vậy.
  • TODO: Có thể tạo Command+ wtrên khung cuối cùng cũng ẩn Emacs?
  • MỚI với chỉnh sửa: nhấp vào biểu tượng dock khi tất cả các cửa sổ được thu nhỏ không tự động tối đa hóa một trong số chúng.

Điều này dựa trên câu trả lời của @ noaham đề xuất giảm thiểu Emacs và câu trả lời này giải thích cách móc nối cố gắng đóng cửa sổ cuối cùng.

CHỈNH SỬA:

Tìm kiếm thông qua nguồn, tôi tìm thấy "ràng buộc chính" chomac-apple-event-map các cuộc gọi mac-ae-reopen-application. mac-ae-reopen-applicationdường như để kiểm tra các khung có thể nhìn thấy và được biểu tượng hóa và bằng cách nào đó phải bỏ lỡ khung ẩn của chúng ta. Đây có thể là một lỗi.

Cách khắc phục dễ dàng là chỉ cần vô hiệu hóa ràng buộc khóa trong init của bạn:

(define-key mac-apple-event-map [core-event reopen-application] nil)

Điều này giới thiệu một lỗi nhỏ mới: nhấp vào biểu tượng dock khi tất cả các cửa sổ được thu nhỏ không tự động tối đa hóa một trong số chúng. Cách khắc phục chính xác sẽ là viết lại mac-ae-reopen-application, nhưng tôi hầu như không biết emacs và elisp.


Nếu có ai tìm ra cách dừng cửa sổ mới ngẫu nhiên (gạch đầu dòng hai) xin vui lòng cho tôi biết. Có lẽ đó là điều duy nhất còn lại khiến tôi bận tâm về thiết lập này.
cha mẹ5446

@ cha5446, xong rồi! Chỉ là hacky như sửa chữa đầu tiên, nhưng nó hoạt động.
bburky

Cảm ơn! Phần hack của nó không làm phiền tôi vì hầu hết thời gian tôi không khởi tạo Emacs từ dock.
phụ huynh5446

4

Thật không may, cổng Yamac Mitsuharu của emacs không hỗ trợ nhiều tty (xem vấn đề này ). Điều này có nghĩa là bạn không thể khởi động trình nền emacs từ thiết bị đầu cuối và khởi chạy một cửa sổ gui với emacsclient.

Đây là những gì tôi làm: Trong init.el của tôi, tôi có (server-start)và tôi khởi chạy Emacs.app khi đăng nhập. Điều khó chịu ở đây là điều này mang đến một cửa sổ mà tôi phải thu nhỏ bằng tay.

Sau đó tôi có một tập lệnh bash được gọi emacscvới sau

#!/bin/bash                                                                          
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
emacsclient -n -c

Sau đó tôi tạo một ứng dụng với applescript có chứa các mục sau

tell application "Emacs"
    activate
end tell
do shell script "~/bin/emacsc"

Điều quan trọng là truyền -ncờ cho emacsclient nếu không bạn sẽ chỉ có thể sử dụng ứng dụng emacsc để mở một máy khách tại một thời điểm. Đặt biến đường dẫn đảm bảo rằng OS X có thể tìm thấy phiên bản chính xác của emacsclient.

Nói với Emacs để "kích hoạt" đảm bảo rằng cửa sổ máy khách của bạn sẽ được khởi chạy ở phía trước.

Như tôi đã nói, điều khó chịu là bạn phải tự thu nhỏ cửa sổ emacs khi đăng nhập và sau đó đặt nó xuống trong dock. Một cách để tránh điều này là tự động "ẩn" Emacs sau khi đăng nhập nhưng sau đó kích hoạt nó sẽ khiến nó bị ẩn.


2

Tôi không chắc chắn Emacs railcat khác với công thức pha chế tại nhà thông thường như thế nào, nhưng với công thức sau bạn sẽ làm ln -sfv /usr/local/opt/emacs/*.plist ~/Library/LaunchAgents, nó sẽ chạy emacs --daemonkhi đăng nhập.

Plist được bao gồm dưới dạng tài liệu TẠI ĐÂY trong công thức . Tất cả những gì bạn cần để áp dụng nó là thay đổi đường dẫn đến ứng dụng emacs của bạn trong dòng <string>#{opt_bin}/emacs</string>.

BTW, bạn cũng có thể nhận Emacs dưới dạng ứng dụng OS X với Homebrew Emacs nếu bạn cài đặt nó với --cocoatùy chọn. (Bạn cũng sẽ cần phải chạy brew linkappssau đó, để liên kết nó /Applicationshoặc tự tạo liên kết.


1

Trên các trình nền mac, 90% thời gian, được quản lý bằng launchd . Nó có thể chạy chúng trên nhiều trình kích hoạt, bao gồm đăng nhập / đăng xuất của người dùng. Có một ứng dụng Mac khá đẹp tên là Lingon để xem và chỉnh sửa những thứ khác nhau mà launchd đang quản lý. Wiki emacs có một số đề cập về điều này, bao gồm và tập tin cấu hình ví dụ . Nhưng có vẻ như nó không giải quyết được mối quan tâm của bạn, tức là làm thế nào để tắt trình nền khi đăng xuất.


0

Tạo một ứng dụng AppleScript như thế này:

tell application "Terminal"
do shell script "/usr/local/bin/emacsclient -c"
endtell

Bạn có thể phải điều chỉnh đường dẫn hoặc bạn có thể rời khỏi đường dẫn hoàn toàn. Bạn cũng có thể sử dụng một cái gì đó fancier với khởi động daemon nếu nó chưa chạy.


@Rainer Có thành công nào với việc này không? Bạn cũng có thể muốn tìm kiếm triển khai fancier thậm chí khởi động trình nền nếu cần thiết trước khi kết nối với nó bằng emacsclient. "applescript emacsclient" cho kết quả tốt với tìm kiếm google.
tarsius

Bạn vẫn đang chờ đợi một câu trả lời tốt hơn hoặc có thể chấp nhận câu trả lời này?
tarsius
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.