diff --git a/README.md b/README.md new file mode 100644 index 0000000..1fd2e0a --- /dev/null +++ b/README.md @@ -0,0 +1,90 @@ +What This Is +======= + +It's a lightweight SSH mode for Emacs. +I used this a whole lot at my last job, +which required me bouncing through lots of hops to get to a destination. +Other SSH modes were failing me here, unable to keep up with dirtrack and other things. +I just wanted a slim comint wrapper. + +Put another way: +I like Plan 9's `acme`. +If you like Plan 9's `acme`, you might enjoy this. + + +Why You Should Use This +================== + +* You have to use strange SSH implementations like like HP iLOs +* You could benefit from a client that bunches up input by line (for + instance, you have a high-latency connection and hate being 20 + keystrokes ahead of what's echoed back) +* You need an SSH implementation for Emacs that's fully debugged with + putty on Windows +* You'd like to have a working `dabbrev-expand` (`M-/`) in your shell + sessions +* You think it would be nice to have instant search over your entire + session, even if it spans multiple hosts +* You're a weirdo +* You're a fan of `cmd` in `acme` + + +Why You Should Not Use This +================= + +* You rely heavily on tab completion and can't switch to `dabbrev-expand` (`M-/`) +* You use lots of things that absolutely require a terminal emulator (like Nethack or irssi) +* You love using `more` and `less` more than you love using `cat` and Emacs built-in navigation + + +How To Use This +======== +Drop it somewhere that you can load it up. +Then, in your emacs initialization file: + + (load "neale-ssh.el") + (setq ssh/default-host "woozle.org") + (setq ssh/frequent-hosts '("woozle.org" "zork.net")) + + +Things I've Found Useful +=============== + +Using `plink`/`putty` +------------------ + +I have to work in Windows sometimes, +which means I'm using `plink.exe`. +I created an "emacs" profile in `putty` that has everything set up the way I want for `plink`. +Then I tell emacs to use it: + + (setq ssh-explicit-args (if (eq system-type 'windows-nt) '("-load" "emacs") '())) + + +Editing Remote Files +----------------- + +At some point after starting to use this, +you are going to find yourself wanting to edit a remote file, +and then you are going to scratch your head. + +You could use `cat filename`, +edit the text straight up in the ssh buffer, +then `cat > filename` to write it back out. + +I've been using `ed` a lot, +which combined with emacs editing isn't too bad +(but also not fantastic). + +A New Hope For Remote File Editing +--------------- + +I've been trying to get some key bindings set up that will: +* Dump the remote file +* Capture the dump in a new buffer +* Bind something in the new buffer to send a `cat > $original_filename` command and dump the output + +But I'm having quite a bit of trouble with Emacs dropping characters for some reason. +If you're interested in helping, +have a look at [neale-comint-edit.el](neale-comint-edit) and see what you can twiddle out of it. + diff --git a/neale-comint-edit.el b/neale-comint-edit.el new file mode 100644 index 0000000..7c314d2 --- /dev/null +++ b/neale-comint-edit.el @@ -0,0 +1,47 @@ +(put 'neale/remote-filename 'permanent-local t) +(put 'neale/remote-comint-buffer 'permanent-local t) + +(defun neale/remote-edit (filename) + (interactive "sFilename: ") + (let ((output-buffer (generate-new-buffer-name (format "remote:%s" (file-name-nondirectory filename)))) + (command (format "base64 %s" filename)) + (comint-buffer (current-buffer))) + (comint-redirect-send-command command output-buffer nil) + ;; Wait for it to finish + (while (null comint-redirect-completed) + (sleep-for 0.1)) + (with-current-buffer output-buffer + (setq-local neale/remote-filename filename) + (setq-local neale/remote-comint-buffer comint-buffer) + (base64-decode-region (point-min) (point-max)) + (normal-mode) + (local-set-key (kbd "C-c C-c") 'neale/remote-write)) + (message "Loaded"))) + +;; (defun neale/remote-write () +;; (interactive) +;; (let ((process (get-buffer-process neale/remote-comint-buffer)) +;; (filename neale/remote-filename) +;; (base64-text (base64-encode-string (buffer-string)))) +;; (with-current-buffer neale/remote-comint-buffer +;; (comint-send-string process (format "base64 -d > %s <<'@EOD'\n" filename)) +;; (comint-send-string process base64-text) +;; (comint-send-string process "\n@EOD\n")) +;; (message "Buffer written to %s " neale/remote-comint-buffer)))) + +(defun neale/remote-write () + (interactive) + (let* ((process (get-buffer-process neale/remote-comint-buffer)) + (filename neale/remote-filename) + (text (buffer-string)) + (base64-text (base64-encode-string text))) + (with-current-buffer neale/remote-comint-buffer + (comint-send-string process (format "echo ==%s\n" filename)) + (comint-send-string process (format "ed %s\n" filename)) + (comint-send-string process ",d\n") + (comint-send-string process "a\n") + (comint-send-string process text) + (comint-send-string process ".\n") + (sleep-for 0.2) ; *sigh* + (comint-send-string process "wq\n")) + (message "Buffer written to %s " neale/remote-comint-buffer))) diff --git a/neale-ssh.el b/neale-ssh.el index ff1dfa3..63bc1c9 100644 --- a/neale-ssh.el +++ b/neale-ssh.el @@ -1,10 +1,10 @@ ;; ;; ssh ;; -(defvar ssh/default-host "woozle.org" +(defvar ssh/default-host "fsf.org" "Default if you just hit enter for hostname") -(defvar ssh/frequent-hosts '("woozle.org") +(defvar ssh/frequent-hosts '("host1.fsf.org") "List of hosts to add to completion options") (defun ssh/known-hosts () @@ -78,35 +78,3 @@ Some machines (HP iLO) need this, because reasons." (start-file-process "mmb" (current-buffer) "~/work/bin/mmb" ircname) (local-set-key (kbd "C-c C-c") 'mmb-proceed))) -;; -;; Change review -;; -(defvar review-default-host "esperanza.canonical.com" - "Default review host") -(defvar review-history '() - "History of review hosts") -(defvar review-directory-alist - '(("esperanza.canonical.com" . "/srv/dns/domains")) - "Alist of directories to diff per host. - -Maps hostname to directory where reviews usually happen. -Defaults to `/etc'. -") -;; XXX: Make it so C-u will prompt for directory -;; XXX: Deal with potential need to sudo -(defun review (remote) - (interactive - (list - (completing-read (format "Remote host (default %s): " review-default-host) - (append ssh/frequent-hosts (ssh/canonical-known-hosts)) - nil nil "" 'review-history))) - (let* ((procname (concat "review " remote)) - (buffer (get-buffer-create (concat "*" procname "*"))) - (bzrdir (or (assoc-default remote review-directory-alist) "/etc"))) - (with-current-buffer buffer - (erase-buffer) - (start-process procname (current-buffer) "ssh" remote (concat "cd " bzrdir " && bzr di")) - (diff-mode) - (display-buffer (current-buffer))))) -(global-set-key (kbd "C-c r") 'review) -;; XXX: Hook this in with rcirc ".* review pl(ease|s)"