Skip to content

Instantly share code, notes, and snippets.

@freckletonj
Last active June 9, 2024 07:53
Show Gist options
  • Save freckletonj/e1eaf7ad704272c94718e624d62f25a5 to your computer and use it in GitHub Desktop.
Save freckletonj/e1eaf7ad704272c94718e624d62f25a5 to your computer and use it in GitHub Desktop.
Run blocks of code in python interpreter using keybinding
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Highlight blocks and send to Python interpreter
(defun search-unique (marker)
"Search for the first and only occurrence of MARKER.
Return the position if found, or nil if not found or multiple occurrences exist."
(let ((first-pos nil)
(count 0))
(save-excursion
(goto-char (point-min))
(while (search-forward marker nil t)
(setq count (1+ count))
(when (= count 1)
(setq first-pos (point)))))
(if (= count 1)
first-pos
nil)))
(defun highlight-block (start-marker stop-marker)
"Set the region between START-MARKER and STOP-MARKER, activate the mark,
and return the region boundaries as a cons cell (start . end)."
(interactive "sStart marker: \nsStop marker: ")
(let ((start-pos (save-excursion
(when-let ((pos (search-unique start-marker)))
(goto-char pos)
(beginning-of-line)
(point))))
(end-pos (save-excursion
(when-let ((pos (search-unique stop-marker)))
(goto-char pos)
(end-of-line)
(point)))))
(when (and start-pos end-pos)
(push-mark start-pos)
(goto-char end-pos)
(activate-mark)
(cons start-pos end-pos))))
(defun python-run-block (start-marker end-marker)
"Highlight the block between START-MARKER and END-MARKER and send it to the Python shell."
(interactive "sStart marker: \nsEnd marker: ")
(let ((current-pos (point))
(region (highlight-block start-marker end-marker))) ; Save the current cursor position
(if region
(let ((start (car region))
(end (cdr region)))
(message "Region is set: %s to %s" start end) ; Debugging message
(python-shell-send-region start end)
(deactivate-mark) ; Deactivate the mark to remove highlighting
(message "Sent region to Python shell"))
(message "No region set"))
(goto-char current-pos))) ; Restore the cursor position
;; Define keybindings for different blocks
;;
;; Ex:
;; # START_BLOCK_1
;; print('hi')
;; # END_BLOCK_1
;; C-c 1 ; run that block
(dolist (i (number-sequence 1 5))
(define-key python-mode-map
(kbd (format "C-c %d" i))
`(lambda ()
(interactive)
(python-run-block
,(format "START_BLOCK_%d" i)
,(format "END_BLOCK_%d" i)))))
@freckletonj
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment