forked from akmrsk/maxscript-mode
-
Notifications
You must be signed in to change notification settings - Fork 1
/
send-to-max.el
176 lines (150 loc) · 6.13 KB
/
send-to-max.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
;;; send-to-max.el --- maxscript mode addition to allow sending of files/regions to max
;; -*- Mode:Emacs-Lisp -*-
;; Copyright (C) 2015 Johannes Becker
;; Author: Johannes Becker <alfalfasprossen@gmail.com>
;; This file is NOT part of Emacs.
;; -----------------------------------------------------------------------------
;; This file will only take care of passing the region/buffer content to a python
;; script. See send_to_max.py
;; Inspired by etom.el and sublime3dsmax.
;;
;; How to use:
;;
;; (add-hook
;; 'maxscript-mode-hook
;; (lambda ()
;; (require 'send-to-max)
;; (local-set-key [S-return] 'maxscript-send-line-or-region)
;; (local-set-key (kbd "C-e") 'maxscript-send-file)
;; (local-set-key (kbd "C-c C-c") 'maxscript-send-buffer)
;; (local-set-key (kbd "C-c C-d") 'maxscript-clear-output)))
;;
;; (add-hook
;; 'python-mode-hook
;; (lambda ()
;; (require 'send-to-max)
;; (local-set-key (kbd "C-c C-m C-r") 'maxscript-send-region-py)
;; (local-set-key (kbd "C-c C-m C-e") 'maxscript-send-file)
;; (local-set-key (kbd "C-c C-m C-c") 'maxscript-send-buffer-py)
;; (local-set-key (kbd "C-c C-m C-d") 'maxscript-clear-listener)))
;;
;; -----------------------------------------------------------------------------
(require 'maxscript-mode)
(defconst maxscript/mode-base-dir (file-name-directory (or load-file-name buffer-file-name))
"Directory this file resides in, used to call the python script with an absolute path.")
(defcustom maxscript-always-show-output t
"Show the maxscript output buffer whenever sending a command."
:type 'boolean
:group 'maxscript)
(defcustom maxscript-always-clear-listener t
"Clear the listener output in 3dsMax before sending a new command. This will make sure we only append the output that is new to our output buffer."
:type 'boolean
:group 'maxscript)
(defcustom maxscript-jump-lines t
"Move point to the next line each time a single line has been sent."
:type 'boolean
:group 'maxscript)
(defun maxscript/send-command (cmd)
"Send whatever pre-assembled command to the python script that will do the actual work."
(let ((result ()))
(setq result (shell-command-to-string
(concat "python " maxscript/mode-base-dir "/send_to_max.py "
cmd)))
result))
(defun maxscript-send-line-or-region ()
"Send the line at point if no region, send region if exists."
(interactive)
(if (use-region-p)
(maxscript-send-region (region-beginning) (region-end))
(progn
(maxscript-send-region (point-at-bol) (point-at-eol))
(if maxscript-jump-lines
(next-line)))))
(defun maxscript-send-line-or-region-py ()
"Send the line at point if no region, send region if exists."
(interactive)
(if (use-region-p)
(maxscript-send-region (region-beginning) (region-end) t)
(progn
(maxscript-send-region (point-at-bol) (point-at-eol) t)
(if maxscript-jump-lines
(next-line)))))
(defun maxscript-send-region (start end &optional aspython)
"Send region to Max."
(interactive "r")
(let ((content (buffer-substring-no-properties start end))
(cmd ()))
(if maxscript-always-clear-listener (maxscript-clear-listener))
(setq cmd (concat (if aspython "-py " "-ms ") (shell-quote-argument content)))
(maxscript/send-command cmd)
(maxscript/fetch-output)
(if maxscript-always-show-output (maxscript-show-output-buffer))))
(defun maxscript-send-region-py (start end)
"Send region to Max as Python code."
(interactive "r")
(maxscript-send-region start end t))
(defun maxscript-send-buffer ()
"Send whole buffer to Max."
(interactive)
(maxscript-send-region (point-min) (point-max)))
(defun maxscript-send-buffer-py ()
"Send whole buffer to Max as Python code."
(interactive)
(maxscript-send-region (point-min) (point-max) t))
(defun maxscript-send-file ()
"Send the current file to Max. The important difference to send-buffer is that the actual file of the buffer will be executed in max. This is important for relative imports etc, but also you should save the file before executing this, or modifications to the buffer will not be present in the file. "
(interactive)
(let ((cmd ()))
(setq cmd (concat "-f " (buffer-file-name)))
(maxscript/send-command cmd)
(maxscript/fetch-output)
(if maxscript-always-show-output (maxscript-show-output-buffer))))
;;; maxscript listener output related functions
(defvar maxscript/output-buffer "*mxs output*"
"Name of buffer used to display Maxscript output.")
(defun maxscript/get-output-buffer ()
"Return the output buffer, create it if necessary. Also, set maxscript-mode there as major-mode."
(let ((buff (get-buffer-create maxscript/output-buffer)))
(with-current-buffer buff
(maxscript-mode)
(maxscript/setup-compile)
(compilation-minor-mode))
buff))
(defun maxscript-show-output-buffer ()
(interactive)
(display-buffer (maxscript/get-output-buffer)))
(defun maxscript-hide-output-buffer ()
(interactive)
(delete-windows-on (maxscript/get-output-buffer)))
(defun maxscript-clear-output ()
"Clear the `maxscript/output-buffer' and the Maxscript-Listener in Max."
(interactive)
(with-current-buffer (get-buffer-create maxscript/output-buffer)
(erase-buffer)
)
(maxscript-clear-listener))
(defun maxscript-clear-listener ()
"Clear the Maxscript-Listener output in Max."
(interactive)
(let ((result (maxscript/send-command "-c")))
(princ result)))
(defun maxscript/get-output ()
"Get the response (listener output) from Max."
(let ((result (maxscript/send-command "-g")))
result))
(defun maxscript/fetch-output ()
"Write the output from Max into the output buffer."
(with-current-buffer (get-buffer-create maxscript/output-buffer)
(insert-before-markers (maxscript/get-output))
(goto-char (point-max))
(compilation--ensure-parse (point-max))))
(require 'compile)
(defun maxscript/setup-compile ()
(interactive)
(set (make-local-variable 'compilation-error-regexp-alist)
(list 'maxscript-compile-nogroup))
(set (make-local-variable 'compilation-error-regexp-alist-alist)
(list (cons 'maxscript-compile-nogroup
(list maxscript/error-pattern 1 2)))))
(provide 'send-to-max)
;;; send-to-max.el ends here