-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathflex-compile-python.el
137 lines (113 loc) · 4.9 KB
/
flex-compile-python.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
;;; flex-compile-python.el --- Python compile functions -*- lexical-binding: t; -*-
;; Copyright (C) 2015 - 2023 Paul Landes
;; Author: Paul Landes
;; Maintainer: Paul Landes
;; Keywords: python integration compilation processes
;; URL: https://github.com/plandes/flex-compile
;; Package-Requires: ((emacs "26.1"))
;; Package-Version: 0
;; 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 2, 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, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;; Implementation compiler for python integration
;;; Code:
(require 'subr-x)
(require 'flex-compile-manage)
(require 'flex-compile-repl)
(declare-function python-nav-backward-statement "python")
(declare-function python-nav-forward-statement "python")
(declare-function python-shell-calculate-command "python")
(declare-function python-shell-completion-native-setup "python")
(declare-function python-shell-parse-command "python")
(declare-function python-shell-send-buffer "python")
(declare-function python-shell-send-string "python")
(declare-function run-python "python")
(config-manage-declare-variables
python-shell-completion-native-enable)
(defun flex-compile-python-path ()
"Return the PYTHONPATH environment to be used when creating the REPL."
(getenv "PYTHONPATH"))
(defclass python-flex-compiler (repl-flex-compiler)
()
:method-invocation-order :c3
:documentation "\
This is a REPL based compiler that allows for evaluation Python buffers and
expressions using [python mode](https://github.com/fgallina/python.el).")
(cl-defmethod initialize-instance ((this python-flex-compiler) &optional slots)
"Initialize instance THIS with arguments SLOTS."
(setq slots (plist-put slots :object-name "python")
slots (plist-put slots :validate-modes '(python-mode))
slots (plist-put slots :repl-buffer-regexp "^\\*Python\\*$")
slots (plist-put slots :repl-buffer-start-timeout 0))
(cl-call-next-method this slots))
(cl-defmethod flex-compiler-load-libraries ((this python-flex-compiler))
"Load the `python' library for THIS compiler."
(ignore this)
(require 'python))
(cl-defmethod flex-compiler-eval-form-impl ((this python-flex-compiler) form)
"Evaluate the FORM and return the response of the REPL for THIS compiler."
(ignore this)
(python-shell-send-string form))
(cl-defmethod flex-compiler-start-buffer ((this python-flex-compiler)
start-type)
"Return a new buffer for THIS compiler with a processing compilation.
START-TYPE is either symbols `compile', `run', `clean' depending
if invoked by `flex-compiler-compile' or `flex-compiler-run'."
(let (ret)
(if (eq start-type 'compile)
(if (flex-compiler-repl-running-p this)
(setq ret (cl-call-next-method this start-type))
(let ((do-native-p python-shell-completion-native-enable)
(python-shell-completion-native-enable nil))
(flex-compiler-run this)
(if do-native-p
(python-shell-completion-native-setup)))))
(or ret (cl-call-next-method this start-type))))
(cl-defmethod flex-compiler-repl-compile ((this python-flex-compiler) file)
"Send the contents of source code FILE to the REPL buffer of THIS compiler."
(ignore this)
(let ((buf (find-file-noselect file)))
(with-current-buffer buf
(python-shell-send-buffer))))
(cl-defmethod flex-compiler-eval-initial-at-point ((this python-flex-compiler))
"Return the Python form at the current point to the REPL for THIS compiler."
(ignore this)
(let ((forward-fn #'python-nav-forward-statement)
(backward-fn #'python-nav-backward-statement))
(save-excursion
(->> (buffer-substring
(progn
(end-of-line 1)
(while (and (or (funcall backward-fn)
(beginning-of-line 1))
(> (current-indentation) 0)))
(forward-line 1)
(point-marker))
(progn
(or (funcall forward-fn)
(end-of-line 1))
(point-marker)))
string-trim))))
(cl-defmethod flex-compiler-repl-start ((this python-flex-compiler))
"Start the REPL using THIS compiler."
(ignore this)
(let ((old-path (getenv "PYTHONPATH")))
(unwind-protect
(let ((new-path (flex-compile-python-path)))
(setenv "PYTHONPATH" new-path)
(run-python (python-shell-calculate-command) nil 4))
(setenv "PYTHONPATH" old-path))))
(flex-compile-manager-register flex-compile-manage-inst (python-flex-compiler))
(provide 'flex-compile-python)
;;; flex-compile-python.el ends here