193 lines
9.1 KiB
EmacsLisp
193 lines
9.1 KiB
EmacsLisp
;;; packages.el --- ipython Layer packages File for Spacemacs
|
|
;;
|
|
;; Copyright (c) 2012-2021 Sylvain Benner & Contributors
|
|
;;
|
|
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
|
;; URL: https://github.com/syl20bnr/spacemacs
|
|
;;
|
|
;; This file is not part of GNU Emacs.
|
|
;;
|
|
;; 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.
|
|
;;
|
|
;; 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
(setq ipython-notebook-packages '(ein company))
|
|
|
|
(defun ipython-notebook/init-ein ()
|
|
(use-package ein
|
|
:init
|
|
(spacemacs/set-leader-keys "atil" 'ein:login
|
|
"atir" 'ein:run
|
|
"atis" 'ein:stop)
|
|
(spacemacs/declare-prefix "ati" "ipython notebook")
|
|
:config
|
|
(with-eval-after-load 'ein-notebook
|
|
(add-hook 'ein:notebook-mode-hook
|
|
(lambda ()
|
|
(add-to-list 'minor-mode-overriding-map-alist
|
|
`(ein:notebook-mode . ,ein:notebook-mode-map))))
|
|
(mapc
|
|
(lambda (mode)
|
|
(evil-define-minor-mode-key mode 'ein:notebook-mode
|
|
(kbd "<C-return>") 'ein:worksheet-execute-cell-km
|
|
(kbd "<S-return>") 'ein:worksheet-execute-cell-and-goto-next-km))
|
|
'(insert hybrid normal))
|
|
(evil-define-minor-mode-key 'normal 'ein:notebook-mode
|
|
"gj" 'ein:worksheet-goto-next-input-km
|
|
"gk" 'ein:worksheet-goto-prev-input-km)
|
|
(let ((bindings '(("j" ein:worksheet-goto-next-input-km)
|
|
("k" ein:worksheet-goto-prev-input-km)
|
|
("J" ein:worksheet-move-cell-down-km)
|
|
("K" ein:worksheet-move-cell-up-km)
|
|
("e" ein:worksheet-toggle-output-km)
|
|
("d" ein:worksheet-kill-cell-km)
|
|
("y" ein:worksheet-copy-cell-km)
|
|
("p" ein:worksheet-yank-cell-km)
|
|
("m" ein:worksheet-merge-cell-km)
|
|
("s" ein:worksheet-split-cell-at-point-km)
|
|
("o" ein:worksheet-insert-cell-below-km)
|
|
("O" ein:worksheet-insert-cell-above-km)
|
|
("t" ein:worksheet-toggle-cell-type-km)
|
|
("RET" ein:worksheet-execute-cell-and-goto-next-km)
|
|
("l" ein:worksheet-clear-output-km)
|
|
("L" ein:worksheet-clear-all-output-km)
|
|
("C-s" ein:notebook-save-notebook-command-km)
|
|
("C-r" ein:notebook-rename-command-km)
|
|
("x" ein:notebook-close-km)
|
|
("z" ein:notebook-kernel-interrupt-command-km))))
|
|
(apply #'spacemacs/set-leader-keys-for-minor-mode 'ein:notebook-mode
|
|
(cl-mapcan
|
|
(lambda (bind)
|
|
(if (fboundp (cl-second bind))
|
|
bind
|
|
(prog1 nil
|
|
(display-warning
|
|
'warn (format "ipython-notebook/init-ein: undefined %s"
|
|
(cl-second bind))))))
|
|
(copy-tree bindings)))
|
|
(eval (append '(spacemacs|define-transient-state
|
|
ipython-notebook
|
|
:title "EIN Transient State"
|
|
:evil-leader-for-mode (ein:notebook-mode . ".")
|
|
:bindings
|
|
("q" nil :exit t))
|
|
bindings
|
|
`(:doc ,(ipython-notebook/transient-doc bindings))))))))
|
|
|
|
(defun ipython-notebook/post-init-company ()
|
|
(add-hook 'ein:notebook-mode-hook #'spacemacs//ein-setup-company))
|
|
|
|
(defun ipython-notebook/max-by-prefix (alist)
|
|
(seq-reduce (lambda (lst1 lst2) (if (> (cl-second lst1)
|
|
(cl-second lst2))
|
|
lst1 lst2))
|
|
(cdr alist) (car alist)))
|
|
|
|
(defun ipython-notebook/count-by-prefix (alist)
|
|
(mapcar (lambda (lst)
|
|
(cons (car lst) (list (length (cdr lst)))))
|
|
alist))
|
|
|
|
(defun ipython-notebook/commands-by-prefix-alist (commands)
|
|
"Return ((P1 P1-CMD1 P1-CMD2) (P2 P2-CMD1 P2-CMD2) ... )"
|
|
(let* ((commands (if (symbolp (car commands))
|
|
(mapcar #'symbol-name commands)
|
|
commands))
|
|
(upto (ipython-notebook/prefix commands))
|
|
result)
|
|
(cl-flet ((get-prefix
|
|
(command)
|
|
(intern (mapconcat #'identity
|
|
(subseq (split-string command (regexp-quote "-"))
|
|
0 (1+ upto))
|
|
"-"))))
|
|
(mapc (lambda (command)
|
|
(let ((lst (alist-get (get-prefix command) result)))
|
|
(setf (alist-get (get-prefix command) result)
|
|
(cons (intern command) lst))))
|
|
commands)
|
|
result)))
|
|
|
|
(cl-defun ipython-notebook/prefix (commands &key (separator "-") (suffix-p nil))
|
|
"Return index of first different prefix among COMMANDS if each were split on SEPARATOR.
|
|
For example, return 2 if COMMANDS are '(ein:notebook-foo ein:notebook-foo-bar)."
|
|
(let* ((commands (if (symbolp (car commands))
|
|
(mapcar #'symbol-name commands)
|
|
commands))
|
|
(split-up (mapcar (lambda (command)
|
|
(funcall (if suffix-p #'reverse #'identity)
|
|
(split-string command (regexp-quote separator))))
|
|
commands)))
|
|
(cl-loop for result from 0
|
|
for bogey = (nth result (car split-up))
|
|
if (or (null bogey)
|
|
(null (cdr split-up))
|
|
(cl-some (lambda (lst) (not (string= bogey (nth result lst))))
|
|
(cdr split-up)))
|
|
return (funcall (if suffix-p #'- #'identity) result)
|
|
end)))
|
|
|
|
(defun ipython-notebook/transient-doc (bindings)
|
|
(let* ((commands-by (ipython-notebook/commands-by-prefix-alist (mapcar #'cl-second bindings)))
|
|
(counts-by (ipython-notebook/count-by-prefix commands-by))
|
|
(max-by (ipython-notebook/max-by-prefix counts-by))
|
|
(main (cl-first max-by))
|
|
(n-main (cl-second max-by))
|
|
(n-other (apply #'+ (mapcar (lambda (lst) (if (eq (cl-first lst) main)
|
|
0 (cl-second lst)))
|
|
counts-by)))
|
|
(max-col 3)
|
|
(spread (min max-col (ceiling (/ n-main (* 1.3 n-other)))))
|
|
(main-commands (cdr (assq main commands-by)))
|
|
(other-commands (cl-mapcan #'cdr (remove-if (lambda (lst)
|
|
(eq (car lst) main))
|
|
commands-by)))
|
|
(other-from (ipython-notebook/prefix other-commands))
|
|
(other-to (ipython-notebook/prefix other-commands :suffix-p t))
|
|
(main-from (ipython-notebook/prefix main-commands))
|
|
(main-to (ipython-notebook/prefix main-commands :suffix-p t)))
|
|
(cl-flet ((get-key (command) (car (rassoc (list command) bindings)))
|
|
(massage (command from to)
|
|
(let ((toks (split-string (symbol-name command) (regexp-quote "-"))))
|
|
(mapconcat #'identity
|
|
(subseq toks from (+ (length toks) to))
|
|
"-"))))
|
|
(cl-macrolet ((rescol
|
|
(result commands from to)
|
|
`(let* ((key-width 10)
|
|
(col-width 20)
|
|
(format-str (format "%%-%ds%%-%ds" key-width col-width)))
|
|
(if-let ((command (pop ,commands)))
|
|
(let ((massaged (massage command ,from ,to)))
|
|
(setq ,result
|
|
(concat ,result
|
|
(format format-str
|
|
(format "[_%s_]^^" (get-key command))
|
|
(subseq massaged 0
|
|
(min (length massaged) col-width))))))
|
|
(setq ,result (concat ,result (format format-str "" "")))))))
|
|
(cl-loop
|
|
with result = "\n"
|
|
with betw = (make-string 1 ? )
|
|
with col = 1
|
|
if (= col spread)
|
|
do (rescol result other-commands other-from other-to)
|
|
and do (setq result (concat result "\n"))
|
|
and do (setq col 1)
|
|
else
|
|
do (rescol result main-commands main-from main-to)
|
|
and do (setq result (concat result betw))
|
|
and do (cl-incf col)
|
|
end
|
|
until (and (null other-commands) (null main-commands))
|
|
finally return result)))))
|