40785
|
1 ;; Calculator for GNU Emacs, part II [calc-graph.el]
|
|
2 ;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
|
3 ;; Written by Dave Gillespie, daveg@synaptics.com.
|
|
4
|
|
5 ;; This file is part of GNU Emacs.
|
|
6
|
|
7 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
8 ;; but WITHOUT ANY WARRANTY. No author or distributor
|
|
9 ;; accepts responsibility to anyone for the consequences of using it
|
|
10 ;; or for whether it serves any particular purpose or works at all,
|
|
11 ;; unless he says so in writing. Refer to the GNU Emacs General Public
|
|
12 ;; License for full details.
|
|
13
|
|
14 ;; Everyone is granted permission to copy, modify and redistribute
|
|
15 ;; GNU Emacs, but only under the conditions described in the
|
|
16 ;; GNU Emacs General Public License. A copy of this license is
|
|
17 ;; supposed to have been given to you along with GNU Emacs so you
|
|
18 ;; can know your rights and responsibilities. It should be in a
|
|
19 ;; file named COPYING. Among other things, the copyright notice
|
|
20 ;; and this notice must be preserved on all copies.
|
|
21
|
|
22
|
|
23
|
|
24 ;; This file is autoloaded from calc-ext.el.
|
|
25 (require 'calc-ext)
|
|
26
|
|
27 (require 'calc-macs)
|
|
28
|
|
29 (defun calc-Need-calc-graph () nil)
|
|
30
|
|
31
|
|
32 ;;; Graphics
|
|
33
|
|
34 ;;; Note that some of the following initial values also occur in calc.el.
|
|
35 (defvar calc-gnuplot-tempfile "/tmp/calc")
|
|
36
|
|
37 (defvar calc-gnuplot-default-device "default")
|
|
38 (defvar calc-gnuplot-default-output "STDOUT")
|
|
39 (defvar calc-gnuplot-print-device "postscript")
|
|
40 (defvar calc-gnuplot-print-output "auto")
|
|
41 (defvar calc-gnuplot-keep-outfile nil)
|
|
42 (defvar calc-gnuplot-version nil)
|
|
43
|
|
44 (defvar calc-gnuplot-display (getenv "DISPLAY"))
|
|
45 (defvar calc-gnuplot-geometry nil)
|
|
46
|
|
47 (defvar calc-graph-default-resolution 15)
|
|
48 (defvar calc-graph-default-resolution-3d 5)
|
|
49 (defvar calc-graph-default-precision 5)
|
|
50
|
|
51 (defvar calc-gnuplot-buffer nil)
|
|
52 (defvar calc-gnuplot-input nil)
|
|
53
|
|
54 (defvar calc-gnuplot-last-error-pos 1)
|
|
55 (defvar calc-graph-last-device nil)
|
|
56 (defvar calc-graph-last-output nil)
|
|
57 (defvar calc-graph-file-cache nil)
|
|
58 (defvar calc-graph-var-cache nil)
|
|
59 (defvar calc-graph-data-cache nil)
|
|
60 (defvar calc-graph-data-cache-limit 10)
|
|
61
|
|
62 (defun calc-graph-fast (many)
|
|
63 (interactive "P")
|
|
64 (let ((calc-graph-no-auto-view t))
|
|
65 (calc-graph-delete t)
|
|
66 (calc-graph-add many)
|
|
67 (calc-graph-plot nil))
|
|
68 )
|
|
69
|
|
70 (defun calc-graph-fast-3d (many)
|
|
71 (interactive "P")
|
|
72 (let ((calc-graph-no-auto-view t))
|
|
73 (calc-graph-delete t)
|
|
74 (calc-graph-add-3d many)
|
|
75 (calc-graph-plot nil))
|
|
76 )
|
|
77
|
|
78 (defun calc-graph-delete (all)
|
|
79 (interactive "P")
|
|
80 (calc-wrapper
|
|
81 (calc-graph-init)
|
|
82 (save-excursion
|
|
83 (set-buffer calc-gnuplot-input)
|
|
84 (and (calc-graph-find-plot t all)
|
|
85 (progn
|
|
86 (if (looking-at "s?plot")
|
|
87 (progn
|
|
88 (setq calc-graph-var-cache nil)
|
|
89 (delete-region (point) (point-max)))
|
|
90 (delete-region (point) (1- (point-max)))))))
|
|
91 (calc-graph-view-commands))
|
|
92 )
|
|
93
|
|
94 (defun calc-graph-find-plot (&optional before all)
|
|
95 (goto-char (point-min))
|
|
96 (and (re-search-forward "^s?plot[ \t]+" nil t)
|
|
97 (let ((beg (point)))
|
|
98 (goto-char (point-max))
|
|
99 (if (or all
|
|
100 (not (search-backward "," nil t))
|
|
101 (< (point) beg))
|
|
102 (progn
|
|
103 (goto-char beg)
|
|
104 (if before
|
|
105 (beginning-of-line)))
|
|
106 (or before
|
|
107 (re-search-forward ",[ \t]+")))
|
|
108 t))
|
|
109 )
|
|
110
|
|
111 (defun calc-graph-add (many)
|
|
112 (interactive "P")
|
|
113 (calc-wrapper
|
|
114 (calc-graph-init)
|
|
115 (cond ((null many)
|
|
116 (calc-graph-add-curve (calc-graph-lookup (calc-top-n 2))
|
|
117 (calc-graph-lookup (calc-top-n 1))))
|
|
118 ((or (consp many) (eq many 0))
|
|
119 (let ((xdata (calc-graph-lookup (calc-top-n 2)))
|
|
120 (ylist (calc-top-n 1)))
|
|
121 (or (eq (car-safe ylist) 'vec)
|
|
122 (error "Y argument must be a vector"))
|
|
123 (while (setq ylist (cdr ylist))
|
|
124 (calc-graph-add-curve xdata (calc-graph-lookup (car ylist))))))
|
|
125 ((> (setq many (prefix-numeric-value many)) 0)
|
|
126 (let ((xdata (calc-graph-lookup (calc-top-n (1+ many)))))
|
|
127 (while (> many 0)
|
|
128 (calc-graph-add-curve xdata
|
|
129 (calc-graph-lookup (calc-top-n many)))
|
|
130 (setq many (1- many)))))
|
|
131 (t
|
|
132 (let (pair)
|
|
133 (setq many (- many))
|
|
134 (while (> many 0)
|
|
135 (setq pair (calc-top-n many))
|
|
136 (or (and (eq (car-safe pair) 'vec)
|
|
137 (= (length pair) 3))
|
|
138 (error "Argument must be an [x,y] vector"))
|
|
139 (calc-graph-add-curve (calc-graph-lookup (nth 1 pair))
|
|
140 (calc-graph-lookup (nth 2 pair)))
|
|
141 (setq many (1- many))))))
|
|
142 (calc-graph-view-commands))
|
|
143 )
|
|
144
|
|
145 (defun calc-graph-add-3d (many)
|
|
146 (interactive "P")
|
|
147 (calc-wrapper
|
|
148 (calc-graph-init)
|
|
149 (cond ((null many)
|
|
150 (calc-graph-add-curve (calc-graph-lookup (calc-top-n 3))
|
|
151 (calc-graph-lookup (calc-top-n 2))
|
|
152 (calc-graph-lookup (calc-top-n 1))))
|
|
153 ((or (consp many) (eq many 0))
|
|
154 (let ((xdata (calc-graph-lookup (calc-top-n 3)))
|
|
155 (ydata (calc-graph-lookup (calc-top-n 2)))
|
|
156 (zlist (calc-top-n 1)))
|
|
157 (or (eq (car-safe zlist) 'vec)
|
|
158 (error "Z argument must be a vector"))
|
|
159 (while (setq zlist (cdr zlist))
|
|
160 (calc-graph-add-curve xdata ydata
|
|
161 (calc-graph-lookup (car zlist))))))
|
|
162 ((> (setq many (prefix-numeric-value many)) 0)
|
|
163 (let ((xdata (calc-graph-lookup (calc-top-n (+ many 2))))
|
|
164 (ydata (calc-graph-lookup (calc-top-n (+ many 1)))))
|
|
165 (while (> many 0)
|
|
166 (calc-graph-add-curve xdata ydata
|
|
167 (calc-graph-lookup (calc-top-n many)))
|
|
168 (setq many (1- many)))))
|
|
169 (t
|
|
170 (let (curve)
|
|
171 (setq many (- many))
|
|
172 (while (> many 0)
|
|
173 (setq curve (calc-top-n many))
|
|
174 (or (and (eq (car-safe curve) 'vec)
|
|
175 (= (length curve) 4))
|
|
176 (error "Argument must be an [x,y,z] vector"))
|
|
177 (calc-graph-add-curve (calc-graph-lookup (nth 1 curve))
|
|
178 (calc-graph-lookup (nth 2 curve))
|
|
179 (calc-graph-lookup (nth 3 curve)))
|
|
180 (setq many (1- many))))))
|
|
181 (calc-graph-view-commands))
|
|
182 )
|
|
183
|
|
184 (defun calc-graph-add-curve (xdata ydata &optional zdata)
|
|
185 (let ((num (calc-graph-count-curves))
|
|
186 (pstyle (calc-var-value 'var-PointStyles))
|
|
187 (lstyle (calc-var-value 'var-LineStyles)))
|
|
188 (save-excursion
|
|
189 (set-buffer calc-gnuplot-input)
|
|
190 (goto-char (point-min))
|
|
191 (if (re-search-forward (if zdata "^plot[ \t]" "^splot[ \t]")
|
|
192 nil t)
|
|
193 (error "Can't mix 2d and 3d curves on one graph"))
|
|
194 (if (re-search-forward "^s?plot[ \t]" nil t)
|
|
195 (progn
|
|
196 (end-of-line)
|
|
197 (insert ", "))
|
|
198 (goto-char (point-max))
|
|
199 (or (eq (preceding-char) ?\n)
|
|
200 (insert "\n"))
|
|
201 (insert (if zdata "splot" "plot") " \n")
|
|
202 (forward-char -1))
|
|
203 (insert "{" (symbol-name (nth 1 xdata))
|
|
204 ":" (symbol-name (nth 1 ydata)))
|
|
205 (if zdata
|
|
206 (insert ":" (symbol-name (nth 1 zdata))))
|
|
207 (insert "} "
|
|
208 "title \"" (symbol-name (nth 1 ydata)) "\" "
|
|
209 "with dots")
|
|
210 (setq pstyle (and (eq (car-safe pstyle) 'vec) (nth (1+ num) pstyle)))
|
|
211 (setq lstyle (and (eq (car-safe lstyle) 'vec) (nth (1+ num) lstyle)))
|
|
212 (calc-graph-set-styles
|
|
213 (or (and (Math-num-integerp lstyle) (math-trunc lstyle))
|
|
214 0)
|
|
215 (or (and (Math-num-integerp pstyle) (math-trunc pstyle))
|
|
216 (if (eq (car-safe (calc-var-value (nth 2 ydata))) 'vec)
|
|
217 0 -1)))))
|
|
218 )
|
|
219
|
|
220 (defun calc-graph-lookup (thing)
|
|
221 (if (and (eq (car-safe thing) 'var)
|
|
222 (calc-var-value (nth 2 thing)))
|
|
223 thing
|
|
224 (let ((found (assoc thing calc-graph-var-cache)))
|
|
225 (or found
|
|
226 (progn
|
|
227 (setq varname (concat "PlotData"
|
|
228 (int-to-string
|
|
229 (1+ (length calc-graph-var-cache))))
|
|
230 var (list 'var (intern varname)
|
|
231 (intern (concat "var-" varname)))
|
|
232 found (cons thing var)
|
|
233 calc-graph-var-cache (cons found calc-graph-var-cache))
|
|
234 (set (nth 2 var) thing)))
|
|
235 (cdr found)))
|
|
236 )
|
|
237
|
|
238 (defun calc-graph-juggle (arg)
|
|
239 (interactive "p")
|
|
240 (calc-graph-init)
|
|
241 (save-excursion
|
|
242 (set-buffer calc-gnuplot-input)
|
|
243 (if (< arg 0)
|
|
244 (let ((num (calc-graph-count-curves)))
|
|
245 (if (> num 0)
|
|
246 (while (< arg 0)
|
|
247 (setq arg (+ arg num))))))
|
|
248 (while (>= (setq arg (1- arg)) 0)
|
|
249 (calc-graph-do-juggle)))
|
|
250 )
|
|
251
|
|
252 (defun calc-graph-count-curves ()
|
|
253 (save-excursion
|
|
254 (set-buffer calc-gnuplot-input)
|
|
255 (if (re-search-forward "^s?plot[ \t]" nil t)
|
|
256 (let ((num 1))
|
|
257 (goto-char (point-min))
|
|
258 (while (search-forward "," nil t)
|
|
259 (setq num (1+ num)))
|
|
260 num)
|
|
261 0))
|
|
262 )
|
|
263
|
|
264 (defun calc-graph-do-juggle ()
|
|
265 (let (base)
|
|
266 (and (calc-graph-find-plot t t)
|
|
267 (progn
|
|
268 (setq base (point))
|
|
269 (calc-graph-find-plot t nil)
|
|
270 (or (eq base (point))
|
|
271 (let ((str (buffer-substring (+ (point) 2) (1- (point-max)))))
|
|
272 (delete-region (point) (1- (point-max)))
|
|
273 (goto-char (+ base 5))
|
|
274 (insert str ", "))))))
|
|
275 )
|
|
276
|
|
277 (defun calc-graph-print (flag)
|
|
278 (interactive "P")
|
|
279 (calc-graph-plot flag t)
|
|
280 )
|
|
281
|
|
282 (defun calc-graph-plot (flag &optional printing)
|
|
283 (interactive "P")
|
|
284 (calc-slow-wrapper
|
|
285 (let ((calcbuf (current-buffer))
|
|
286 (tempbuf (get-buffer-create "*Gnuplot Temp-2*"))
|
|
287 (tempbuftop 1)
|
|
288 (tempoutfile nil)
|
|
289 (curve-num 0)
|
|
290 (refine (and flag (> (prefix-numeric-value flag) 0)))
|
|
291 (recompute (and flag (< (prefix-numeric-value flag) 0)))
|
|
292 (surprise-splot nil)
|
|
293 (tty-output nil)
|
|
294 cache-env is-splot device output resolution precision samples-pos)
|
|
295 (or (boundp 'calc-graph-prev-kill-hook)
|
|
296 (if calc-emacs-type-19
|
|
297 (progn
|
|
298 (setq calc-graph-prev-kill-hook nil)
|
|
299 (add-hook 'kill-emacs-hook 'calc-graph-kill-hook))
|
|
300 (setq calc-graph-prev-kill-hook kill-emacs-hook)
|
|
301 (setq kill-emacs-hook 'calc-graph-kill-hook)))
|
|
302 (save-excursion
|
|
303 (calc-graph-init)
|
|
304 (set-buffer tempbuf)
|
|
305 (erase-buffer)
|
|
306 (set-buffer calc-gnuplot-input)
|
|
307 (goto-char (point-min))
|
|
308 (setq is-splot (re-search-forward "^splot[ \t]" nil t))
|
|
309 (let ((str (buffer-string))
|
|
310 (ver calc-gnuplot-version))
|
|
311 (set-buffer (get-buffer-create "*Gnuplot Temp*"))
|
|
312 (erase-buffer)
|
|
313 (insert "# (Note: This is a temporary copy---do not edit!)\n")
|
|
314 (if (>= ver 2)
|
|
315 (insert "set noarrow\nset nolabel\n"
|
|
316 "set autoscale xy\nset nologscale xy\n"
|
|
317 "set xlabel\nset ylabel\nset title\n"
|
|
318 "set noclip points\nset clip one\nset clip two\n"
|
|
319 "set format \"%g\"\nset tics\nset xtics\nset ytics\n"
|
|
320 "set data style linespoints\n"
|
|
321 "set nogrid\nset nokey\nset nopolar\n"))
|
|
322 (if (>= ver 3)
|
|
323 (insert "set surface\nset nocontour\n"
|
|
324 "set " (if is-splot "" "no") "parametric\n"
|
|
325 "set notime\nset border\nset ztics\nset zeroaxis\n"
|
|
326 "set view 60,30,1,1\nset offsets 0,0,0,0\n"))
|
|
327 (setq samples-pos (point))
|
|
328 (insert "\n\n" str))
|
|
329 (goto-char (point-min))
|
|
330 (if is-splot
|
|
331 (if refine
|
|
332 (error "This option works only for 2d plots")
|
|
333 (setq recompute t)))
|
|
334 (let ((calc-gnuplot-input (current-buffer))
|
|
335 (calc-graph-no-auto-view t))
|
|
336 (if printing
|
|
337 (setq device calc-gnuplot-print-device
|
|
338 output calc-gnuplot-print-output)
|
|
339 (setq device (calc-graph-find-command "terminal")
|
|
340 output (calc-graph-find-command "output"))
|
|
341 (or device
|
|
342 (setq device calc-gnuplot-default-device))
|
|
343 (if output
|
|
344 (setq output (car (read-from-string output)))
|
|
345 (setq output calc-gnuplot-default-output)))
|
|
346 (if (or (equal device "") (equal device "default"))
|
|
347 (setq device (if printing
|
|
348 "postscript"
|
|
349 (if (or (eq window-system 'x) (getenv "DISPLAY"))
|
|
350 "x11"
|
|
351 (if (>= calc-gnuplot-version 3)
|
|
352 "dumb" "postscript")))))
|
|
353 (if (equal device "dumb")
|
|
354 (setq device (format "dumb %d %d"
|
|
355 (1- (screen-width)) (1- (screen-height)))))
|
|
356 (if (equal device "big")
|
|
357 (setq device (format "dumb %d %d"
|
|
358 (* 4 (- (screen-width) 3))
|
|
359 (* 4 (- (screen-height) 3)))))
|
|
360 (if (stringp output)
|
|
361 (if (or (equal output "auto")
|
|
362 (and (equal output "tty") (setq tty-output t)))
|
|
363 (setq tempoutfile (calc-temp-file-name -1)
|
|
364 output tempoutfile))
|
|
365 (setq output (eval output)))
|
|
366 (or (equal device calc-graph-last-device)
|
|
367 (progn
|
|
368 (setq calc-graph-last-device device)
|
|
369 (calc-gnuplot-command "set terminal" device)))
|
|
370 (or (equal output calc-graph-last-output)
|
|
371 (progn
|
|
372 (setq calc-graph-last-output output)
|
|
373 (calc-gnuplot-command "set output"
|
|
374 (if (equal output "STDOUT")
|
|
375 ""
|
|
376 (prin1-to-string output)))))
|
|
377 (setq resolution (calc-graph-find-command "samples"))
|
|
378 (if resolution
|
|
379 (setq resolution (string-to-int resolution))
|
|
380 (setq resolution (if is-splot
|
|
381 calc-graph-default-resolution-3d
|
|
382 calc-graph-default-resolution)))
|
|
383 (setq precision (calc-graph-find-command "precision"))
|
|
384 (if precision
|
|
385 (setq precision (string-to-int precision))
|
|
386 (setq precision calc-graph-default-precision))
|
|
387 (calc-graph-set-command "terminal")
|
|
388 (calc-graph-set-command "output")
|
|
389 (calc-graph-set-command "samples")
|
|
390 (calc-graph-set-command "precision"))
|
|
391 (goto-char samples-pos)
|
|
392 (insert "set samples " (int-to-string (max (if is-splot 20 200)
|
|
393 (+ 5 resolution))) "\n")
|
|
394 (while (re-search-forward "{\\*[^}]+}[^,\n]*" nil t)
|
|
395 (delete-region (match-beginning 0) (match-end 0))
|
|
396 (if (looking-at ",")
|
|
397 (delete-char 1)
|
|
398 (while (memq (preceding-char) '(?\ ?\t))
|
|
399 (forward-char -1))
|
|
400 (if (eq (preceding-char) ?\,)
|
|
401 (delete-backward-char 1))))
|
|
402 (save-excursion
|
|
403 (set-buffer calcbuf)
|
|
404 (setq cache-env (list calc-angle-mode
|
|
405 calc-complex-mode
|
|
406 calc-simplify-mode
|
|
407 calc-infinite-mode
|
|
408 calc-word-size
|
|
409 precision is-splot))
|
|
410 (if (and (not recompute)
|
|
411 (equal (cdr (car calc-graph-data-cache)) cache-env))
|
|
412 (while (> (length calc-graph-data-cache)
|
|
413 calc-graph-data-cache-limit)
|
|
414 (setcdr calc-graph-data-cache
|
|
415 (cdr (cdr calc-graph-data-cache))))
|
|
416 (setq calc-graph-data-cache (list (cons nil cache-env)))))
|
|
417 (calc-graph-find-plot t t)
|
|
418 (while (re-search-forward
|
|
419 (if is-splot
|
|
420 "{\\([^{}:\n]+\\):\\([^{}:\n]+\\):\\([^{}:\n]+\\)}"
|
|
421 "{\\([^{}:\n]+\\)\\(:\\)\\([^{}:\n]+\\)}")
|
|
422 nil t)
|
|
423 (setq curve-num (1+ curve-num))
|
|
424 (let* ((xname (buffer-substring (match-beginning 1) (match-end 1)))
|
|
425 (xvar (intern (concat "var-" xname)))
|
|
426 (xvalue (math-evaluate-expr (calc-var-value xvar)))
|
|
427 (y3name (and is-splot
|
|
428 (buffer-substring (match-beginning 2)
|
|
429 (match-end 2))))
|
|
430 (y3var (and is-splot (intern (concat "var-" y3name))))
|
|
431 (y3value (and is-splot (calc-var-value y3var)))
|
|
432 (yname (buffer-substring (match-beginning 3) (match-end 3)))
|
|
433 (yvar (intern (concat "var-" yname)))
|
|
434 (yvalue (calc-var-value yvar))
|
|
435 filename)
|
|
436 (delete-region (match-beginning 0) (match-end 0))
|
|
437 (setq filename (calc-temp-file-name curve-num))
|
|
438 (save-excursion
|
|
439 (set-buffer calcbuf)
|
|
440 (let (tempbuftop
|
|
441 (xp xvalue)
|
|
442 (yp yvalue)
|
|
443 (zp nil)
|
|
444 (xlow nil) (xhigh nil) (y3low nil) (y3high nil)
|
|
445 xvec xval xstep var-DUMMY
|
|
446 y3vec y3val y3step var-DUMMY2 (zval nil)
|
|
447 yvec yval ycache ycacheptr yvector
|
|
448 numsteps numsteps3
|
|
449 (keep-file (and (not is-splot) (file-exists-p filename)))
|
|
450 (stepcount 0)
|
|
451 (calc-symbolic-mode nil)
|
|
452 (calc-prefer-frac nil)
|
|
453 (calc-internal-prec (max 3 precision))
|
|
454 (calc-simplify-mode (and (not (memq calc-simplify-mode
|
|
455 '(none num)))
|
|
456 calc-simplify-mode))
|
|
457 (blank t)
|
|
458 (non-blank nil)
|
|
459 (math-working-step 0)
|
|
460 (math-working-step-2 nil))
|
|
461 (save-excursion
|
|
462 (if is-splot
|
|
463 (calc-graph-compute-3d)
|
|
464 (calc-graph-compute-2d))
|
|
465 (set-buffer tempbuf)
|
|
466 (goto-char (point-max))
|
|
467 (insert "\n" xname)
|
|
468 (if is-splot
|
|
469 (insert ":" y3name))
|
|
470 (insert ":" yname "\n\n")
|
|
471 (setq tempbuftop (point))
|
|
472 (let ((calc-group-digits nil)
|
|
473 (calc-leading-zeros nil)
|
|
474 (calc-number-radix 10)
|
|
475 (entry (and (not is-splot)
|
|
476 (list xp yp xhigh numsteps))))
|
|
477 (or (equal entry
|
|
478 (nth 1 (nth (1+ curve-num)
|
|
479 calc-graph-file-cache)))
|
|
480 (setq keep-file nil))
|
|
481 (setcar (cdr (nth (1+ curve-num) calc-graph-file-cache))
|
|
482 entry)
|
|
483 (or keep-file
|
|
484 (calc-graph-format-data)))
|
|
485 (or keep-file
|
|
486 (progn
|
|
487 (or non-blank
|
|
488 (error "No valid data points for %s:%s"
|
|
489 xname yname))
|
|
490 (write-region tempbuftop (point-max) filename
|
|
491 nil 'quiet))))))
|
|
492 (insert (prin1-to-string filename))))
|
|
493 (if surprise-splot
|
|
494 (setcdr cache-env nil))
|
|
495 (if (= curve-num 0)
|
|
496 (progn
|
|
497 (calc-gnuplot-command "clear")
|
|
498 (calc-clear-command-flag 'clear-message)
|
|
499 (message "No data to plot!"))
|
|
500 (setq calc-graph-data-cache-limit (max curve-num
|
|
501 calc-graph-data-cache-limit)
|
|
502 filename (calc-temp-file-name 0))
|
|
503 (write-region (point-min) (point-max) filename nil 'quiet)
|
|
504 (calc-gnuplot-command "load" (prin1-to-string filename))
|
|
505 (or (equal output "STDOUT")
|
|
506 calc-gnuplot-keep-outfile
|
|
507 (progn ; need to close the output file before printing/plotting
|
|
508 (setq calc-graph-last-output "STDOUT")
|
|
509 (calc-gnuplot-command "set output")))
|
|
510 (let ((command (if printing
|
|
511 calc-gnuplot-print-command
|
|
512 (or calc-gnuplot-plot-command
|
|
513 (and (string-match "^dumb" device)
|
|
514 'calc-graph-show-dumb)
|
|
515 (and tty-output
|
|
516 'calc-graph-show-tty)))))
|
|
517 (if command
|
|
518 (if (stringp command)
|
|
519 (calc-gnuplot-command
|
|
520 "!" (format command
|
|
521 (or tempoutfile
|
|
522 calc-gnuplot-print-output)))
|
|
523 (if (symbolp command)
|
|
524 (funcall command output)
|
|
525 (eval command)))))))))
|
|
526 )
|
|
527
|
|
528 (defun calc-graph-compute-2d ()
|
|
529 (if (setq yvec (eq (car-safe yvalue) 'vec))
|
|
530 (if (= (setq numsteps (1- (length yvalue))) 0)
|
|
531 (error "Can't plot an empty vector")
|
|
532 (if (setq xvec (eq (car-safe xvalue) 'vec))
|
|
533 (or (= (1- (length xvalue)) numsteps)
|
|
534 (error "%s and %s have different lengths" xname yname))
|
|
535 (if (and (eq (car-safe xvalue) 'intv)
|
|
536 (math-constp xvalue))
|
|
537 (setq xstep (math-div (math-sub (nth 3 xvalue)
|
|
538 (nth 2 xvalue))
|
|
539 (1- numsteps))
|
|
540 xvalue (nth 2 xvalue))
|
|
541 (if (math-realp xvalue)
|
|
542 (setq xstep 1)
|
|
543 (error "%s is not a suitable basis for %s" xname yname)))))
|
|
544 (or (math-realp yvalue)
|
|
545 (let ((arglist nil))
|
|
546 (setq yvalue (math-evaluate-expr yvalue))
|
|
547 (calc-default-formula-arglist yvalue)
|
|
548 (or arglist
|
|
549 (error "%s does not contain any unassigned variables" yname))
|
|
550 (and (cdr arglist)
|
|
551 (error "%s contains more than one variable: %s"
|
|
552 yname arglist))
|
|
553 (setq yvalue (math-expr-subst yvalue
|
|
554 (math-build-var-name (car arglist))
|
|
555 '(var DUMMY var-DUMMY)))))
|
|
556 (setq ycache (assoc yvalue calc-graph-data-cache))
|
|
557 (delq ycache calc-graph-data-cache)
|
|
558 (nconc calc-graph-data-cache
|
|
559 (list (or ycache (setq ycache (list yvalue)))))
|
|
560 (if (and (not (setq xvec (eq (car-safe xvalue) 'vec)))
|
|
561 refine (cdr (cdr ycache)))
|
|
562 (calc-graph-refine-2d)
|
|
563 (calc-graph-recompute-2d)))
|
|
564 )
|
|
565
|
|
566 (defun calc-graph-refine-2d ()
|
|
567 (setq keep-file nil
|
|
568 ycacheptr (cdr ycache))
|
|
569 (if (and (setq xval (calc-graph-find-command "xrange"))
|
|
570 (string-match "\\`\\[\\([0-9.eE+-]*\\):\\([0-9.eE+-]*\\)\\]\\'"
|
|
571 xval))
|
|
572 (let ((b2 (match-beginning 2))
|
|
573 (e2 (match-end 2)))
|
|
574 (setq xlow (math-read-number (substring xval
|
|
575 (match-beginning 1)
|
|
576 (match-end 1)))
|
|
577 xhigh (math-read-number (substring xval b2 e2))))
|
|
578 (if xlow
|
|
579 (while (and (cdr ycacheptr)
|
|
580 (Math-lessp (car (nth 1 ycacheptr)) xlow))
|
|
581 (setq ycacheptr (cdr ycacheptr)))))
|
|
582 (setq math-working-step-2 (1- (length ycacheptr)))
|
|
583 (while (and (cdr ycacheptr)
|
|
584 (or (not xhigh)
|
|
585 (Math-lessp (car (car ycacheptr)) xhigh)))
|
|
586 (setq var-DUMMY (math-div (math-add (car (car ycacheptr))
|
|
587 (car (nth 1 ycacheptr)))
|
|
588 2)
|
|
589 math-working-step (1+ math-working-step)
|
|
590 yval (math-evaluate-expr yvalue))
|
|
591 (setcdr ycacheptr (cons (cons var-DUMMY yval)
|
|
592 (cdr ycacheptr)))
|
|
593 (setq ycacheptr (cdr (cdr ycacheptr))))
|
|
594 (setq yp ycache
|
|
595 numsteps 1000000)
|
|
596 )
|
|
597
|
|
598 (defun calc-graph-recompute-2d ()
|
|
599 (setq ycacheptr ycache)
|
|
600 (if xvec
|
|
601 (setq numsteps (1- (length xvalue))
|
|
602 yvector nil)
|
|
603 (if (and (eq (car-safe xvalue) 'intv)
|
|
604 (math-constp xvalue))
|
|
605 (setq numsteps resolution
|
|
606 yp nil
|
|
607 xlow (nth 2 xvalue)
|
|
608 xhigh (nth 3 xvalue)
|
|
609 xstep (math-div (math-sub xhigh xlow)
|
|
610 (1- numsteps))
|
|
611 xvalue (nth 2 xvalue))
|
|
612 (error "%s is not a suitable basis for %s"
|
|
613 xname yname)))
|
|
614 (setq math-working-step-2 numsteps)
|
|
615 (while (>= (setq numsteps (1- numsteps)) 0)
|
|
616 (setq math-working-step (1+ math-working-step))
|
|
617 (if xvec
|
|
618 (progn
|
|
619 (setq xp (cdr xp)
|
|
620 xval (car xp))
|
|
621 (and (not (eq ycacheptr ycache))
|
|
622 (consp (car ycacheptr))
|
|
623 (not (Math-lessp (car (car ycacheptr)) xval))
|
|
624 (setq ycacheptr ycache)))
|
|
625 (if (= numsteps 0)
|
|
626 (setq xval xhigh) ; avoid cumulative roundoff
|
|
627 (setq xval xvalue
|
|
628 xvalue (math-add xvalue xstep))))
|
|
629 (while (and (cdr ycacheptr)
|
|
630 (Math-lessp (car (nth 1 ycacheptr)) xval))
|
|
631 (setq ycacheptr (cdr ycacheptr)))
|
|
632 (or (and (cdr ycacheptr)
|
|
633 (Math-equal (car (nth 1 ycacheptr)) xval))
|
|
634 (progn
|
|
635 (setq keep-file nil
|
|
636 var-DUMMY xval)
|
|
637 (setcdr ycacheptr (cons (cons xval (math-evaluate-expr yvalue))
|
|
638 (cdr ycacheptr)))))
|
|
639 (setq ycacheptr (cdr ycacheptr))
|
|
640 (if xvec
|
|
641 (setq yvector (cons (cdr (car ycacheptr)) yvector))
|
|
642 (or yp (setq yp ycacheptr))))
|
|
643 (if xvec
|
|
644 (setq xp xvalue
|
|
645 yvec t
|
|
646 yp (cons 'vec (nreverse yvector))
|
|
647 numsteps (1- (length xp)))
|
|
648 (setq numsteps 1000000))
|
|
649 )
|
|
650
|
|
651 (defun calc-graph-compute-3d ()
|
|
652 (if (setq yvec (eq (car-safe yvalue) 'vec))
|
|
653 (if (math-matrixp yvalue)
|
|
654 (progn
|
|
655 (setq numsteps (1- (length yvalue))
|
|
656 numsteps3 (1- (length (nth 1 yvalue))))
|
|
657 (if (eq (car-safe xvalue) 'vec)
|
|
658 (or (= (1- (length xvalue)) numsteps)
|
|
659 (error "%s has wrong length" xname))
|
|
660 (if (and (eq (car-safe xvalue) 'intv)
|
|
661 (math-constp xvalue))
|
|
662 (setq xvalue (calcFunc-index numsteps
|
|
663 (nth 2 xvalue)
|
|
664 (math-div
|
|
665 (math-sub (nth 3 xvalue)
|
|
666 (nth 2 xvalue))
|
|
667 (1- numsteps))))
|
|
668 (if (math-realp xvalue)
|
|
669 (setq xvalue (calcFunc-index numsteps xvalue 1))
|
|
670 (error "%s is not a suitable basis for %s" xname yname))))
|
|
671 (if (eq (car-safe y3value) 'vec)
|
|
672 (or (= (1- (length y3value)) numsteps3)
|
|
673 (error "%s has wrong length" y3name))
|
|
674 (if (and (eq (car-safe y3value) 'intv)
|
|
675 (math-constp y3value))
|
|
676 (setq y3value (calcFunc-index numsteps3
|
|
677 (nth 2 y3value)
|
|
678 (math-div
|
|
679 (math-sub (nth 3 y3value)
|
|
680 (nth 2 y3value))
|
|
681 (1- numsteps3))))
|
|
682 (if (math-realp y3value)
|
|
683 (setq y3value (calcFunc-index numsteps3 y3value 1))
|
|
684 (error "%s is not a suitable basis for %s" y3name yname))))
|
|
685 (setq xp nil
|
|
686 yp nil
|
|
687 zp nil
|
|
688 xvec t)
|
|
689 (while (setq xvalue (cdr xvalue) yvalue (cdr yvalue))
|
|
690 (setq xp (nconc xp (make-list (1+ numsteps3) (car xvalue)))
|
|
691 yp (nconc yp (cons 0 (copy-sequence (cdr y3value))))
|
|
692 zp (nconc zp (cons '(skip)
|
|
693 (copy-sequence (cdr (car yvalue)))))))
|
|
694 (setq numsteps (1- (* numsteps (1+ numsteps3)))))
|
|
695 (if (= (setq numsteps (1- (length yvalue))) 0)
|
|
696 (error "Can't plot an empty vector"))
|
|
697 (or (and (eq (car-safe xvalue) 'vec)
|
|
698 (= (1- (length xvalue)) numsteps))
|
|
699 (error "%s is not a suitable basis for %s" xname yname))
|
|
700 (or (and (eq (car-safe y3value) 'vec)
|
|
701 (= (1- (length y3value)) numsteps))
|
|
702 (error "%s is not a suitable basis for %s" y3name yname))
|
|
703 (setq xp xvalue
|
|
704 yp y3value
|
|
705 zp yvalue
|
|
706 xvec t))
|
|
707 (or (math-realp yvalue)
|
|
708 (let ((arglist nil))
|
|
709 (setq yvalue (math-evaluate-expr yvalue))
|
|
710 (calc-default-formula-arglist yvalue)
|
|
711 (setq arglist (sort arglist 'string-lessp))
|
|
712 (or (cdr arglist)
|
|
713 (error "%s does not contain enough unassigned variables" yname))
|
|
714 (and (cdr (cdr arglist))
|
|
715 (error "%s contains too many variables: %s" yname arglist))
|
|
716 (setq yvalue (math-multi-subst yvalue
|
|
717 (mapcar 'math-build-var-name
|
|
718 arglist)
|
|
719 '((var DUMMY var-DUMMY)
|
|
720 (var DUMMY2 var-DUMMY2))))))
|
|
721 (if (setq xvec (eq (car-safe xvalue) 'vec))
|
|
722 (setq numsteps (1- (length xvalue)))
|
|
723 (if (and (eq (car-safe xvalue) 'intv)
|
|
724 (math-constp xvalue))
|
|
725 (setq numsteps resolution
|
|
726 xvalue (calcFunc-index numsteps
|
|
727 (nth 2 xvalue)
|
|
728 (math-div (math-sub (nth 3 xvalue)
|
|
729 (nth 2 xvalue))
|
|
730 (1- numsteps))))
|
|
731 (error "%s is not a suitable basis for %s"
|
|
732 xname yname)))
|
|
733 (if (setq y3vec (eq (car-safe y3value) 'vec))
|
|
734 (setq numsteps3 (1- (length y3value)))
|
|
735 (if (and (eq (car-safe y3value) 'intv)
|
|
736 (math-constp y3value))
|
|
737 (setq numsteps3 resolution
|
|
738 y3value (calcFunc-index numsteps3
|
|
739 (nth 2 y3value)
|
|
740 (math-div (math-sub (nth 3 y3value)
|
|
741 (nth 2 y3value))
|
|
742 (1- numsteps3))))
|
|
743 (error "%s is not a suitable basis for %s"
|
|
744 y3name yname)))
|
|
745 (setq xp nil
|
|
746 yp nil
|
|
747 zp nil
|
|
748 xvec t)
|
|
749 (setq math-working-step 0)
|
|
750 (while (setq xvalue (cdr xvalue))
|
|
751 (setq xp (nconc xp (make-list (1+ numsteps3) (car xvalue)))
|
|
752 yp (nconc yp (cons 0 (copy-sequence (cdr y3value))))
|
|
753 zp (cons '(skip) zp)
|
|
754 y3step y3value
|
|
755 var-DUMMY (car xvalue)
|
|
756 math-working-step-2 0
|
|
757 math-working-step (1+ math-working-step))
|
|
758 (while (setq y3step (cdr y3step))
|
|
759 (setq math-working-step-2 (1+ math-working-step-2)
|
|
760 var-DUMMY2 (car y3step)
|
|
761 zp (cons (math-evaluate-expr yvalue) zp))))
|
|
762 (setq zp (nreverse zp)
|
|
763 numsteps (1- (* numsteps (1+ numsteps3)))))
|
|
764 )
|
|
765
|
|
766 (defun calc-graph-format-data ()
|
|
767 (while (<= (setq stepcount (1+ stepcount)) numsteps)
|
|
768 (if xvec
|
|
769 (setq xp (cdr xp)
|
|
770 xval (car xp)
|
|
771 yp (cdr yp)
|
|
772 yval (car yp)
|
|
773 zp (cdr zp)
|
|
774 zval (car zp))
|
|
775 (if yvec
|
|
776 (setq xval xvalue
|
|
777 xvalue (math-add xvalue xstep)
|
|
778 yp (cdr yp)
|
|
779 yval (car yp))
|
|
780 (setq xval (car (car yp))
|
|
781 yval (cdr (car yp))
|
|
782 yp (cdr yp))
|
|
783 (if (or (not yp)
|
|
784 (and xhigh (equal xval xhigh)))
|
|
785 (setq numsteps 0))))
|
|
786 (if is-splot
|
|
787 (if (and (eq (car-safe zval) 'calcFunc-xyz)
|
|
788 (= (length zval) 4))
|
|
789 (setq xval (nth 1 zval)
|
|
790 yval (nth 2 zval)
|
|
791 zval (nth 3 zval)))
|
|
792 (if (and (eq (car-safe yval) 'calcFunc-xyz)
|
|
793 (= (length yval) 4))
|
|
794 (progn
|
|
795 (or surprise-splot
|
|
796 (save-excursion
|
|
797 (set-buffer (get-buffer-create "*Gnuplot Temp*"))
|
|
798 (save-excursion
|
|
799 (goto-char (point-max))
|
|
800 (re-search-backward "^plot[ \t]")
|
|
801 (insert "set parametric\ns")
|
|
802 (setq surprise-splot t))))
|
|
803 (setq xval (nth 1 yval)
|
|
804 zval (nth 3 yval)
|
|
805 yval (nth 2 yval)))
|
|
806 (if (and (eq (car-safe yval) 'calcFunc-xy)
|
|
807 (= (length yval) 3))
|
|
808 (setq xval (nth 1 yval)
|
|
809 yval (nth 2 yval)))))
|
|
810 (if (and (Math-realp xval)
|
|
811 (Math-realp yval)
|
|
812 (or (not zval) (Math-realp zval)))
|
|
813 (progn
|
|
814 (setq blank nil
|
|
815 non-blank t)
|
|
816 (if (Math-integerp xval)
|
|
817 (insert (math-format-number xval))
|
|
818 (if (eq (car xval) 'frac)
|
|
819 (setq xval (math-float xval)))
|
|
820 (insert (math-format-number (nth 1 xval))
|
|
821 "e" (int-to-string (nth 2 xval))))
|
|
822 (insert " ")
|
|
823 (if (Math-integerp yval)
|
|
824 (insert (math-format-number yval))
|
|
825 (if (eq (car yval) 'frac)
|
|
826 (setq yval (math-float yval)))
|
|
827 (insert (math-format-number (nth 1 yval))
|
|
828 "e" (int-to-string (nth 2 yval))))
|
|
829 (if zval
|
|
830 (progn
|
|
831 (insert " ")
|
|
832 (if (Math-integerp zval)
|
|
833 (insert (math-format-number zval))
|
|
834 (if (eq (car zval) 'frac)
|
|
835 (setq zval (math-float zval)))
|
|
836 (insert (math-format-number (nth 1 zval))
|
|
837 "e" (int-to-string (nth 2 zval))))))
|
|
838 (insert "\n"))
|
|
839 (and (not (equal zval '(skip)))
|
|
840 (boundp 'var-PlotRejects)
|
|
841 (eq (car-safe var-PlotRejects) 'vec)
|
|
842 (nconc var-PlotRejects
|
|
843 (list (list 'vec
|
|
844 curve-num
|
|
845 stepcount
|
|
846 xval yval)))
|
|
847 (calc-refresh-evaltos 'var-PlotRejects))
|
|
848 (or blank
|
|
849 (progn
|
|
850 (insert "\n")
|
|
851 (setq blank t)))))
|
|
852 )
|
|
853
|
|
854 (defun calc-temp-file-name (num)
|
|
855 (while (<= (length calc-graph-file-cache) (1+ num))
|
|
856 (setq calc-graph-file-cache (nconc calc-graph-file-cache (list nil))))
|
|
857 (car (or (nth (1+ num) calc-graph-file-cache)
|
|
858 (setcar (nthcdr (1+ num) calc-graph-file-cache)
|
|
859 (list (make-temp-name
|
|
860 (concat calc-gnuplot-tempfile
|
|
861 (if (<= num 0)
|
|
862 (char-to-string (- ?A num))
|
|
863 (int-to-string num))))
|
|
864 nil))))
|
|
865 )
|
|
866
|
|
867 (defun calc-graph-delete-temps ()
|
|
868 (while calc-graph-file-cache
|
|
869 (and (car calc-graph-file-cache)
|
|
870 (file-exists-p (car (car calc-graph-file-cache)))
|
|
871 (condition-case err
|
|
872 (delete-file (car (car calc-graph-file-cache)))
|
|
873 (error nil)))
|
|
874 (setq calc-graph-file-cache (cdr calc-graph-file-cache)))
|
|
875 )
|
|
876
|
|
877 (defun calc-graph-kill-hook ()
|
|
878 (calc-graph-delete-temps)
|
|
879 (if calc-graph-prev-kill-hook
|
|
880 (funcall calc-graph-prev-kill-hook))
|
|
881 )
|
|
882
|
|
883 (defun calc-graph-show-tty (output)
|
|
884 "Default calc-gnuplot-plot-command for \"tty\" output mode.
|
|
885 This is useful for tek40xx and other graphics-terminal types."
|
|
886 (call-process-region 1 1 shell-file-name
|
|
887 nil calc-gnuplot-buffer nil
|
|
888 "-c" (format "cat %s >/dev/tty; rm %s" output output))
|
|
889 )
|
|
890
|
|
891 (defun calc-graph-show-dumb (&optional output)
|
|
892 "Default calc-gnuplot-plot-command for Pinard's \"dumb\" terminal type.
|
|
893 This \"dumb\" driver will be present in Gnuplot 3.0."
|
|
894 (interactive)
|
|
895 (save-window-excursion
|
|
896 (switch-to-buffer calc-gnuplot-buffer)
|
|
897 (delete-other-windows)
|
|
898 (goto-char calc-gnuplot-trail-mark)
|
|
899 (or (search-forward "\f" nil t)
|
|
900 (sleep-for 1))
|
|
901 (goto-char (point-max))
|
|
902 (re-search-backward "\f\\|^[ \t]+\\^$\\|G N U P L O T")
|
|
903 (setq found-pt (point))
|
|
904 (if (looking-at "\f")
|
|
905 (progn
|
|
906 (forward-char 1)
|
|
907 (if (eolp) (forward-line 1))
|
|
908 (or (calc-graph-find-command "time")
|
|
909 (calc-graph-find-command "title")
|
|
910 (calc-graph-find-command "ylabel")
|
|
911 (let ((pt (point)))
|
|
912 (insert-before-markers (format "(%s)" (current-time-string)))
|
|
913 (goto-char pt)))
|
|
914 (set-window-start (selected-window) (point))
|
|
915 (goto-char (point-max)))
|
|
916 (end-of-line)
|
|
917 (backward-char 1)
|
|
918 (recenter '(4)))
|
|
919 (or (boundp 'calc-dumb-map)
|
|
920 (progn
|
|
921 (setq calc-dumb-map (make-sparse-keymap))
|
|
922 (define-key calc-dumb-map "\n" 'scroll-up)
|
|
923 (define-key calc-dumb-map " " 'scroll-up)
|
|
924 (define-key calc-dumb-map "\177" 'scroll-down)
|
|
925 (define-key calc-dumb-map "<" 'scroll-left)
|
|
926 (define-key calc-dumb-map ">" 'scroll-right)
|
|
927 (define-key calc-dumb-map "{" 'scroll-down)
|
|
928 (define-key calc-dumb-map "}" 'scroll-up)
|
|
929 (define-key calc-dumb-map "q" 'exit-recursive-edit)
|
|
930 (define-key calc-dumb-map "\C-c\C-c" 'exit-recursive-edit)))
|
|
931 (use-local-map calc-dumb-map)
|
|
932 (setq truncate-lines t)
|
|
933 (message "Type `q'%s to return to Calc."
|
|
934 (if (eq (lookup-key (current-global-map) "\e#") 'calc-dispatch)
|
|
935 " or `M-# M-#'" ""))
|
|
936 (recursive-edit)
|
|
937 (bury-buffer "*Gnuplot Trail*"))
|
|
938 )
|
|
939
|
|
940 (defun calc-graph-clear ()
|
|
941 (interactive)
|
|
942 (if calc-graph-last-device
|
|
943 (if (or (equal calc-graph-last-device "x11")
|
|
944 (equal calc-graph-last-device "X11"))
|
|
945 (calc-gnuplot-command "set output"
|
|
946 (if (equal calc-graph-last-output "STDOUT")
|
|
947 ""
|
|
948 (prin1-to-string calc-graph-last-output)))
|
|
949 (calc-gnuplot-command "clear")))
|
|
950 )
|
|
951
|
|
952 (defun calc-graph-title-x (title)
|
|
953 (interactive "sX axis title: ")
|
|
954 (calc-graph-set-command "xlabel" (if (not (equal title ""))
|
|
955 (prin1-to-string title)))
|
|
956 )
|
|
957
|
|
958 (defun calc-graph-title-y (title)
|
|
959 (interactive "sY axis title: ")
|
|
960 (calc-graph-set-command "ylabel" (if (not (equal title ""))
|
|
961 (prin1-to-string title)))
|
|
962 )
|
|
963
|
|
964 (defun calc-graph-title-z (title)
|
|
965 (interactive "sZ axis title: ")
|
|
966 (calc-graph-set-command "zlabel" (if (not (equal title ""))
|
|
967 (prin1-to-string title)))
|
|
968 )
|
|
969
|
|
970 (defun calc-graph-range-x (range)
|
|
971 (interactive "sX axis range: ")
|
|
972 (calc-graph-set-range "xrange" range)
|
|
973 )
|
|
974
|
|
975 (defun calc-graph-range-y (range)
|
|
976 (interactive "sY axis range: ")
|
|
977 (calc-graph-set-range "yrange" range)
|
|
978 )
|
|
979
|
|
980 (defun calc-graph-range-z (range)
|
|
981 (interactive "sZ axis range: ")
|
|
982 (calc-graph-set-range "zrange" range)
|
|
983 )
|
|
984
|
|
985 (defun calc-graph-set-range (cmd range)
|
|
986 (if (equal range "$")
|
|
987 (calc-wrapper
|
|
988 (let ((val (calc-top-n 1)))
|
|
989 (if (and (eq (car-safe val) 'intv) (math-constp val))
|
|
990 (setq range (concat
|
|
991 (math-format-number (math-float (nth 2 val))) ":"
|
|
992 (math-format-number (math-float (nth 3 val)))))
|
|
993 (if (and (eq (car-safe val) 'vec)
|
|
994 (= (length val) 3))
|
|
995 (setq range (concat
|
|
996 (math-format-number (math-float (nth 1 val))) ":"
|
|
997 (math-format-number (math-float (nth 2 val)))))
|
|
998 (error "Range specification must be an interval or 2-vector")))
|
|
999 (calc-pop-stack 1))))
|
|
1000 (if (string-match "\\[.+\\]" range)
|
|
1001 (setq range (substring range 1 -1)))
|
|
1002 (if (and (not (string-match ":" range))
|
|
1003 (or (string-match "," range)
|
|
1004 (string-match " " range)))
|
|
1005 (aset range (match-beginning 0) ?\:))
|
|
1006 (calc-graph-set-command cmd (if (not (equal range ""))
|
|
1007 (concat "[" range "]")))
|
|
1008 )
|
|
1009
|
|
1010 (defun calc-graph-log-x (flag)
|
|
1011 (interactive "P")
|
|
1012 (calc-graph-set-log flag 0 0)
|
|
1013 )
|
|
1014
|
|
1015 (defun calc-graph-log-y (flag)
|
|
1016 (interactive "P")
|
|
1017 (calc-graph-set-log 0 flag 0)
|
|
1018 )
|
|
1019
|
|
1020 (defun calc-graph-log-z (flag)
|
|
1021 (interactive "P")
|
|
1022 (calc-graph-set-log 0 0 flag)
|
|
1023 )
|
|
1024
|
|
1025 (defun calc-graph-set-log (xflag yflag zflag)
|
|
1026 (let* ((old (or (calc-graph-find-command "logscale") ""))
|
|
1027 (xold (string-match "x" old))
|
|
1028 (yold (string-match "y" old))
|
|
1029 (zold (string-match "z" old))
|
|
1030 str)
|
|
1031 (setq str (concat (if (if xflag
|
|
1032 (if (eq xflag 0) xold
|
|
1033 (> (prefix-numeric-value xflag) 0))
|
|
1034 (not xold)) "x" "")
|
|
1035 (if (if yflag
|
|
1036 (if (eq yflag 0) yold
|
|
1037 (> (prefix-numeric-value yflag) 0))
|
|
1038 (not yold)) "y" "")
|
|
1039 (if (if zflag
|
|
1040 (if (eq zflag 0) zold
|
|
1041 (> (prefix-numeric-value zflag) 0))
|
|
1042 (not zold)) "z" "")))
|
|
1043 (calc-graph-set-command "logscale" (if (not (equal str "")) str)))
|
|
1044 )
|
|
1045
|
|
1046 (defun calc-graph-line-style (style)
|
|
1047 (interactive "P")
|
|
1048 (calc-graph-set-styles (and style (prefix-numeric-value style)) t)
|
|
1049 )
|
|
1050
|
|
1051 (defun calc-graph-point-style (style)
|
|
1052 (interactive "P")
|
|
1053 (calc-graph-set-styles t (and style (prefix-numeric-value style)))
|
|
1054 )
|
|
1055
|
|
1056 (defun calc-graph-set-styles (lines points)
|
|
1057 (calc-graph-init)
|
|
1058 (save-excursion
|
|
1059 (set-buffer calc-gnuplot-input)
|
|
1060 (or (calc-graph-find-plot nil nil)
|
|
1061 (error "No data points have been set!"))
|
|
1062 (let ((base (point))
|
|
1063 (mode nil) (lstyle nil) (pstyle nil)
|
|
1064 start end lenbl penbl)
|
|
1065 (re-search-forward "[,\n]")
|
|
1066 (forward-char -1)
|
|
1067 (setq end (point) start end)
|
|
1068 (goto-char base)
|
|
1069 (if (looking-at "[^,\n]*[^,\n \t]\\([ \t]+with\\)")
|
|
1070 (progn
|
|
1071 (setq start (match-beginning 1))
|
|
1072 (goto-char (match-end 0))
|
|
1073 (if (looking-at "[ \t]+\\([a-z]+\\)")
|
|
1074 (setq mode (buffer-substring (match-beginning 1)
|
|
1075 (match-end 1))))
|
|
1076 (if (looking-at "[ \ta-z]+\\([0-9]+\\)")
|
|
1077 (setq lstyle (string-to-int
|
|
1078 (buffer-substring (match-beginning 1)
|
|
1079 (match-end 1)))))
|
|
1080 (if (looking-at "[ \ta-z]+[0-9]+[ \t]+\\([0-9]+\\)")
|
|
1081 (setq pstyle (string-to-int
|
|
1082 (buffer-substring (match-beginning 1)
|
|
1083 (match-end 1)))))))
|
|
1084 (setq lenbl (or (equal mode "lines") (equal mode "linespoints"))
|
|
1085 penbl (or (equal mode "points") (equal mode "linespoints")))
|
|
1086 (if lines
|
|
1087 (or (eq lines t)
|
|
1088 (setq lstyle lines
|
|
1089 lenbl (>= lines 0)))
|
|
1090 (setq lenbl (not lenbl)))
|
|
1091 (if points
|
|
1092 (or (eq points t)
|
|
1093 (setq pstyle points
|
|
1094 penbl (>= points 0)))
|
|
1095 (setq penbl (not penbl)))
|
|
1096 (delete-region start end)
|
|
1097 (goto-char start)
|
|
1098 (insert " with "
|
|
1099 (if lenbl
|
|
1100 (if penbl "linespoints" "lines")
|
|
1101 (if penbl "points" "dots")))
|
|
1102 (if (and pstyle (> pstyle 0))
|
|
1103 (insert " " (if (and lstyle (> lstyle 0)) (int-to-string lstyle) "1")
|
|
1104 " " (int-to-string pstyle))
|
|
1105 (if (and lstyle (> lstyle 0))
|
|
1106 (insert " " (int-to-string lstyle))))))
|
|
1107 (calc-graph-view-commands)
|
|
1108 )
|
|
1109
|
|
1110 (defun calc-graph-zero-x (flag)
|
|
1111 (interactive "P")
|
|
1112 (calc-graph-set-command "noxzeroaxis"
|
|
1113 (and (if flag
|
|
1114 (<= (prefix-numeric-value flag) 0)
|
|
1115 (not (calc-graph-find-command "noxzeroaxis")))
|
|
1116 " "))
|
|
1117 )
|
|
1118
|
|
1119 (defun calc-graph-zero-y (flag)
|
|
1120 (interactive "P")
|
|
1121 (calc-graph-set-command "noyzeroaxis"
|
|
1122 (and (if flag
|
|
1123 (<= (prefix-numeric-value flag) 0)
|
|
1124 (not (calc-graph-find-command "noyzeroaxis")))
|
|
1125 " "))
|
|
1126 )
|
|
1127
|
|
1128 (defun calc-graph-name (name)
|
|
1129 (interactive "sTitle for current curve: ")
|
|
1130 (calc-graph-init)
|
|
1131 (save-excursion
|
|
1132 (set-buffer calc-gnuplot-input)
|
|
1133 (or (calc-graph-find-plot nil nil)
|
|
1134 (error "No data points have been set!"))
|
|
1135 (let ((base (point))
|
|
1136 start)
|
|
1137 (re-search-forward "[,\n]\\|[ \t]+with")
|
|
1138 (setq end (match-beginning 0))
|
|
1139 (goto-char base)
|
|
1140 (if (looking-at "[^,\n]*[^,\n \t]\\([ \t]+title\\)")
|
|
1141 (progn
|
|
1142 (goto-char (match-beginning 1))
|
|
1143 (delete-region (point) end))
|
|
1144 (goto-char end))
|
|
1145 (insert " title " (prin1-to-string name))))
|
|
1146 (calc-graph-view-commands)
|
|
1147 )
|
|
1148
|
|
1149 (defun calc-graph-hide (flag)
|
|
1150 (interactive "P")
|
|
1151 (calc-graph-init)
|
|
1152 (and (calc-graph-find-plot nil nil)
|
|
1153 (progn
|
|
1154 (or (looking-at "{")
|
|
1155 (error "Can't hide this curve (wrong format)"))
|
|
1156 (forward-char 1)
|
|
1157 (if (looking-at "*")
|
|
1158 (if (or (null flag) (<= (prefix-numeric-value flag) 0))
|
|
1159 (delete-char 1))
|
|
1160 (if (or (null flag) (> (prefix-numeric-value flag) 0))
|
|
1161 (insert "*")))))
|
|
1162 )
|
|
1163
|
|
1164 (defun calc-graph-header (title)
|
|
1165 (interactive "sTitle for entire graph: ")
|
|
1166 (calc-graph-set-command "title" (if (not (equal title ""))
|
|
1167 (prin1-to-string title)))
|
|
1168 )
|
|
1169
|
|
1170 (defun calc-graph-border (flag)
|
|
1171 (interactive "P")
|
|
1172 (calc-graph-set-command "noborder"
|
|
1173 (and (if flag
|
|
1174 (<= (prefix-numeric-value flag) 0)
|
|
1175 (not (calc-graph-find-command "noborder")))
|
|
1176 " "))
|
|
1177 )
|
|
1178
|
|
1179 (defun calc-graph-grid (flag)
|
|
1180 (interactive "P")
|
|
1181 (calc-graph-set-command "grid" (and (if flag
|
|
1182 (> (prefix-numeric-value flag) 0)
|
|
1183 (not (calc-graph-find-command "grid")))
|
|
1184 " "))
|
|
1185 )
|
|
1186
|
|
1187 (defun calc-graph-key (flag)
|
|
1188 (interactive "P")
|
|
1189 (calc-graph-set-command "key" (and (if flag
|
|
1190 (> (prefix-numeric-value flag) 0)
|
|
1191 (not (calc-graph-find-command "key")))
|
|
1192 " "))
|
|
1193 )
|
|
1194
|
|
1195 (defun calc-graph-num-points (res flag)
|
|
1196 (interactive "sNumber of data points: \nP")
|
|
1197 (if flag
|
|
1198 (if (> (prefix-numeric-value flag) 0)
|
|
1199 (if (equal res "")
|
|
1200 (message "Default resolution is %d."
|
|
1201 calc-graph-default-resolution)
|
|
1202 (setq calc-graph-default-resolution (string-to-int res)))
|
|
1203 (if (equal res "")
|
|
1204 (message "Default 3D resolution is %d."
|
|
1205 calc-graph-default-resolution-3d)
|
|
1206 (setq calc-graph-default-resolution-3d (string-to-int res))))
|
|
1207 (calc-graph-set-command "samples" (if (not (equal res "")) res)))
|
|
1208 )
|
|
1209
|
|
1210 (defun calc-graph-device (name flag)
|
|
1211 (interactive "sDevice name: \nP")
|
|
1212 (if (equal name "?")
|
|
1213 (progn
|
|
1214 (calc-gnuplot-command "set terminal")
|
|
1215 (calc-graph-view-trail))
|
|
1216 (if flag
|
|
1217 (if (> (prefix-numeric-value flag) 0)
|
|
1218 (if (equal name "")
|
|
1219 (message "Default GNUPLOT device is \"%s\"."
|
|
1220 calc-gnuplot-default-device)
|
|
1221 (setq calc-gnuplot-default-device name))
|
|
1222 (if (equal name "")
|
|
1223 (message "GNUPLOT device for Print command is \"%s\"."
|
|
1224 calc-gnuplot-print-device)
|
|
1225 (setq calc-gnuplot-print-device name)))
|
|
1226 (calc-graph-set-command "terminal" (if (not (equal name ""))
|
|
1227 name))))
|
|
1228 )
|
|
1229
|
|
1230 (defun calc-graph-output (name flag)
|
|
1231 (interactive "FOutput file name: \np")
|
|
1232 (cond ((string-match "\\<[aA][uU][tT][oO]$" name)
|
|
1233 (setq name "auto"))
|
|
1234 ((string-match "\\<[tT][tT][yY]$" name)
|
|
1235 (setq name "tty"))
|
|
1236 ((string-match "\\<[sS][tT][dD][oO][uU][tT]$" name)
|
|
1237 (setq name "STDOUT"))
|
|
1238 ((equal (file-name-nondirectory name) "")
|
|
1239 (setq name ""))
|
|
1240 (t (setq name (expand-file-name name))))
|
|
1241 (if flag
|
|
1242 (if (> (prefix-numeric-value flag) 0)
|
|
1243 (if (equal name "")
|
|
1244 (message "Default GNUPLOT output file is \"%s\"."
|
|
1245 calc-gnuplot-default-output)
|
|
1246 (setq calc-gnuplot-default-output name))
|
|
1247 (if (equal name "")
|
|
1248 (message "GNUPLOT output file for Print command is \"%s\"."
|
|
1249 calc-gnuplot-print-output)
|
|
1250 (setq calc-gnuplot-print-output name)))
|
|
1251 (calc-graph-set-command "output" (if (not (equal name ""))
|
|
1252 (prin1-to-string name))))
|
|
1253 )
|
|
1254
|
|
1255 (defun calc-graph-display (name)
|
|
1256 (interactive "sX display name: ")
|
|
1257 (if (equal name "")
|
|
1258 (message "Current X display is \"%s\"."
|
|
1259 (or calc-gnuplot-display "<none>"))
|
|
1260 (setq calc-gnuplot-display name)
|
|
1261 (if (calc-gnuplot-alive)
|
|
1262 (calc-gnuplot-command "exit")))
|
|
1263 )
|
|
1264
|
|
1265 (defun calc-graph-geometry (name)
|
|
1266 (interactive "sX geometry spec (or \"default\"): ")
|
|
1267 (if (equal name "")
|
|
1268 (message "Current X geometry is \"%s\"."
|
|
1269 (or calc-gnuplot-geometry "default"))
|
|
1270 (setq calc-gnuplot-geometry (and (not (equal name "default")) name))
|
|
1271 (if (calc-gnuplot-alive)
|
|
1272 (calc-gnuplot-command "exit")))
|
|
1273 )
|
|
1274
|
|
1275 (defun calc-graph-find-command (cmd)
|
|
1276 (calc-graph-init)
|
|
1277 (save-excursion
|
|
1278 (set-buffer calc-gnuplot-input)
|
|
1279 (goto-char (point-min))
|
|
1280 (if (re-search-forward (concat "^set[ \t]+" cmd "[ \t]*\\(.*\\)$") nil t)
|
|
1281 (buffer-substring (match-beginning 1) (match-end 1))))
|
|
1282 )
|
|
1283
|
|
1284 (defun calc-graph-set-command (cmd &rest args)
|
|
1285 (calc-graph-init)
|
|
1286 (save-excursion
|
|
1287 (set-buffer calc-gnuplot-input)
|
|
1288 (goto-char (point-min))
|
|
1289 (if (re-search-forward (concat "^set[ \t]+" cmd "[ \t\n]") nil t)
|
|
1290 (progn
|
|
1291 (forward-char -1)
|
|
1292 (end-of-line)
|
|
1293 (let ((end (point)))
|
|
1294 (beginning-of-line)
|
|
1295 (delete-region (point) (1+ end))))
|
|
1296 (if (calc-graph-find-plot t t)
|
|
1297 (if (eq (preceding-char) ?\n)
|
|
1298 (forward-char -1))
|
|
1299 (goto-char (1- (point-max)))))
|
|
1300 (if (and args (car args))
|
|
1301 (progn
|
|
1302 (or (bolp)
|
|
1303 (insert "\n"))
|
|
1304 (insert "set " (mapconcat 'identity (cons cmd args) " ") "\n"))))
|
|
1305 (calc-graph-view-commands)
|
|
1306 )
|
|
1307
|
|
1308 (defun calc-graph-command (cmd)
|
|
1309 (interactive "sGNUPLOT command: ")
|
|
1310 (calc-wrapper
|
|
1311 (calc-graph-init)
|
|
1312 (calc-graph-view-trail)
|
|
1313 (calc-gnuplot-command cmd)
|
|
1314 (accept-process-output)
|
|
1315 (calc-graph-view-trail))
|
|
1316 )
|
|
1317
|
|
1318 (defun calc-graph-kill (&optional no-view)
|
|
1319 (interactive)
|
|
1320 (calc-graph-delete-temps)
|
|
1321 (if (calc-gnuplot-alive)
|
|
1322 (calc-wrapper
|
|
1323 (or no-view (calc-graph-view-trail))
|
|
1324 (let ((calc-graph-no-wait t))
|
|
1325 (calc-gnuplot-command "exit"))
|
|
1326 (sit-for 1)
|
|
1327 (if (process-status calc-gnuplot-process)
|
|
1328 (delete-process calc-gnuplot-process))
|
|
1329 (setq calc-gnuplot-process nil)))
|
|
1330 )
|
|
1331
|
|
1332 (defun calc-graph-quit ()
|
|
1333 (interactive)
|
|
1334 (if (get-buffer-window calc-gnuplot-input)
|
|
1335 (calc-graph-view-commands t))
|
|
1336 (if (get-buffer-window calc-gnuplot-buffer)
|
|
1337 (calc-graph-view-trail t))
|
|
1338 (calc-graph-kill t)
|
|
1339 )
|
|
1340
|
|
1341 (defun calc-graph-view-commands (&optional no-need)
|
|
1342 (interactive "p")
|
|
1343 (or calc-graph-no-auto-view (calc-graph-init-buffers))
|
|
1344 (calc-graph-view calc-gnuplot-input calc-gnuplot-buffer (null no-need))
|
|
1345 )
|
|
1346
|
|
1347 (defun calc-graph-view-trail (&optional no-need)
|
|
1348 (interactive "p")
|
|
1349 (or calc-graph-no-auto-view (calc-graph-init-buffers))
|
|
1350 (calc-graph-view calc-gnuplot-buffer calc-gnuplot-input (null no-need))
|
|
1351 )
|
|
1352
|
|
1353 (defun calc-graph-view (buf other-buf need)
|
|
1354 (let (win)
|
|
1355 (or calc-graph-no-auto-view
|
|
1356 (if (setq win (get-buffer-window buf))
|
|
1357 (or need
|
|
1358 (and (eq buf calc-gnuplot-buffer)
|
|
1359 (save-excursion
|
|
1360 (set-buffer buf)
|
|
1361 (not (pos-visible-in-window-p (point-max) win))))
|
|
1362 (progn
|
|
1363 (bury-buffer buf)
|
|
1364 (bury-buffer other-buf)
|
|
1365 (let ((curwin (selected-window)))
|
|
1366 (select-window win)
|
|
1367 (switch-to-buffer nil)
|
|
1368 (select-window curwin))))
|
|
1369 (if (setq win (get-buffer-window other-buf))
|
|
1370 (set-window-buffer win buf)
|
|
1371 (if (eq major-mode 'calc-mode)
|
|
1372 (if (or need
|
|
1373 (< (window-height) (1- (screen-height))))
|
|
1374 (display-buffer buf))
|
|
1375 (switch-to-buffer buf)))))
|
|
1376 (save-excursion
|
|
1377 (set-buffer buf)
|
|
1378 (if (and (eq buf calc-gnuplot-buffer)
|
|
1379 (setq win (get-buffer-window buf))
|
|
1380 (not (pos-visible-in-window-p (point-max) win)))
|
|
1381 (progn
|
|
1382 (goto-char (point-max))
|
|
1383 (vertical-motion (- 6 (window-height win)))
|
|
1384 (set-window-start win (point))
|
|
1385 (goto-char (point-max)))))
|
|
1386 (or calc-graph-no-auto-view (sit-for 0)))
|
|
1387 )
|
|
1388 (setq calc-graph-no-auto-view nil)
|
|
1389
|
|
1390 (defun calc-gnuplot-check-for-errors ()
|
|
1391 (if (save-excursion
|
|
1392 (prog2
|
|
1393 (progn
|
|
1394 (set-buffer calc-gnuplot-buffer)
|
|
1395 (goto-char calc-gnuplot-last-error-pos))
|
|
1396 (re-search-forward "^[ \t]+\\^$" nil t)
|
|
1397 (goto-char (point-max))
|
|
1398 (setq calc-gnuplot-last-error-pos (point-max))))
|
|
1399 (calc-graph-view-trail))
|
|
1400 )
|
|
1401
|
|
1402 (defun calc-gnuplot-command (&rest args)
|
|
1403 (calc-graph-init)
|
|
1404 (let ((cmd (concat (mapconcat 'identity args " ") "\n")))
|
|
1405 (accept-process-output)
|
|
1406 (save-excursion
|
|
1407 (set-buffer calc-gnuplot-buffer)
|
|
1408 (calc-gnuplot-check-for-errors)
|
|
1409 (goto-char (point-max))
|
|
1410 (setq calc-gnuplot-trail-mark (point))
|
|
1411 (or (>= calc-gnuplot-version 3)
|
|
1412 (insert cmd))
|
|
1413 (set-marker (process-mark calc-gnuplot-process) (point))
|
|
1414 (process-send-string calc-gnuplot-process cmd)
|
|
1415 (if (get-buffer-window calc-gnuplot-buffer)
|
|
1416 (calc-graph-view-trail))
|
|
1417 (accept-process-output (and (not calc-graph-no-wait)
|
|
1418 calc-gnuplot-process))
|
|
1419 (calc-gnuplot-check-for-errors)
|
|
1420 (if (get-buffer-window calc-gnuplot-buffer)
|
|
1421 (calc-graph-view-trail))))
|
|
1422 )
|
|
1423 (setq calc-graph-no-wait nil)
|
|
1424
|
|
1425 (defun calc-graph-init-buffers ()
|
|
1426 (or (and calc-gnuplot-buffer
|
|
1427 (buffer-name calc-gnuplot-buffer))
|
|
1428 (setq calc-gnuplot-buffer (get-buffer-create "*Gnuplot Trail*")))
|
|
1429 (or (and calc-gnuplot-input
|
|
1430 (buffer-name calc-gnuplot-input))
|
|
1431 (setq calc-gnuplot-input (get-buffer-create "*Gnuplot Commands*")))
|
|
1432 )
|
|
1433
|
|
1434 (defun calc-graph-init ()
|
|
1435 (or (calc-gnuplot-alive)
|
|
1436 (let ((process-connection-type t)
|
|
1437 origin)
|
|
1438 (if calc-gnuplot-process
|
|
1439 (progn
|
|
1440 (delete-process calc-gnuplot-process)
|
|
1441 (setq calc-gnuplot-process nil)))
|
|
1442 (calc-graph-init-buffers)
|
|
1443 (save-excursion
|
|
1444 (set-buffer calc-gnuplot-buffer)
|
|
1445 (insert "\nStarting gnuplot...\n")
|
|
1446 (setq origin (point)))
|
|
1447 (setq calc-graph-last-device nil)
|
|
1448 (setq calc-graph-last-output nil)
|
|
1449 (condition-case err
|
|
1450 (let ((args (append (and calc-gnuplot-display
|
|
1451 (not (equal calc-gnuplot-display
|
|
1452 (getenv "DISPLAY")))
|
|
1453 (list "-display"
|
|
1454 calc-gnuplot-display))
|
|
1455 (and calc-gnuplot-geometry
|
|
1456 (list "-geometry"
|
|
1457 calc-gnuplot-geometry)))))
|
|
1458 (setq calc-gnuplot-process
|
|
1459 (apply 'start-process
|
|
1460 "gnuplot"
|
|
1461 calc-gnuplot-buffer
|
|
1462 calc-gnuplot-name
|
|
1463 args))
|
|
1464 (process-kill-without-query calc-gnuplot-process))
|
|
1465 (file-error
|
|
1466 (error "Sorry, can't find \"%s\" on your system."
|
|
1467 calc-gnuplot-name)))
|
|
1468 (save-excursion
|
|
1469 (set-buffer calc-gnuplot-buffer)
|
|
1470 (while (and (not (save-excursion
|
|
1471 (goto-char origin)
|
|
1472 (search-forward "gnuplot> " nil t)))
|
|
1473 (memq (process-status calc-gnuplot-process) '(run stop)))
|
|
1474 (accept-process-output calc-gnuplot-process))
|
|
1475 (or (memq (process-status calc-gnuplot-process) '(run stop))
|
|
1476 (error "Unable to start GNUPLOT process."))
|
|
1477 (if (save-excursion
|
|
1478 (goto-char origin)
|
|
1479 (re-search-forward
|
|
1480 "G N U P L O T.*\n.*version \\([0-9]+\\)\\." nil t))
|
|
1481 (setq calc-gnuplot-version (string-to-int (buffer-substring
|
|
1482 (match-beginning 1)
|
|
1483 (match-end 1))))
|
|
1484 (setq calc-gnuplot-version 1))
|
|
1485 (goto-char (point-max)))))
|
|
1486 (save-excursion
|
|
1487 (set-buffer calc-gnuplot-input)
|
|
1488 (if (= (buffer-size) 0)
|
|
1489 (insert "# Commands for running gnuplot\n\n\n")
|
|
1490 (or calc-graph-no-auto-view
|
|
1491 (eq (char-after (1- (point-max))) ?\n)
|
|
1492 (progn
|
|
1493 (goto-char (point-max))
|
|
1494 (insert "\n")))))
|
|
1495 )
|
|
1496
|