From da2ab8333bac4eaa18e3d1b9e34a608d4aee135f Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Fri, 30 Mar 2012 10:36:52 +0200 Subject: [PATCH 1/4] implemented python-shell-send-cell + new bindings this commit implements the four functions python-shell-send-cell python-forward-cell python-backward-cell python-beginning-of-cell plus appropriate bindings Signed-off-by: Thomas Hisch --- python.el | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/python.el b/python.el index b1d5292..bab2449 100644 --- a/python.el +++ b/python.el @@ -253,6 +253,9 @@ ;; Shell interaction (define-key map "\C-c\C-s" 'python-shell-send-string) (define-key map "\C-c\C-r" 'python-shell-send-region) + (define-key map (kbd "C-") 'python-backward-cell) + (define-key map (kbd "C-") 'python-forward-cell) + (define-key map (kbd "") 'python-shell-send-cell) (define-key map "\C-\M-x" 'python-shell-send-defun) (define-key map "\C-c\C-c" 'python-shell-send-buffer) (define-key map "\C-c\C-l" 'python-shell-send-file) @@ -1166,6 +1169,55 @@ when defun is completed, else nil." (goto-char (marker-position def-marker)) (back-to-indentation)))) +(defcustom python-cell-delimiter-regex "^##" + "Delimiter used for detecting the cell boundaries of code cells/blocks." + :type 'string + :group 'python + :safe 'stringp) + +(defun python-forward-cell (&optional arg) + (interactive "p") + ;; TODO: prefix support + + (if (re-search-forward python-cell-delimiter-regex nil t) + (progn (end-of-line) + (forward-char 1)) + (goto-char (point-max)))) + +(defun python-backward-cell (&optional arg) + (interactive "p") + ;; TODO: prefix support + + ;; check if it finds a line matched by the delimiter regex before + ;; the actual point + (and (save-excursion (re-search-backward python-cell-delimiter-regex + nil t)) + (= (match-beginning 0) (save-excursion + (forward-char -1) (beginning-of-line) (point))) + (goto-char (match-beginning 0))) + + (if (> (point) (point-min)) + (forward-char -1)) + (if (re-search-backward python-cell-delimiter-regex nil t) + ;; We found one--move to the end of it. + (progn (goto-char (match-end 0)) + (end-of-line) + (forward-char 1)) + ;; We found nothing--go to beg of buffer. + (goto-char (point-min)))) + +(defun python-beginning-of-cell (&optional arg) + (interactive "p") + ;; TODO: prefix support + + (if (re-search-backward python-cell-delimiter-regex nil t) + ;; We found one--move to the end of it. + (progn (goto-char (match-end 0)) + (end-of-line) + (forward-char 1)) + ;; We found nothing--go to beg of buffer. + (goto-char (point-min)))) + ;;; Shell integration @@ -1594,6 +1646,24 @@ Returns the output. See `python-shell-send-string-no-output'." (let ((deactivate-mark nil)) (python-shell-send-string (buffer-substring start end) nil t))) + +(defun python-shell-send-cell () + "Send the cell the cursor is in to the inferior Python process." + (interactive) + (let ( + (start (save-excursion (python-beginning-of-cell) + (point))) + (end (save-excursion (python-forward-cell) + (forward-char -1) + (beginning-of-line) + (forward-char -1) + (point)))) + ;; (goto-char end) + ;; (push-mark start) + ;; (activate-mark))) + (python-shell-send-region start end))) + + (defun python-shell-send-buffer () "Send the entire buffer to inferior Python process." (interactive) From 5dd53b5c4ebf8b9aa34685812827de8c41b09a8d Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Thu, 12 Apr 2012 01:04:52 +0200 Subject: [PATCH 2/4] added new python-end-of-cell function --- python.el | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/python.el b/python.el index bab2449..27bb53d 100644 --- a/python.el +++ b/python.el @@ -1199,11 +1199,9 @@ when defun is completed, else nil." (if (> (point) (point-min)) (forward-char -1)) (if (re-search-backward python-cell-delimiter-regex nil t) - ;; We found one--move to the end of it. (progn (goto-char (match-end 0)) (end-of-line) (forward-char 1)) - ;; We found nothing--go to beg of buffer. (goto-char (point-min)))) (defun python-beginning-of-cell (&optional arg) @@ -1211,13 +1209,20 @@ when defun is completed, else nil." ;; TODO: prefix support (if (re-search-backward python-cell-delimiter-regex nil t) - ;; We found one--move to the end of it. (progn (goto-char (match-end 0)) (end-of-line) (forward-char 1)) - ;; We found nothing--go to beg of buffer. (goto-char (point-min)))) +(defun python-end-of-cell (&optional arg) + (interactive "p") + ;; TODO: prefix support + + (if (re-search-forward python-cell-delimiter-regex nil t) + (progn (goto-char (match-beginning 0)) + (forward-char -1)) + (goto-char (point-max)))) + ;;; Shell integration @@ -1653,10 +1658,7 @@ Returns the output. See `python-shell-send-string-no-output'." (let ( (start (save-excursion (python-beginning-of-cell) (point))) - (end (save-excursion (python-forward-cell) - (forward-char -1) - (beginning-of-line) - (forward-char -1) + (end (save-excursion (python-end-of-cell) (point)))) ;; (goto-char end) ;; (push-mark start) From 15121a2f66e02b2437a9d4aef2cb23952aaf5c8c Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Sun, 15 Apr 2012 15:03:08 +0200 Subject: [PATCH 3/4] cell-support for *.py files created with the IPython notebook plus: regex -> regexp --- python.el | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/python.el b/python.el index 27bb53d..6d27979 100644 --- a/python.el +++ b/python.el @@ -1169,7 +1169,7 @@ when defun is completed, else nil." (goto-char (marker-position def-marker)) (back-to-indentation)))) -(defcustom python-cell-delimiter-regex "^##" +(defcustom python-cell-delimiter-regexp "^##" "Delimiter used for detecting the cell boundaries of code cells/blocks." :type 'string :group 'python @@ -1179,7 +1179,7 @@ when defun is completed, else nil." (interactive "p") ;; TODO: prefix support - (if (re-search-forward python-cell-delimiter-regex nil t) + (if (re-search-forward python-cell-delimiter-regexp nil t) (progn (end-of-line) (forward-char 1)) (goto-char (point-max)))) @@ -1188,9 +1188,9 @@ when defun is completed, else nil." (interactive "p") ;; TODO: prefix support - ;; check if it finds a line matched by the delimiter regex before + ;; check if it finds a line matched by the delimiter regexp before ;; the actual point - (and (save-excursion (re-search-backward python-cell-delimiter-regex + (and (save-excursion (re-search-backward python-cell-delimiter-regexp nil t)) (= (match-beginning 0) (save-excursion (forward-char -1) (beginning-of-line) (point))) @@ -1198,7 +1198,7 @@ when defun is completed, else nil." (if (> (point) (point-min)) (forward-char -1)) - (if (re-search-backward python-cell-delimiter-regex nil t) + (if (re-search-backward python-cell-delimiter-regexp nil t) (progn (goto-char (match-end 0)) (end-of-line) (forward-char 1)) @@ -1208,7 +1208,7 @@ when defun is completed, else nil." (interactive "p") ;; TODO: prefix support - (if (re-search-backward python-cell-delimiter-regex nil t) + (if (re-search-backward python-cell-delimiter-regexp nil t) (progn (goto-char (match-end 0)) (end-of-line) (forward-char 1)) @@ -1218,7 +1218,7 @@ when defun is completed, else nil." (interactive "p") ;; TODO: prefix support - (if (re-search-forward python-cell-delimiter-regex nil t) + (if (re-search-forward python-cell-delimiter-regexp nil t) (progn (goto-char (match-beginning 0)) (forward-char -1)) (goto-char (point-max)))) @@ -2853,8 +2853,14 @@ if that value is non-nil." (python-skeleton-add-menu-items) (when python-indent-guess-indent-offset - (python-indent-guess-indent-offset))) - + (python-indent-guess-indent-offset)) + + ;; cell-support for *.py files created with the IPython notebook + (when (save-excursion + (save-match-data + (goto-char (point-min)) + (re-search-forward "^# " nil t))) + (set (make-local-variable 'python-cell-delimiter-regexp) "^# <\\(codecell\\|markdowncell\\)>"))) (provide 'python) ;;; python.el ends here From 83a4323932bc2cecf57344d081df8ad37b87c275 Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Wed, 18 Apr 2012 13:52:26 +0200 Subject: [PATCH 4/4] cell-break font-lock --- python.el | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/python.el b/python.el index 6d27979..8f52a6f 100644 --- a/python.el +++ b/python.el @@ -349,6 +349,30 @@ This variant of `rx' supports common python named REGEXPS." (rx-to-string (car regexps) t))))) + +(defvar python-cellbreak-face 'python-cellbreak-face + "Self reference for cellbreaks.") + +(defface python-cellbreak-face + (list + (list t + (list :background (face-background font-lock-comment-face) + :foreground (face-foreground font-lock-comment-face) + :overline t + :bold t))) + "*Face to use for cellbreak lines." + :group 'python) + +;; Now make some cellbreak variable faces +(cond ((facep 'font-comment-face) + (copy-face 'font-lock-comment-face 'python-cellbreak-face)) + (t + (make-face 'python-cellbreak-face))) +(set-face-bold-p 'python-cellbreak-face t) +(condition-case nil + (set-face-attribute 'python-cellbreak-face nil :overline t) + (error nil)) + ;;; Font-lock and syntax (defvar python-font-lock-keywords ;; Keywords @@ -429,6 +453,11 @@ This variant of `rx' supports common python named REGEXPS." ;; Extra: "__all__" "__doc__" "__name__" "__package__") symbol-end) . font-lock-builtin-face) + ;; Cell Break + (,(rx line-start (* space) (group (and "#" (or (and "#" (* (not (any "\n")))) + (and " <" (or "codecell" "markdowncell") ">")) + line-end))) + (1 python-cellbreak-face append)) ;; asignations ;; support for a = b = c = 5 (,(lambda (limit)