Compare commits
18 Commits
Author | SHA1 | Date |
---|---|---|
Allard Hendriksen | cb4f151554 | |
Allard Hendriksen | e672ca5a95 | |
Kai Harries | 155ffea48e | |
Allard Hendriksen | 3687ed7b87 | |
Allard Hendriksen | 4d222155a2 | |
Allard Hendriksen | 9bf6b35b8a | |
dkrm | 00e0de3cd7 | |
dkrm | 9cd0c05338 | |
dkrm | 9a3361f13f | |
dkrm | 867d1802b2 | |
Allard Hendriksen | 73bed0ebad | |
Allard Hendriksen | 4b5c30eea9 | |
Allard Hendriksen | 2ad983419f | |
Allard Hendriksen | 92f398cf0e | |
Allard Hendriksen | 8886f31291 | |
Allard Hendriksen | 16c59c9b18 | |
Allard Hendriksen | eab05445f2 | |
Allard Hendriksen | fb4333a59e |
61
README.org
61
README.org
|
@ -8,29 +8,62 @@ functionality can be used to document software installation, build
|
|||
instructions, and administrative tasks. The documentation can be
|
||||
tested and adjusted while it is written.
|
||||
* Installation
|
||||
Unfortunately, ob-tmux has not yet been added to melpa. You will need
|
||||
to copy the ~ob-tmux.el~ file to a directory in your ~load-path~.
|
||||
|
||||
This package is available on from [[https://melpa.org/#/ob-tmux][MELPA]].
|
||||
|
||||
If you have added MELPA to your package sources, you can install
|
||||
ob-tmux interactively
|
||||
#+BEGIN_EXAMPLE
|
||||
M-x package-install [RET] ob-tmux [RET]
|
||||
#+END_EXAMPLE
|
||||
|
||||
Alternatively, you can copy the ~ob-tmux.el~ file to a directory in
|
||||
your ~load-path~.
|
||||
** Configuration
|
||||
In your ~.emacs~ or ~.emacs.d/init.el~ file, add the following:
|
||||
#+BEGIN_SRC elisp
|
||||
(require 'ob-tmux)
|
||||
(setq org-babel-default-header-args:tmux
|
||||
'((:results . "silent") ;
|
||||
(:session . "default") ; The default tmux session to send code to
|
||||
(:socket . nil) ; The default tmux socket to communicate with
|
||||
;; You can use "xterm" and "gnome-terminal".
|
||||
;; On mac, you can use "iterm" as well.
|
||||
(:terminal . "gnome-terminal")))
|
||||
'((:results . "silent") ;
|
||||
(:session . "default") ; The default tmux session to send code to
|
||||
(:socket . nil))) ; The default tmux socket to communicate with
|
||||
|
||||
;; The tmux sessions are prefixed with the following string.
|
||||
;; You can customize this if you like.
|
||||
(setq org-babel-tmux-session-prefix "ob-")
|
||||
|
||||
;; The terminal that will be used.
|
||||
;; You can also customize the options passed to the terminal.
|
||||
(setq org-babel-tmux-terminal "xterm")
|
||||
(setq org-babel-tmux-terminal-opts '("-T" "ob-tmux" "-e"))
|
||||
; The default terminal is "gnome-terminal" with options "--".
|
||||
|
||||
;; Finally, if your tmux is not in your $PATH for whatever reason, you
|
||||
;; may set the path to the tmux binary as follows:
|
||||
(setq org-babel-tmux-location "/usr/bin/tmux")
|
||||
#+END_SRC
|
||||
|
||||
|
||||
If you use =use-package=, you can also write
|
||||
#+BEGIN_SRC elisp
|
||||
(use-package ob-tmux
|
||||
;; Install package automatically (optional)
|
||||
:ensure t
|
||||
:custom
|
||||
(org-babel-default-header-args:tmux
|
||||
'((:results . "silent") ;
|
||||
(:session . "default") ; The default tmux session to send code to
|
||||
(:socket . nil))) ; The default tmux socket to communicate with
|
||||
;; The tmux sessions are prefixed with the following string.
|
||||
;; You can customize this if you like.
|
||||
(org-babel-tmux-session-prefix "ob-")
|
||||
;; The terminal that will be used.
|
||||
;; You can also customize the options passed to the terminal.
|
||||
;; The default terminal is "gnome-terminal" with options "--".
|
||||
(org-babel-tmux-terminal "xterm")
|
||||
(org-babel-tmux-terminal-opts '("-T" "ob-tmux" "-e"))
|
||||
;; Finally, if your tmux is not in your $PATH for whatever reason, you
|
||||
;; may set the path to the tmux binary as follows:
|
||||
(org-babel-tmux-location "/usr/bin/tmux"))
|
||||
#+END_SRC
|
||||
* Usage
|
||||
You can start a new terminal window with a tmux session as follows:
|
||||
|
@ -59,6 +92,12 @@ following example, the ~:session~ argument has been changed to
|
|||
Executing this code block will add a window, ~new-window~, to your
|
||||
session.
|
||||
|
||||
You can parameterize scripts by using ~:var variable="value"~. This will add a
|
||||
line containing =variable="value"= preceding the content body.
|
||||
: #+begin_src tmux :var name="Ismael"
|
||||
: echo hello ${name}
|
||||
: #+end_src
|
||||
|
||||
You can exit your tmux session by detaching. The terminal window will
|
||||
close automatically. Ob-tmux will not detect that you have
|
||||
detached. Any commands you send will be sent to the tmux session in
|
||||
|
@ -136,10 +175,6 @@ it is already logged in remotely.
|
|||
My tmux indexes start at 1. By default, tmux window indexes start at
|
||||
zero. This might lead to problems. I have not yet checked.
|
||||
|
||||
Terminals other than xterm and gnome-terminal have not been
|
||||
tested. If you have positive or negative experiences with any other
|
||||
terminal, let me know.
|
||||
|
||||
I will try to respond within a week to any issues raised. I cannot
|
||||
promise I will fix them.
|
||||
* Contributions
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Fixed
|
||||
- Fix issue with lines containing leading minus signs "-". (Thanks to
|
||||
medranocalvo!)
|
||||
- Fix issue with lines containing trailing semicolon ";".
|
||||
### Changed
|
||||
- License language
|
||||
### Deprecated
|
||||
- Possibility to configure terminal using org-babel header arguments.
|
||||
### Added
|
||||
- Add possibility to define variables (Thanks to KaiHa!)
|
||||
- Add installation instructions for MELPA.
|
||||
- Add possibility to configure terminal and add options to the
|
||||
terminal. (Thanks to dkrm0!)
|
||||
|
||||
## [0.1.5] - 2018-07-19
|
||||
### Changed
|
||||
- Make variables defcustom
|
||||
- Rename internal functions
|
||||
|
||||
## [0.1.1] - 2018-07-17
|
||||
### Added
|
||||
- Initial release
|
||||
|
||||
[Unreleased]: https://github.com/ahendriksen/ob-tmux/compare/0.1.5...HEAD
|
||||
[0.1.5]: https://github.com/ahendriksen/ob-tmux/compare/0.1.1...0.1.5
|
||||
[0.1.1]: https://github.com/ahendriksen/ob-tmux/tree/0.1.1
|
160
ob-tmux.el
160
ob-tmux.el
|
@ -6,24 +6,24 @@
|
|||
;; Author: Allard Hendriksen
|
||||
;; Keywords: literate programming, interactive shell, tmux
|
||||
;; URL: https://github.com/ahendriksen/ob-tmux
|
||||
;; Version: 0.1.2
|
||||
;; Package-version: 0.1.2
|
||||
;; Version: 0.1.5
|
||||
;; Package-version: 0.1.5
|
||||
;; Package-Requires: ((emacs "25.1") (seq "2.3") (s "1.9.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
|
@ -43,21 +43,37 @@
|
|||
(require 'seq)
|
||||
(require 's)
|
||||
|
||||
(defvar org-babel-tmux-location "tmux"
|
||||
|
||||
(defcustom org-babel-tmux-location "tmux"
|
||||
"The command location for tmux.
|
||||
In case you want to use a different tmux than one selected by your $PATH")
|
||||
Change in case you want to use a different tmux than the one in your $PATH."
|
||||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defvar org-babel-tmux-session-prefix "org-babel-session-"
|
||||
"The string that will be prefixed to tmux sessions started by ob-tmux.")
|
||||
(defcustom org-babel-tmux-session-prefix "org-babel-session-"
|
||||
"The string that will be prefixed to tmux session names started by ob-tmux."
|
||||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defvar org-babel-tmux-default-window-name "ob1"
|
||||
"This is the default tmux window name used for windows that are not explicitly named in an org session.")
|
||||
(defcustom org-babel-tmux-default-window-name "ob1"
|
||||
"This is the default tmux window name used for windows that are not explicitly named in an org session."
|
||||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-babel-tmux-terminal "gnome-terminal"
|
||||
"This is the terminal that will be spawned."
|
||||
:group 'org-babel
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-babel-tmux-terminal-opts '("--")
|
||||
"The list of options that will be passed to the terminal."
|
||||
:group 'org-babel
|
||||
:type 'list)
|
||||
|
||||
(defvar org-babel-default-header-args:tmux
|
||||
'((:results . "silent")
|
||||
(:session . "default")
|
||||
(:socket . nil)
|
||||
(:terminal . "gnome-terminal"))
|
||||
(:socket . nil))
|
||||
"Default arguments to use when running tmux source blocks.")
|
||||
|
||||
(add-to-list 'org-src-lang-modes '("tmux" . sh))
|
||||
|
@ -75,7 +91,11 @@ Argument PARAMS the org parameters of the code block."
|
|||
(message "Sending source code block to interactive terminal session...")
|
||||
(save-window-excursion
|
||||
(let* ((org-session (cdr (assq :session params)))
|
||||
(terminal (cdr (assq :terminal params)))
|
||||
(org-header-terminal (cdr (assq :terminal params)))
|
||||
(vars (mapcar
|
||||
(lambda (y) (format "%s=\"%s\"" (cadr y) (cddr y)))
|
||||
(seq-filter (lambda (x) (eq :var (car x))) params)))
|
||||
(terminal (or org-header-terminal org-babel-tmux-terminal))
|
||||
(socket (cdr (assq :socket params)))
|
||||
(socket (when socket (expand-file-name socket)))
|
||||
(ob-session (ob-tmux--from-org-session org-session socket))
|
||||
|
@ -92,8 +112,12 @@ Argument PARAMS the org parameters of the code block."
|
|||
;; Disable window renaming from within tmux
|
||||
(ob-tmux--disable-renaming ob-session)
|
||||
(ob-tmux--send-body
|
||||
ob-session (org-babel-expand-body:generic body params)))))
|
||||
|
||||
ob-session (org-babel-expand-body:generic body params vars))
|
||||
;; Warn that setting the terminal from the org source block
|
||||
;; header arguments is going to be deprecated.
|
||||
(message "ob-tmux terminal: %s" org-header-terminal)
|
||||
(when org-header-terminal
|
||||
(ob-tmux--deprecation-warning org-header-terminal)))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ob-tmux object
|
||||
|
@ -104,20 +128,23 @@ Argument PARAMS the org parameters of the code block."
|
|||
window
|
||||
socket)
|
||||
|
||||
(defun ob-tmux--tmux-session (org-session)
|
||||
"Extract tmux session from ORG-SESSION string."
|
||||
(let* ((session (car (split-string org-session ":"))))
|
||||
(concat org-babel-tmux-session-prefix
|
||||
(if (string-equal "" session) "default" session))))
|
||||
(defun ob-tmux--tmux-window (org-session)
|
||||
"Extract tmux window from ORG-SESSION string."
|
||||
(let* ((window (cadr (split-string org-session ":"))))
|
||||
(if (string-equal "" window) nil window)))
|
||||
|
||||
(defun ob-tmux--from-org-session (org-session &optional socket)
|
||||
"Create a new ob-tmux-session object from ORG-SESSION specification.
|
||||
Optional argument SOCKET: the location of the tmux socket (only use if non-standard)."
|
||||
(defun -tmux-session (org-session)
|
||||
(let* ((session (car (split-string org-session ":"))))
|
||||
(concat org-babel-tmux-session-prefix
|
||||
(if (string-equal "" session) "default" session))))
|
||||
(defun -tmux-window (org-session)
|
||||
(let* ((window (cadr (split-string org-session ":"))))
|
||||
(if (string-equal "" window) nil window)))
|
||||
|
||||
(ob-tmux--create
|
||||
:session (-tmux-session org-session)
|
||||
:window (-tmux-window org-session)
|
||||
:session (ob-tmux--tmux-session org-session)
|
||||
:window (ob-tmux--tmux-window org-session)
|
||||
:socket socket))
|
||||
|
||||
(defun ob-tmux--window-default (ob-session)
|
||||
|
@ -174,19 +201,17 @@ automatically space separated."
|
|||
(defun ob-tmux--start-terminal-window (ob-session terminal)
|
||||
"Start a TERMINAL window with tmux attached to session.
|
||||
|
||||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(let* ((process-name (concat "org-babel: terminal")))
|
||||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(let ((start-process-mandatory-args `("org-babel: terminal"
|
||||
"*Messages*"
|
||||
,terminal))
|
||||
(tmux-cmd `(,org-babel-tmux-location
|
||||
"attach-session"
|
||||
"-t" ,(ob-tmux--target ob-session))))
|
||||
(unless (ob-tmux--socket ob-session)
|
||||
(if (string-equal terminal "xterm")
|
||||
(start-process process-name "*Messages*"
|
||||
terminal
|
||||
"-T" (ob-tmux--target ob-session)
|
||||
"-e" org-babel-tmux-location "attach-session"
|
||||
"-t" (ob-tmux--target ob-session))
|
||||
(start-process process-name "*Messages*"
|
||||
terminal "--"
|
||||
org-babel-tmux-location "attach-session"
|
||||
"-t" (ob-tmux--target ob-session))))))
|
||||
(apply 'start-process (append start-process-mandatory-args
|
||||
org-babel-tmux-terminal-opts
|
||||
tmux-cmd)))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tmux interaction
|
||||
|
@ -198,7 +223,6 @@ Argument OB-SESSION: the current ob-tmux session."
|
|||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(unless (ob-tmux--session-alive-p ob-session)
|
||||
(ob-tmux--execute ob-session
|
||||
;; TODO: set socket
|
||||
"new-session"
|
||||
"-d" ;; just create the session, don't attach.
|
||||
"-c" (expand-file-name "~") ;; start in home directory
|
||||
|
@ -211,7 +235,6 @@ Argument OB-SESSION: the current ob-tmux session."
|
|||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(unless (ob-tmux--window-alive-p ob-session)
|
||||
(ob-tmux--execute ob-session
|
||||
;; TODO: set socket
|
||||
"new-window"
|
||||
"-c" (expand-file-name "~") ;; start in home directory
|
||||
"-n" (ob-tmux--window-default ob-session)
|
||||
|
@ -223,7 +246,6 @@ Argument OB-SESSION: the current ob-tmux session."
|
|||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(when (ob-tmux--window-alive-p ob-session)
|
||||
(ob-tmux--execute ob-session
|
||||
;; TODO set socket
|
||||
"set-window-option"
|
||||
"-t" (ob-tmux--target ob-session)
|
||||
option value)))
|
||||
|
@ -239,17 +261,23 @@ Argument OB-SESSION: the current ob-tmux session."
|
|||
(ob-tmux--set-window-option ob-session "allow-rename" "off")
|
||||
(ob-tmux--set-window-option ob-session "automatic-rename" "off")))
|
||||
|
||||
|
||||
(defun ob-tmux--format-keys (string)
|
||||
"Format STRING as a sequence of hexadecimal numbers, to be sent via the `send-keys' command."
|
||||
(mapcar (lambda (c) (format "0x%x" c))
|
||||
string))
|
||||
|
||||
(defun ob-tmux--send-keys (ob-session line)
|
||||
"If tmux window exists, send a LINE of text to it.
|
||||
|
||||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(when (ob-tmux--window-alive-p ob-session)
|
||||
(ob-tmux--execute ob-session
|
||||
;; TODO set socket
|
||||
"send-keys"
|
||||
"-l"
|
||||
"-t" (ob-tmux--target ob-session)
|
||||
line "\n")))
|
||||
(let* ((hex-line (ob-tmux--format-keys line)))
|
||||
(apply 'ob-tmux--execute
|
||||
ob-session
|
||||
"send-keys"
|
||||
"-t" (ob-tmux--target ob-session)
|
||||
hex-line))))
|
||||
|
||||
(defun ob-tmux--send-body (ob-session body)
|
||||
"If tmux window (passed in OB-SESSION) exists, send BODY to it.
|
||||
|
@ -257,7 +285,9 @@ Argument OB-SESSION: the current ob-tmux session."
|
|||
Argument OB-SESSION: the current ob-tmux session."
|
||||
(let ((lines (split-string body "[\n\r]+")))
|
||||
(when (ob-tmux--window-alive-p ob-session)
|
||||
(mapc (lambda (l) (ob-tmux--send-keys ob-session l)) lines))))
|
||||
(mapc (lambda (l)
|
||||
(ob-tmux--send-keys ob-session (concat l "\n")))
|
||||
lines))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tmux interrogation
|
||||
|
@ -289,6 +319,42 @@ If no window is specified in OB-SESSION, returns 't."
|
|||
't))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Warnings
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defun ob-tmux--deprecation-warning (org-header-terminal)
|
||||
(let* ((message (format "DEPRECATION WARNING: Setting `:terminal` using org source block header arguments is deprecated.
|
||||
|
||||
Consider changing your ob-tmux configuration as follows:
|
||||
|
||||
(setq org-babel-default-header-args:tmux
|
||||
'((:results . \"\")
|
||||
(:session . \"\")
|
||||
(:terminal. \"%s\") ; <--- REMOVE THIS LINE
|
||||
(:socket . nil)))
|
||||
|
||||
;; You can now customize the terminal and its options as follows:
|
||||
(setq org-babel-tmux-terminal \"%s\")
|
||||
(setq org-babel-tmux-terminal-opts '(\"-T\" \"ob-tmux\" \"-e\"))
|
||||
; The default terminal is \"gnome-terminal\" with options \"--\".
|
||||
|
||||
If you have any source blocks containing `:terminal`, please consider removing them:
|
||||
|
||||
#+begin_src tmux :session test :terminal %s
|
||||
echo hello
|
||||
#+end_src
|
||||
|
||||
Becomes:
|
||||
|
||||
#+begin_src tmux :session test
|
||||
echo hello
|
||||
#+end_src
|
||||
|
||||
End of warning. (See *Warnings* buffer for full message)
|
||||
" org-header-terminal org-header-terminal org-header-terminal)))
|
||||
(display-warning 'deprecation-warning message :warning)
|
||||
message))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Test functions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
Loading…
Reference in New Issue