From ebfc5648efdfe0eb59d18bbba8f9828c8a102ba2 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 30 May 2018 18:13:22 +0200 Subject: [PATCH] lang/org: major refactor of +ipython feature --- modules/lang/org/+babel.el | 44 +++++++ modules/lang/org/+ipython.el | 47 ------- modules/lang/org/autoload/ipython.el | 178 ++++++++++----------------- modules/lang/org/config.el | 1 - 4 files changed, 112 insertions(+), 158 deletions(-) delete mode 100644 modules/lang/org/+ipython.el diff --git a/modules/lang/org/+babel.el b/modules/lang/org/+babel.el index ccf8899a0..ea722d31c 100644 --- a/modules/lang/org/+babel.el +++ b/modules/lang/org/+babel.el @@ -50,3 +50,47 @@ string). Stops at the first function to return non-nil.") for p in params if (funcall fn (eq (car p) key)) collect p))) + + +;; +;; Plugins +;; + +(def-package! ob-ipython + :when (featurep! +ipython) + :defer t + :init + (defvar +ob-ipython-local-runtime-dir nil + "TODO") + + (setq ob-ipython-resources-dir ".ob-ipython-resrc") + + (defun +org|babel-load-ipython (language) + (and (string-match-p "^jupyter-" language) + (require 'ob-ipython nil t))) + (add-hook '+org-babel-load-functions #'+org|babel-load-ipython) + :config + (set! :popups + '("^\\*Org Src" + ((size . 100) (side . right) (slot . -1) (window-height . 0.6)) + ((quit) (select . t) (modeline))) + '("^\\*Python" + ((slot . 0) (side . right) (size . 100)) + ((select) (quit) (transient))) + '("\\*ob-ipython.*" + ((slot . 2) (side . right) (size . 100) (window-height . 0.2)) + ((select) (quit) (transient))) + '("\\*Python:.*" + ((slot . 0) (side . right) (size . 100)) + ((select) (quit) (transient)))) + ;; TODO Add more popup styles + + ;; advices for remote kernel and org-src-edit + (advice-add 'org-babel-edit-prep:ipython :override #'+org*org-babel-edit-prep:ipython) + (advice-add 'org-babel-ipython-initiate-session :override #'+org*org-babel-ipython-initiate-session) + (advice-add 'ob-ipython--create-repl :override #'+org*ob-ipython--create-repl) + (advice-add 'org-babel-execute:ipython :override #'+org*org-babel-execute:ipython) + + ;; retina resolution image hack + (when (eq window-system 'ns) + (advice-add 'ob-ipython--write-base64-string :around #'+org*ob-ipython--write-base64-string))) diff --git a/modules/lang/org/+ipython.el b/modules/lang/org/+ipython.el deleted file mode 100644 index 8c483987c..000000000 --- a/modules/lang/org/+ipython.el +++ /dev/null @@ -1,47 +0,0 @@ -;;; lang/org/+ipython.el -*- lexical-binding: t; -*- -(defvar +org-ob-ipython-resources-dir ".ob-ipython-resrc") -(defvar +ob-ipython-local-runtime-dir - (substring (shell-command-to-string (concat "jupyter --runtime-dir")) 0 -1)) -(def-package! ob-ipython - :when (featurep! +ipython) - :after (ob) - :config - (setq ob-ipython-resources-dir +org-ob-ipython-resources-dir) - ;; popup - (when (featurep! +right-popup) - (set! - :popup "^\\*Org Src" - '((size . 100) - (side . right) - (slot . -1) - (window-height . 0.6)) - '((quit) - (select . t) - (modeline))) - (set! - :popup "^\\*Python" - '((slot . 0) - (side . right) - (size . 100)) - '((select) (quit) (transient))) - (set! - :popup "\\*ob-ipython.*" - '((slot . 2) - (side . right) - (size . 100) - (window-height . 0.2)) - '((select) (quit) (transient))) - (set! - :popup "\\*Python:.*" - '((slot . 0) - (side . right) - (size . 100)) - '((select) (quit) (transient)))) - ;; advices for remote kernel and org-src-edit - (advice-add 'org-babel-edit-prep:ipython :override #'+org*org-babel-edit-prep:ipython) - (advice-add 'org-babel-ipython-initiate-session :override #'+org*org-babel-ipython-initiate-session) - (advice-add 'ob-ipython--create-repl :override #'+org*ob-ipython--create-repl) - (advice-add 'org-babel-execute:ipython :override #'+org*org-babel-execute:ipython) - ;; retina resolution image hack - (when (eq window-system 'ns) - (advice-add 'ob-ipython--write-base64-string :around #'+org*ob-ipython--write-base64-string))) diff --git a/modules/lang/org/autoload/ipython.el b/modules/lang/org/autoload/ipython.el index f5fa6eb57..4a602b6d5 100644 --- a/modules/lang/org/autoload/ipython.el +++ b/modules/lang/org/autoload/ipython.el @@ -1,5 +1,6 @@ ;;; lang/org/autoload/ipython.el -*- lexical-binding: t; -*- -;; * remote +;;;###if (featurep! +ipython) + ;;;###autoload (defun +org*org-babel-ipython-initiate-session (&optional session params) "Create a session named SESSION according to PARAMS." @@ -7,7 +8,7 @@ (error "ob-ipython currently only supports evaluation using a session. Make sure your src block has a :session param.") - (when (not (s-ends-with-p ".json" session)) + (when (not (string-suffix-p ".json" session t)) (ob-ipython--create-kernel (ob-ipython--normalize-session session) @@ -22,50 +23,34 @@ Make sure your src block has a :session param.") "Create repl based on NAME and PARAMS. If PARAMS specifies remote kernel, copy the kernel config from remote server and create a repl connecting to remote session." - (let ((cmd (s-join - " " - (ob-ipython--kernel-repl-cmd - name)))) - (if (string= "default" name) - (progn - (run-python cmd nil nil) - (format - "*%s*" - python-shell-buffer-name)) - (if (string-match - "^remote-.*ssh.json" - name) - (when (not (ignore-errors - (process-live-p - (get-process - (format - "Python:ob-ipython-%s" - name))))) - (let* ((remote (s-split "-" name)) - (remote-host (nth 1 remote)) - (remote-session (nth 3 remote))) - (+org/ob-ipython-generate-local-path-from-remote - remote-session - remote-host - params))) - (let* ((process-name (format - "Python:ob-ipython-%s" - name)) - (python-shell-prompt-detect-enabled nil) - (python-shell-completion-native-enable nil) - (buf (python-shell-make-comint - cmd - process-name - t)) - (dir (cdr (assoc :pydir params)))) - (if dir - (with-current-buffer - buf - (setq-local - default-directory - dir))) - (sleep-for 1) - (format "*%s*" process-name)))))) + (let ((cmd (string-join (ob-ipython--kernel-repl-cmd name) " "))) + (cond ((string= "default" name) + (run-python cmd nil nil) + (format "*%s*" python-shell-buffer-name)) + ((string-match "^remote-.*ssh.json" name) + (when (not (ignore-errors + (process-live-p + (get-process + (format + "Python:ob-ipython-%s" + name))))) + (let* ((remote (s-split "-" name)) + (remote-host (nth 1 remote)) + (remote-session (nth 3 remote))) + (+org/ob-ipython-generate-local-path-from-remote + remote-session + remote-host + params)))) + ((let* ((process-name (format "Python:ob-ipython-%s" name)) + (python-shell-prompt-detect-enabled nil) + (python-shell-completion-native-enable nil) + (buf (python-shell-make-comint cmd process-name t)) + (dir (cdr (assoc :pydir params)))) + (if dir + (with-current-buffer buf + (setq-local default-directory dir))) + (sleep-for 1) + (format "*%s*" process-name)))))) ;;;###autoload (defun +org*org-babel-execute:ipython (body params) @@ -73,17 +58,11 @@ create a repl connecting to remote session." This function is called by `org-babel-execute-src-block'." (message default-directory) (let ((session (cdr (assoc :session params)))) - (org-babel-ipython-initiate-session - session - params)) + (org-babel-ipython-initiate-session session params)) (ob-ipython--clear-output-buffer) (if (cdr (assoc :async params)) - (ob-ipython--execute-async - body - params) - (ob-ipython--execute-sync - body - params))) + (ob-ipython--execute-async body params) + (ob-ipython--execute-sync body params))) ;;;###autoload (defun +org/ob-ipython-generate-local-path-from-remote (session host params) @@ -92,7 +71,10 @@ This function is called by `org-babel-execute-src-block'." (substring (shell-command-to-string (concat "ssh " host " jupyter --runtime-dir")) 0 -1)) (runtime-file (concat runtime-dir "/" "kernel-" session ".json")) (tramp-path (concat "/ssh:" host ":" runtime-file)) - (tramp-copy (concat +ob-ipython-local-runtime-dir "/remote-" host "-kernel-" session ".json")) + (tramp-copy (concat (or +ob-ipython-local-runtime-dir + (substring (shell-command-to-string "jupyter --runtime-dir") + 0 -1)) + "/remote-" host "-kernel-" session ".json")) (local-path (concat "Python:ob-ipython-" @@ -105,21 +87,17 @@ This function is called by `org-babel-execute-src-block'." (python-shell-prompt-detect-enabled nil) (python-shell-completion-native-enable nil) (buf (python-shell-make-comint - (concat - ob-ipython-command - " console --simple-prompt --existing " - tramp-copy - " --ssh " - host) + (concat ob-ipython-command + " console --simple-prompt --existing " + tramp-copy " --ssh " host) (concat "" local-path) t)) (proc (get-buffer-process buf)) (dir (cdr (assoc :pydir params)))) (sleep-for 3) - (if dir - (with-current-buffer - buf - (setq-local default-directory dir))) + (when dir + (with-current-buffer buf + (setq-local default-directory dir))) (format "*%s*" proc)))) ;; * org-src-edit @@ -127,51 +105,31 @@ This function is called by `org-babel-execute-src-block'." (defun +org*org-babel-edit-prep:ipython (info) (let* ((params (nth 2 info)) (session (cdr (assoc :session params)))) - (org-babel-ipython-initiate-session - session - params)) + (org-babel-ipython-initiate-session session params)) ;; Support for python.el's "send-code" commands within edit buffers. - (setq-local - python-shell-buffer-name - (format - "Python:ob-ipython-%s" - (->> - info - (nth 2) - (assoc :session) - cdr ob-ipython--normalize-session))) - (setq-local - default-directory - (format - "%s" - (->> - info - (nth 2) - (assoc :pydir) - cdr ob-ipython--normalize-session))) + (setq-local python-shell-buffer-name + (format "Python:ob-ipython-%s" + (->> info (nth 2) (assoc :session) + cdr ob-ipython--normalize-session))) + (setq-local default-directory + (format "%s" + (->> info (nth 2) (assoc :pydir) + cdr ob-ipython--normalize-session))) (ob-ipython-mode 1) ;; hack on company mode to use company-capf rather than company-anaconda (when (featurep! :completion company) - (setq-local - company-backends - '(company-capf - company-dabbrev - company-files - company-yasnippet)) - (setq-local - company-idle-delay - nil)) + (setq-local company-backends + '(company-capf + company-dabbrev + company-files + company-yasnippet)) + (setq-local company-idle-delay nil)) (when (featurep 'lpy) (setq lispy-python-proc - (format - "Python:ob-ipython-%s" - (->> - info - (nth 2) - (assoc :session) - cdr ob-ipython--normalize-session))) - (setq lispy--python-middleware-loaded-p - nil) + (format "Python:ob-ipython-%s" + (->> info (nth 2) (assoc :session) + cdr ob-ipython--normalize-session)) + lispy--python-middleware-loaded-p nil) (lispy--python-middleware-load))) ;; * retina @@ -180,11 +138,11 @@ This function is called by `org-babel-execute-src-block'." "Return the name of high-resolution image file for FILENAME. The optional arg SCALE is scale factor, and defaults to 2." (let ((pos (or (string-match "\\.[^./]*\\'" filename) (length filename)))) - (format - "%s@%dx%s" - (substring filename 0 pos) - (or scale 2) - (substring filename pos)))) + (format "%s@%dx%s" + (substring filename 0 pos) + (or scale 2) + (substring filename pos)))) + ;;;###autoload (defun +org*ob-ipython--write-base64-string (oldfunc &rest args) (let ((file (car args)) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index f76c198cd..7c7daed71 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -8,7 +8,6 @@ (if (featurep! +babel) (load! "+babel")) (if (featurep! +capture) (load! "+capture")) (if (featurep! +export) (load! "+export")) -(if (featurep! +ipython) (load! "+ipython")) (if (featurep! +present) (load! "+present")) ;; TODO (if (featurep! +publish) (load! "+publish"))