Skip to content

Instantly share code, notes, and snippets.

@jonEbird
Last active August 29, 2015 14:05
Show Gist options
  • Save jonEbird/615b0237de2540ba5592 to your computer and use it in GitHub Desktop.
Save jonEbird/615b0237de2540ba5592 to your computer and use it in GitHub Desktop.
Simulate a GNU screen setup within Emacs
;; Simulate GNU Screen within Emacs using ansi-term
;; ------------------------------
(defun term-next ()
"Go to the next terminal based on the buffer name. Will extract the
number from the buffer-name, add 1 and go to a buffer of that name if it
exists."
(interactive)
(let ((cur-buffer (buffer-name)))
(if (string-match "\\([0-9]+\\)" cur-buffer)
(let* ((n (match-string-no-properties 0 cur-buffer))
(next (int-to-string (+ (string-to-int n) 1)))
(next-buffer (replace-regexp-in-string n next cur-buffer)))
(if (get-buffer next-buffer)
(switch-to-buffer next-buffer nil t))))))
(defun term-prev ()
"Go to the previous terminal based on the buffer name. Will extract the
number from the buffer-name, subtract 1 and go to a buffer of that name if
it exists."
(interactive)
(let ((cur-buffer (buffer-name)))
(if (string-match "\\([0-9]+\\)" cur-buffer)
(let* ((n (match-string-no-properties 0 cur-buffer))
(prev (int-to-string (- (string-to-int n) 1)))
(prev-buffer (replace-regexp-in-string n prev cur-buffer)))
(if (get-buffer prev-buffer)
(switch-to-buffer prev-buffer nil t))))))
(defun my-terminals (&optional N shell inferior)
"Create a set of commonly used terminals ala GNU screen.
Will create 8 ansi shells unless you specific `N`. Can also pass
which `shell` you would like to use with /bin/bash being the
default. Finally anything but nil for `inferior` will cause us to
launch shell (the inferior shell) instead of ansi-term."
(interactive)
(let ((escape-key (kbd "C-\\"))
(started-terms '())
(times (or N 8))
(default-directory (expand-file-name "~/"))
(explicit-shell-file-name (or shell "/bin/bash")))
; Reset global key bindings around our escape-key
(global-unset-key escape-key)
(global-set-key (kbd (format "%s %s" escape-key escape-key)) 'previous-buffer)
(global-set-key (kbd (format "%s n" escape-key)) 'term-next)
(global-set-key (kbd (format "%s p" escape-key)) 'term-prev)
(dotimes (n times)
(let* ((shell-name (format "Shell %d" n))
(buffer-name (format "*%s*" shell-name)))
; "escape-key N" -> go to terminal N where 0 < N <= times
(global-set-key (kbd (format "%s %s" escape-key n))
`(lambda ()
(interactive)
(switch-to-buffer ,buffer-name nil t)))
(unless (get-buffer buffer-name)
(add-to-list 'started-terms n t)
(setenv "EMACS_PS1" (format "(\\e[1;32m%d\\e[0m) \\W $ " n))
(save-window-excursion
(if inferior
(shell buffer-name)
(ansi-term explicit-shell-file-name shell-name)))
(with-current-buffer buffer-name
(local-unset-key escape-key)))))
; Cleanup
(setenv "EMACS_PS1" "")
(if started-terms
(message (format "Started shells %s" started-terms))
(message "Your %d terms are already started" times))))
(my-terminals 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment