2012-11-22 24 views
6

Tôi đang sử dụng một ví dụ emacs địa phương (aquamacs) để chạy các tiến trình R trên một máy chủ từ xa và tôi muốn tự động hoá quá trình kết nối với máy chủ của tôi. Quá trình này là như sau:Làm cách nào để tự động hóa các lệnh ESS (ess-remote) emacs này?

[trong emacs]

M-x shell 

[trong kết quả console]

TERM=xterm 
ssh -Y -C <my remote server> 
screen -rd [and/or] R 

[trong emacs]

M-x ess-remote 
r 

tôi phát hiện ra phương pháp chung này tại đây: http://blog.nguyenvq.com/2010/07/11/using-r-ess-remote-with-screen-in-emacs/. Các tùy chọn -Y -C cho phép bạn sử dụng xterm để xem các ô. Tôi không biết lisp và tho tôi đã googled xung quanh một chút, tôi không thể có vẻ mảnh với nhau như thế nào để thực sự xác định một chức năng để tự động hóa này (ví dụ, trong .emacs.el). Có ai thực hiện bất cứ điều gì như thế này?

Trả lời

6

Giả sử bạn chỉ muốn gọi shell trong mã. Trong Lisp, mọi thứ đều là ký hiệu tiền tố được bao quanh bởi dấu ngoặc đơn. Vì vậy, chúng ta bước này vào một bộ đệm (ví dụ, các bộ đệm đầu):

(shell) 

Di chuyển con trỏ của bạn vào cuối dòng sau khi kết thúc-Dấu ngoặc đơn, và gõ <C-x C-e> để thực thi mã Lisp. Bạn sẽ thấy rằng hàm shell được gọi.

Bây giờ, hãy biến nó thành một hàm, để chúng ta có thể thêm những thứ khác vào nó. Lệnh để tạo ra một chức năng là defun, và phải mất tên của hàm, danh sách đối số (trong ngoặc đơn), và sau đó cơ quan chức năng:

(defun automate-connection() 
    (shell)) 

Di chuyển con trỏ của bạn đến cuối của mã , nhấn <C-x C-e> và chức năng sẽ được xác định. Bạn có thể gọi nó từ Lisp bằng cách thực hiện

(automate-connection) 

Ok, bây giờ chúng ta chỉ cần đặt một số văn bản vào bộ đệm vỏ.

(defun automate-connection() 
    (shell) 
    (insert "TERM=xterm")) 

Bây giờ, khi chúng tôi chạy điều đó, chúng tôi nhận được "TERM = xterm" được đưa vào bộ đệm vỏ. Nhưng nó không thực sự gửi lệnh. Hãy thử đặt một dòng mới.

(defun automate-connection() 
    (shell) 
    (insert "TERM=xterm\n")) 

Điều đó đặt trong dòng mới, nhưng thực sự không thực hiện lệnh. Tại sao không? Hãy xem những gì nhập phím nào. Truy cập bộ đệm *shell* và nhập <C-h c>, sau đó nhấn phím trả về. (<C-h c> chạy describe-key-briefly, in tên của hàm được gọi bằng cách bấm phím đã cho). Điều đó nói rằng khi bạn nhấn RET, nó không đặt một dòng mới, nhưng thực sự gọi comint-send-input. Vì vậy, hãy làm điều đó:

(defun automate-connection() 
    (shell) 
    (insert "TERM=xterm") 
    (comint-send-input)) 

Bây giờ, khi bạn chạy `(tự động kết nối) từ bất kỳ mã Lisp nào, bạn sẽ nhận được thông báo đã gửi. Tôi để nó như một bài tập để người đọc thêm các lệnh khác của bạn.

Nhưng hãy đợi! Chúng ta không thực sự làm, đúng không? Tôi giả sử bạn không muốn chuyển sang bộ đệm đầu Lisp, nhập (automate-connection), sau đó đánh giá mã đó. Bạn có thể chỉ muốn gõ, và gọi nó là một ngày.Bạn không thể làm điều đó theo mặc định với hàm chúng ta vừa tạo. May mắn thay, nó đơn giản để cho phép điều đó: chỉ cần thêm một cuộc gọi đến (interactive) trong chức năng của bạn:

(defun automate-connection() 
    (interactive) 
    (shell) 
    (insert "TERM=xterm") 
    (comint-send-input)) 

Bây giờ bạn có thể gọi nó như bạn muốn, và nó sẽ mở *shell* đệm, đặt trong văn bản, và nói Emacs nói với shell để chạy văn bản đó.

+0

điều này cực kỳ hữu ích, cảm ơn. Bây giờ tôi có: '(defun tự động kết nối() (tương tác) (shell) (chèn" TERM = xterm \ n ssh -Y -C \ n màn hình -rd ") (comint-send-input) (ess-remote) ) ' nhưng' (ess-remote) 'dường như không chạy trừ khi tôi đã có quá trình R-in-shell đang chạy. Tôi đoán tôi cần phải làm điều gì đó giữa '(comint-send-input)' và '(ess-remote)' – Solomon

Các vấn đề liên quan