-
Notifications
You must be signed in to change notification settings - Fork 21
/
gnuplot.el
2096 lines (1817 loc) · 83.2 KB
/
gnuplot.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;; gnuplot.el --- Major-mode and interactive frontend for gnuplot -*- lexical-binding: t -*-
;; Copyright (C) 1998, 2011 Phil Type and Bruce Ravel, 1999-2012 Bruce Ravel
;; Author: Jon Oddie, Bruce Ravel, Phil Type
;; Maintainer: Maxime Tréca <maxime@gmail.com>, Daniel Mendler <mail@daniel-mendler.de>
;; Created: 1998
;; Version: 0.8.1
;; Keywords: data gnuplot plotting
;; URL: https://github.com/emacs-gnuplot/gnuplot
;; Package-Requires: ((emacs "25.1"))
;; 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This is a major mode for composing gnuplot scripts and displaying
;; their results using gnuplot. It supports features of recent Gnuplot
;; versions (5.0 and up), but should also work fine with older
;; versions.
;;
;; This version of gnuplot-mode has been tested mostly on GNU Emacs
;; 25.
;;
;; Gnuplot-mode now includes context-sensitive support for keyword
;; completion and, optionally, eldoc-mode help text. See the
;; commentary in gnuplot-context.el for more information. If you
;; don't find it useful, it can be turned off by customizing
;; `gnuplot-context-sensitive-mode'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Acknowledgements:
;; David Batty <DB> (numerous corrections)
;; Laurent Bonnaud <LB> (suggestions regarding font-lock rules)
;; Markus Dickebohm <MD> (suggested `gnuplot-send-line-and-forward')
;; Stephen Eglan <SE> (suggested the use of info-look,
;; contributed a bug fix regarding shutting
;; down the gnuplot process, improvement to
;; `gnuplot-send-line-and-forward')
;; Robert Fenk <RF> (suggested respecting continuation lines)
;; Michael Karbach <MK> (suggested trimming the gnuplot process buffer)
;; Alex Chan Libchen <AL> (suggested font-lock for plotting words)
;; Kuang-Yu Liu <KL> (pointed out buggy dependence on font-lock)
;; Hrvoje Niksic <HN> (help with defcustom arguments for insertions)
;; Andreas Rechtsteiner <AR> (pointed out problem with C-c C-v)
;; Michael Sanders <MS> (help with the info-look interface)
;; Jinwei Shen <JS> (suggested functionality in comint buffer)
;; Michael M. Tung <MT> (prompted me to add pm3d support)
;; Holger Wenzel <HW> (suggested using `gnuplot-keywords-when')
;; Wolfgang Zocher <WZ> (pointed out problem with gnuplot-mode + speedbar)
;; Jon Oddie <jjo> (indentation, inline images, context mode)
;; Maxime F. Treca <MFT> (package update, XEmacs deprecation)
;;
;; and especially to Lars Hecking <LH> for including gnuplot-mode
;; with the gnuplot 3.7-beta distribution and for providing me with
;; installation materials
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Code:
(require 'cl-lib)
(require 'comint)
(require 'custom)
(require 'easymenu)
(require 'info)
(require 'info-look)
(declare-function 'eldoc-add-command "eldoc")
(defgroup gnuplot nil
"Gnuplot-mode for Emacs."
:prefix "gnuplot-"
:group 'processes
:group 'applications
:group 'local
:link '(emacs-library-link :tag "Lisp File" "gnuplot.el")
:link '(url-link :tag "Homepage"
"https://github.com/emacs-gnuplot/gnuplot/")
:link '(custom-manual "(gnuplot)Top")
:link '(emacs-commentary-link :tag "Commentary" "gnuplot.el"))
(defgroup gnuplot-insertions nil
"Insert commands into gnuplot-scripts from a pull-down menu."
:prefix "gnuplot-insertions-"
:group 'gnuplot)
(defgroup gnuplot-hooks nil
"Hook variables used by `gnuplot-mode'."
:prefix "gnuplot-"
:group 'gnuplot)
(defcustom gnuplot-mode-hook nil
"Hook run when `gnuplot-mode' is entered."
:group 'gnuplot-hooks
:type 'hook)
(defcustom gnuplot-after-plot-hook (list #'gnuplot-trim-gnuplot-buffer)
"Hook run after gnuplot plots something.
This is the last thing done by the functions for plotting a line, a
region, a buffer, or a file."
:group 'gnuplot-hooks
:type 'hook)
;; comint hook suggested by <DB>
(defcustom gnuplot-comint-setup-hook nil
"Hook run after setting up the gnuplot buffer in comint mode.
So the configuration can be customised by the user."
:group 'gnuplot-hooks
:type 'hook)
(defcustom gnuplot-comint-mode-hook nil
"Hook run after setting up the gnuplot buffer in `gnuplot-comint-mode'.
By default this runs the hook named `gnuplot-comint-setup-hook',
for backward compatibility."
:group 'gnuplot-hooks
:type 'hook)
(defvar-local gnuplot-recently-sent nil
"This is a record of the most recent kind of text sent to gnuplot.
It takes as its value nil, `line', `region', `buffer', or `file'. It is
useful for functions included in `gnuplot-after-plot-hook'.")
(defcustom gnuplot-program "gnuplot"
"The name of the gnuplot executable."
:group 'gnuplot
:type 'string)
(defcustom gnuplot-program-args nil
"Whitespace-separated flags to pass to the gnuplot executable."
:group 'gnuplot
:type 'string)
(defcustom gnuplot-process-name "gnuplot"
"Name given to the gnuplot buffer and process."
:group 'gnuplot
:type 'string)
(defvar gnuplot-buffer nil
"The name of the buffer displaying the gnuplot process.")
(defvar gnuplot-process nil
"Variable holding the process handle.")
(defvar gnuplot-process-frame nil
"The frame for displaying the gnuplot process.
This is used when `gnuplot-display-process' is equal to `frame'.")
(defvar gnuplot-comint-recent-buffer nil
"The most recently plotted gnuplot script buffer.
This is used by the function that plot from the comint buffer. It is
reset every time something is plotted from a script buffer.")
(defcustom gnuplot-gnuplot-buffer "plot.gp"
"The name of the gnuplot scratch buffer opened by `gnuplot-make-buffer'."
:group 'gnuplot
:type 'string)
(defcustom gnuplot-display-process 'window
"This controls how the gnuplot process buffer is displayed.
The values are
\\='frame display gnuplot process in a separate frame
\\='window display gnuplot process in this frame but in another window
nil `gnuplot-process' is in the current frame but not displayed"
:group 'gnuplot
:type '(radio (const :tag "Separate frame" frame)
(const :tag "Separate window" window)
(const :tag "Not displayed" nil)))
(defcustom gnuplot-info-display 'window
"Determines how `gnuplot-info-lookup-symbol' displays the info file.
The values are
\\='frame display info file in a separate frame
\\='window display info file in another window
nil display info file in the current window"
:group 'gnuplot
:type '(radio (const :tag "Separate frame" frame)
(const :tag "Separate window" window)
(const :tag "This window" nil)))
(defcustom gnuplot-echo-command-line-flag
(not (string-match "msvc" (emacs-version)))
"Non-nil means the gnuplot subprocess echoes any input.
This sets the fall-back value of `comint-process-echoes'.
If `gnuplot-mode' cannot figure out what version number of gnuplot
this is, then the value of this variable will be used for
`comint-process-echos'. It seems that gnuplot 3.5 wants this to be
nil and 3.7 wants it to be t. If lines that you send to gnuplot from
the `gnuplot-mode' buffer are not appearing at the gnuplot prompt in
the process buffer, try toggling it. Also see the document string for
`comint-process-echos'. If you change this, kill the gnuplot process
and start it again."
:group 'gnuplot
:type 'boolean)
(defcustom gnuplot-insertions-show-help-flag nil
"Non-nil means to display certain help messages automatically.
These messages are shown after menu insertion of gnuplot commands."
:group 'gnuplot-insertions
:type 'boolean)
(defcustom gnuplot-delay 0.01
"Amount of time to delay before sending a new line to gnuplot.
This is needed so that the the line is not written in the gnuplot
buffer in advance of its prompt. Increase this number if the
prompts and lines are displayed out of order."
:group 'gnuplot
:type 'number)
(defcustom gnuplot-buffer-max-size 1000
"The maximum size in lines of the gnuplot process buffer.
Each time text is written in the gnuplot process buffer, lines are
trimmed from the beginning of the buffer so that the buffer is this
many lines long. The lines are deleted after the most recent lines
were interpretted by gnuplot. Setting to 0 turns off this feature."
:group 'gnuplot
:type 'integer)
(defcustom gnuplot-quote-character "\'"
"Quotation character used for inserting quoted strings.
Gnuplot can use single or double quotes. If you prefer to have the
filename insertion function never insert quotes for you, set this
to the empty string."
:group 'gnuplot
:type '(radio (const :tag "double quote" "\"")
(const :tag "single quote" "\'")
(const :tag "none" "" )))
(defcustom gnuplot-basic-offset 4
"Number of columns to indent lines inside a do- or if-else-block.
This applies only to new-style do- and if-statements using
braces. Commands continued over a linebreak using a backslash
are always indented to line up with the second word on the line
beginning the continued command."
:group 'gnuplot
:type 'integer)
(defvar gnuplot-info-frame nil)
;; with info-look, there is no need to carry this list around -- it
;; can be generated on the fly appropriate to the currently installed
;; version of gnuplot.info
(defvar gnuplot-keywords nil
"A list of keywords used in GNUPLOT.
These are set by `gnuplot-set-keywords-list' from the values in
`info-lookup-cache'.")
(defvar gnuplot-keywords-pending t ;; <HW>
"A boolean which gets toggled when the info file is probed.")
(defcustom gnuplot-keywords-when 'deferred ;; 'immediately
"This variable controls when the info file is parsed.
The choices are immediately upon starting `gnuplot-mode' or the first
time that data is needed."
:group 'gnuplot
:type
'(radio (const :tag "Parse info file when gnuplot-mode starts" immediately)
(const :tag "Parse info file the first time it is needed" deferred)))
(defcustom gnuplot-use-context-sensitive-completion t
"Non-nil if `gnuplot-context-sensitive-mode' should be enabled by default.
In context-sensitive mode, `gnuplot-mode' parses the current
command line to provide smarter completion and documentation
suggestions."
:group 'gnuplot
:type 'boolean
:set (lambda (sym value)
(set sym value)
(cond
(value
(add-hook 'gnuplot-mode-hook 'gnuplot-context-sensitive-mode nil nil)
(add-hook 'gnuplot-comint-mode-hook 'gnuplot-context-sensitive-mode nil nil))
(t
(remove-hook 'gnuplot-mode-hook 'gnuplot-context-sensitive-mode)
(remove-hook 'gnuplot-comint-mode-hook 'gnuplot-context-sensitive-mode)))
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (and (derived-mode-p 'gnuplot-mode 'gnuplot-comint-mode)
(fboundp 'gnuplot-context-sensitive-mode))
(gnuplot-context-sensitive-mode (if value 1 0))))))
:link '(emacs-commentary-link "gnuplot-context"))
(defcustom gnuplot-eldoc-mode nil
"Non-nil if ElDoc mode should be enabled by default in Gnuplot buffers.
ElDoc support requires `gnuplot-context-sensitive-mode' to be
on."
:group 'gnuplot
:type 'boolean)
(defcustom gnuplot-tab-completion nil
"Non-nil if TAB should perform completion in `gnuplot-mode' buffers.
Setting this to non-nil sets the `tab-always-indent' variable to the
symbol `complete' in `gnuplot-mode' buffers."
:group 'gnuplot
:type 'boolean)
(defun gnuplot-set-display-mode (variable value &rest _args)
"Customize :set function for `gnuplot-inline-image-mode'.
Set VARIABLE to VALUE. ARGS is optional args."
(if (and (eq variable 'gnuplot-inline-image-mode)
value
(not (display-images-p)))
(progn
(message "Displaying images is not supported.")
(set variable nil))
(set variable value))
(gnuplot-setup-comint-for-image-mode))
(defcustom gnuplot-inline-image-mode nil
"Whether to display Gnuplot output in Emacs.
Possible values are nil, `inline' and `dedicated'.
When this is nil, Gnuplot output is handled outside of Emacs in
the normal way. Otherwise, Emacs attempts to capture Gnuplot's
output and display it in a buffer. Output is inserted inline in
the Gnuplot interaction buffer it this is `inline', in a
separate dedicated buffer if it is `dedicated'.
Use Customize to set this variable, or the commands
`gnuplot-external-display-mode', `gnuplot-inline-display-mode',
and `gnuplot-dedicated-display-mode'."
:group 'gnuplot
:type '(radio
(const :tag "No" nil)
(const :tag "In Comint buffer" inline)
(const :tag "In dedicated buffer" dedicated))
:initialize #'custom-initialize-default
:set #'gnuplot-set-display-mode)
(defcustom gnuplot-image-format "png"
"Image format to use for displaying images within Emacs.
This will be sent directly to Gnuplot as a command of the form
\"set terminal <FORMAT>\". Common values are \"png\" and
\"svg\".
This only has an effect when `gnuplot-inline-image-mode' is
non-nil."
:group 'gnuplot
:type 'string
:initialize #'custom-initialize-default
:set #'gnuplot-set-display-mode)
(defgroup gnuplot-faces nil
"Text faces used by `gnuplot-mode'."
:prefix "gnuplot-"
:group 'gnuplot)
(defface gnuplot-prompt-face '((((class color))
(:foreground "firebrick"))
(t
(:bold t :underline t)))
"Face used for the prompt in the gnuplot process buffer."
:group 'gnuplot-faces)
;;; --- key bindings and menus
(defvar gnuplot-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-b" #'gnuplot-send-buffer-to-gnuplot)
(define-key map "\C-c\C-c" #'comment-region) ; <RF>
(define-key map "\C-c\C-o" 'gnuplot-gui-set-options-and-insert)
(define-key map "\C-c\C-e" #'gnuplot-show-gnuplot-buffer)
(define-key map "\C-c\C-f" #'gnuplot-send-file-to-gnuplot)
(define-key map "\C-c\C-d" #'gnuplot-info-lookup-symbol)
(define-key map "\C-c\C-i" #'gnuplot-insert-filename)
(define-key map "\C-c\C-j" #'gnuplot-forward-script-line)
(define-key map "\C-c\C-k" #'gnuplot-kill-gnuplot-buffer)
(define-key map "\C-c\C-l" #'gnuplot-send-line-to-gnuplot)
(define-key map "\C-c\C-n" #'gnuplot-negate-option)
(define-key map "\C-c\C-r" #'gnuplot-send-region-to-gnuplot)
(define-key map (kbd "C-M-x") #'gnuplot-send-line-to-gnuplot)
(define-key map "\C-c\C-v" #'gnuplot-send-line-and-forward)
(define-key map "\C-c\C-z" #'gnuplot-customize)
(define-key map "\C-i" #'indent-for-tab-command)
(define-key map "\C-m" #'newline-and-indent)
(define-key map (kbd "}") #'gnuplot-electric-insert)
(define-key map "\M-\r" #'completion-at-point)
(define-key map "\M-\t" #'completion-at-point)
(define-key map [S-mouse-2] 'gnuplot-gui-mouse-set)
map))
(defvar gnuplot-mode-menu nil)
(defvar gnuplot-display-options-menu
(cl-flet ((make-image-setter (type)
`[,(concat (upcase type) " images")
(lambda () (interactive) (gnuplot-set-image-format ,type))
:style toggle
:selected (eq gnuplot-image-format ,type)]))
`("Display plot output"
["Externally" gnuplot-external-display-mode
:style toggle
:selected (null gnuplot-inline-image-mode)]
["In Comint buffer" gnuplot-inline-display-mode
:active (display-images-p)
:style toggle
:selected (eq gnuplot-inline-image-mode 'comint)]
["In dedicated buffer" gnuplot-dedicated-display-mode
:style toggle
:selected (eq gnuplot-inline-image-mode 'dedicated)]
"---"
,@(mapcar #'make-image-setter (list "png" "jpeg" "svg"))
["Other image type..." gnuplot-set-image-format])))
(defvar gnuplot-menu
`("Gnuplot"
["Send line to gnuplot" gnuplot-send-line-to-gnuplot t]
["Send line & move forward" gnuplot-send-line-and-forward (not (eobp))]
["Send region to gnuplot" gnuplot-send-region-to-gnuplot
(gnuplot-mark-active)]
["Send buffer to gnuplot" gnuplot-send-buffer-to-gnuplot t]
["Send file to gnuplot" gnuplot-send-file-to-gnuplot t]
"---"
,gnuplot-display-options-menu
["Contextual completion and help" gnuplot-context-sensitive-mode
:style toggle
:selected gnuplot-context-sensitive-mode]
["Echo area help (eldoc-mode)" eldoc-mode
:active gnuplot-context-sensitive-mode
:style toggle
:selected eldoc-mode]
"---"
["Insert filename at point" gnuplot-insert-filename t]
["Negate set option" gnuplot-negate-option t]
["Keyword help" gnuplot-info-lookup-symbol
(or gnuplot-keywords gnuplot-keywords-pending)]
["Quick help for thing at point" gnuplot-help-function
gnuplot-context-sensitive-mode]
["Info documentation on thing at point"
gnuplot-info-at-point
gnuplot-context-sensitive-mode]
["Show gnuplot process buffer" gnuplot-show-gnuplot-buffer t]
["Set arguments at point" gnuplot-gui-set-options-and-insert t]
["Swap plot/splot/fit lists in GUI" gnuplot-gui-swap-simple-complete t]
"---"
["Customize gnuplot" gnuplot-customize t]
"---"
["Kill gnuplot" gnuplot-kill-gnuplot-buffer t])
"Menu for `gnuplot-mode'.")
;;; --- insertions variables and menus
(defvar gnuplot-mode-insertions-menu nil)
(defvar gnuplot-insertions-menu nil
"Menu for insertions in `gnuplot-mode'.
The insertions menu is composed of several sub-menus. The variables
describing the sub-menus are:
`gnuplot-insertions-adornments'
`gnuplot-insertions-plot-options'
`gnuplot-insertions-terminal'
`gnuplot-insertions-x-axis'
`gnuplot-insertions-y-axis'
`gnuplot-insertions-z-axis'
`gnuplot-insertions-x2-axis'
`gnuplot-insertions-y2-axis'
`gnuplot-insertions-parametric-plots'
`gnuplot-insertions-polar-plots'
`gnuplot-insertions-surface-plots'
These variables can be customized by the user. For example, there are
many terminal types which are not in the terminal submenu but which
may be compiled into your copy of gnuplot.
Each of these variables is a list whose first element is a string and
all the rest are vectors as described in the document string for
`easy-menu-define'. The callback used throughout these menus is
`gnuplot-insert' which inserts the appropriate set expression and,
optionally, looks up that item in the gnuplot info file.
The easiest way to customize the submenus is to use the custom
package. Just type \\[gnuplot-customize] and follow your nose.
You can also add new items to any of these sub-menus by adding to the
`with-eval-after-load' blocks in your .emacs file. Here is an example of
adding the \"regis\" terminal type to the terminal sub-menu:
(with-eval-after-load \\='gnuplot
(setq gnuplot-insertions-terminal
(append gnuplot-insertions-terminal
(list
[\"regis\"
(gnuplot-insert \"set terminal regis\")
t]))))")
(defvar gnuplot-insertions-top ()
"Top part of insertions menu.
See the document string for `gnuplot-insertions-menu'")
(defcustom gnuplot-insertions-menu-flag t
"Non-nil means to place the insertion menu in the menubar.
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type 'boolean)
(defcustom gnuplot-insertions-adornments ; this is icky...
'("adornments"
["arrow" (gnuplot-insert "set arrow ") t]
["bar" (gnuplot-insert "set bar") t]
["border" (gnuplot-insert "set border") t]
["boxwidth" (gnuplot-insert "set boxwidth ") t]
["format" (gnuplot-insert "set format ") t]
["grid" (gnuplot-insert "set grid") t]
["key" (gnuplot-insert "set key ") t]
["label" (gnuplot-insert "set label ") t]
["pointsize" (gnuplot-insert "set pointsize ") t]
["samples" (gnuplot-insert "set samples ") t]
["size" (gnuplot-insert "set size ") t]
["style" (gnuplot-insert "set style ") t]
["tics" (gnuplot-insert "set tics ") t]
["timefmt" (gnuplot-insert "set timefmt ") t]
["timestamp" (gnuplot-insert "set timestamp ") t]
["title" (gnuplot-insert "set title ") t]
["zeroaxis" (gnuplot-insert "set zeroaxis") t])
"Adornments submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-plot-options
'("plot options"
["autoscale" (gnuplot-insert "set autoscale ") t]
["clip" (gnuplot-insert "set clip ") t]
["encoding" (gnuplot-insert "set encoding ") t]
["locale" (gnuplot-insert "set locale ") t]
["logscale" (gnuplot-insert "set logscale ") t]
["multiplot" (gnuplot-insert "set multiplot") t]
["missing" (gnuplot-insert "set missing \"\"") t]
["palette" (gnuplot-insert "set palette ") t] ; <MT>
["pm3d" (gnuplot-insert "set pm3d ") t]
["offsets" (gnuplot-insert "set offsets ") t]
["output" (gnuplot-insert "set output ") t]
["zero" (gnuplot-insert "set zero ") t])
"Plot options submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-terminal
'("terminal"
["eepic" (gnuplot-insert "set terminal eepic") t]
["fig" (gnuplot-insert "set terminal fig") t]
["gpic" (gnuplot-insert "set terminal gpic") t]
["latex" (gnuplot-insert "set terminal latex") t]
["linux" (gnuplot-insert "set terminal linux") t]
["pbm" (gnuplot-insert "set terminal pbm") t]
["png" (gnuplot-insert "set terminal png") t]
["postscript" (gnuplot-insert "set terminal postscript") t]
["pslatex" (gnuplot-insert "set terminal pslatex") t]
["table" (gnuplot-insert "set terminal table") t]
["tek40xx" (gnuplot-insert "set terminal tek40xx") t]
["tkcanvas" (gnuplot-insert "set terminal tkcanvas") t]
["tpic" (gnuplot-insert "set terminal tpic") t]
["vgagl" (gnuplot-insert "set terminal vgagl") t] ; for pm3d patch
["vttek" (gnuplot-insert "set terminal vttek") t]
["x11" (gnuplot-insert "set terminal x11") t])
"Terminal submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-x-axis
'("x-axis"
["xdata" (gnuplot-insert "set xdata ") t]
["xlabel" (gnuplot-insert "set xlabel ") t]
["xrange" (gnuplot-insert "set xrange [:]") t]
["xtics" (gnuplot-insert "set xtics ") t]
["mxtics" (gnuplot-insert "set mxtics ") t]
["xzeroaxis" (gnuplot-insert "set xzeroaxis ") t]
["xdtics" (gnuplot-insert "set xdtics ") t]
["xmtics" (gnuplot-insert "set xmtics ") t])
"X-axis submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-x2-axis
'("x2-axis"
["x2data" (gnuplot-insert "set xdata ") t]
["x2label" (gnuplot-insert "set xlabel ") t]
["x2range" (gnuplot-insert "set xrange [:]") t]
["x2tics" (gnuplot-insert "set xtics ") t]
["mx2tics" (gnuplot-insert "set mxtics ") t]
["x2zeroaxis" (gnuplot-insert "set xzeroaxis ") t]
["x2dtics" (gnuplot-insert "set xdtics ") t]
["x2mtics" (gnuplot-insert "set xmtics ") t])
"X2-axis submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-y-axis
'("y-axis"
["ydata" (gnuplot-insert "set ydata ") t]
["ylabel" (gnuplot-insert "set ylabel ") t]
["ymtics" (gnuplot-insert "set ymtics ") t]
["yrange" (gnuplot-insert "set yrange [:]") t]
["ytics" (gnuplot-insert "set ytics ") t]
["yzeroaxis" (gnuplot-insert "set yzeroaxis ") t]
["ydtics" (gnuplot-insert "set ydtics ") t]
["mytics" (gnuplot-insert "set mytics ") t])
"Y-axis submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-y2-axis
'("y2-axis"
["y2data" (gnuplot-insert "set ydata ") t]
["y2label" (gnuplot-insert "set ylabel ") t]
["y2range" (gnuplot-insert "set yrange [:]") t]
["y2tics" (gnuplot-insert "set ytics ") t]
["my2tics" (gnuplot-insert "set mytics ") t]
["y2zeroaxis" (gnuplot-insert "set yzeroaxis ") t]
["y2mtics" (gnuplot-insert "set ymtics ") t]
["y2dtics" (gnuplot-insert "set ydtics ") t])
"Y2-axis submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-z-axis
'("z-axis"
["zdata" (gnuplot-insert "set zdata ") t]
["zlabel" (gnuplot-insert "set zlabel ") t]
["zrange" (gnuplot-insert "set zrange [:]") t]
["ztics" (gnuplot-insert "set ztics ") t]
["mztics" (gnuplot-insert "set mztics ") t]
["zdtics" (gnuplot-insert "set zdtics ") t]
["zmtics" (gnuplot-insert "set zmtics ") t])
"Z-axis submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-parametric-plots
'("parametric plots"
["parametric" (gnuplot-insert "set parametric") t]
["isosamples" (gnuplot-insert "set isosamples ") t]
["dummy" (gnuplot-insert "set dummy ") t]
["trange" (gnuplot-insert "set trange [:]") t]
["urange" (gnuplot-insert "set urange [:]") t]
["vrange" (gnuplot-insert "set vrange [:]") t])
"Parametric plots submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-polar-plots
'("polar plots"
["polar" (gnuplot-insert "set polar") t]
["angles" (gnuplot-insert "set angles ") t]
["rrange" (gnuplot-insert "set rrange [:]") t])
"Polar plots submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defcustom gnuplot-insertions-surface-plots
'("surface plots"
["clabel" (gnuplot-insert "set clabel ") t]
["cntrparam" (gnuplot-insert "set cntrparam ") t]
["contour" (gnuplot-insert "set contour") t]
["dgrid3d" (gnuplot-insert "set dgrid3d ") t]
["hidden3d" (gnuplot-insert "set hidden3d ") t]
["mapping" (gnuplot-insert "set mapping ") t]
["surface" (gnuplot-insert "set surface ") t]
["view" (gnuplot-insert "set view ") t])
"Surface plots submenu in the insertions menu.
See the document string for `gnuplot-insertions-menu'
Changing this will not effect a change in any currently existing
`gnuplot-mode' buffer. You will see the change the next time you
create a `gnuplot-mode' buffer."
:group 'gnuplot-insertions
:type '(list (string :tag "Title")
(repeat :inline t
(vector (string :tag "Name")
(function :tag "Callback")
(boolean :tag "Enabled" t)))))
(defvar gnuplot-insertions-bottom
'("---"
["Display of info with insertion" gnuplot-toggle-info-display
:style toggle :selected gnuplot-insertions-show-help-flag]
["Display GUI popup with insertion" gnuplot-gui-toggle-popup
:active t
:style toggle :selected gnuplot-gui-popup-flag])
"Bottom part of the insertions menu.
This part contains the toggle buttons for displaying info or
opening an argument-setting popup.")
(defun gnuplot-setup-menubar ()
"Initial setup of gnuplot and insertions menus."
(if gnuplot-insertions-menu-flag ; set up insertions menu
(progn
(setq gnuplot-insertions-top
'("insert set expression" "---"))
(setq gnuplot-insertions-menu
(append (list "Insertions")
gnuplot-insertions-top
(list gnuplot-insertions-adornments)
(list gnuplot-insertions-plot-options)
(list gnuplot-insertions-terminal)
(list gnuplot-insertions-x-axis)
(list gnuplot-insertions-y-axis)
(list gnuplot-insertions-z-axis)
(list gnuplot-insertions-x2-axis)
(list gnuplot-insertions-y2-axis)
(list gnuplot-insertions-parametric-plots)
(list gnuplot-insertions-polar-plots)
(list gnuplot-insertions-surface-plots)
gnuplot-insertions-bottom))
(easy-menu-define gnuplot-mode-insertions-menu gnuplot-mode-map
"Insertions menu used in Gnuplot-mode"
gnuplot-insertions-menu)))
(easy-menu-define ; set up gnuplot menu
gnuplot-mode-menu gnuplot-mode-map "Menu used in gnuplot-mode"
gnuplot-menu))
(defun gnuplot-mark-active ()
"Return non-nil if the mark is active and it is not equal to point."
(condition-case nil
(and (mark) (/= (mark) (point)))
(error nil)))
;;; --- syntax colorization, syntax table
(defvar gnuplot-mode-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?* "." table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?/ "." table)
(modify-syntax-entry ?% "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?: "." table)
(modify-syntax-entry ?& "." table )
(modify-syntax-entry ?^ "." table )
(modify-syntax-entry ?| "." table )
(modify-syntax-entry ?& "." table )
(modify-syntax-entry ?? "." table )
(modify-syntax-entry ?~ "." table )
(modify-syntax-entry ?_ "w" table )
(modify-syntax-entry ?\" "." table)
(modify-syntax-entry ?\' "." table)
(modify-syntax-entry ?` "." table)
(modify-syntax-entry ?\\ "." table)
table)
"Syntax table in use in `gnuplot-mode' buffers.
This is the same as the standard syntax table except that ` and _
are word characters, and math operators are punctuation
characters.")
;; Macro to generate efficient regexps for keyword matching
;;
;; These regular expressions treat the gnuplot vocabulary as complete
;; words. Although gnuplot will recognise unique abbreviations, these
;; regular expressions will not.
(defmacro gnuplot-make-regexp (list)
"Macro to generate efficient regexps for keyword matching from LIST."
`(regexp-opt ,list 'words))
;; Lists of gnuplot keywords for syntax coloring etc.
(defvar gnuplot-keywords-builtin-functions
'("abs" "acosh" "acos" "arg" "asinh" "asin" "atan" "atanh" "atan2" "besj1"
"besj0" "besy1" "besy0" "ceil" "column" "cosh" "cos" "erfc" "erf" "exp"
"floor" "gamma" "ibeta" "igamma" "imag" "int" "inverf" "invnorm" "lgamma"
"log" "log10" "norm" "rand" "real" "sgn" "sinh" "sin" "sqrt" "tanh" "tan"
"tm_hour" "tm_mday" "tm_min" "tm_mon" "tm_sec" "tm_wday" "tm_yday" "tm_year"
"valid" "EllipticPi" "EllipticE" "EllipticK" "words" "word" "value"
"timecolumn" "substr" "strstrt" "strptime" "strlen" "stringcolumn"
"strftime" "sprintf" "lambertw" "gprintf" "exists" "defined" "columnhead")
"List of GNUPLOT built-in functions, as strings.
These are highlighted using `font-lock-function-name-face'.")
(defvar gnuplot-keywords-plotting
'("axes" "every" "index" "lw" "lt" "ls" "linestyle" "linetype" "linewidth"
"notitle" "pt" "ps" "pointsize" "pointtype" "smooth" "thru" "title" "using"
"with" "noautoscale" "volatile" "matrix" "nonuniform" "binary" "fillstyle"
"linecolor" "pointinterval" "nosurface" "nocontours" "nohidden3d")
"List of GNUPLOT keywords associated with plotting, as strings.
These are highlighted using `font-lock-type-face'.
This list does not include plotting styles -- for that, see
`gnuplot-keywords-plotting-styles'")
(defvar gnuplot-keywords-plotting-styles
'("boxerrorbars" "boxes" "boxxyerrorbars" "candlesticks" "dots" "errorbars"
"financebars" "fsteps" "histeps" "impulses" "lines" "linespoints" "points"
"steps" "vector" "xerrorbars" "xyerrorbars" "yerrorbars" "vectors"
"filledcurves" "labels" "rgbalpha" "rgbimage" "image" "circles" "pm3d"
"histograms" "xyerrorlines" "xerrorlines" "errorlines" "yerrorlines")
"List of GNUPLOT plotting styles, as strings.
These are highlighted using `font-lock-function-name-face'.")
(defvar gnuplot-keywords-misc
'("bind" "cd" "clear" "exit" "fit" "help" "history" "load" "pause" "print"
"pwd" "quit" "replot" "save" "set" "show" "unset" "if" "else" "do" "update"
"undefine" "test" "system" "raise" "lower" "eval" "shell" "reset" "reread"
"refresh" "call")
"List of GNUPLOT miscellaneous commands, as strings.
These are highlighted using `font-lock-constant-face'.")
(defvar gnuplot-keywords-negatable-options
'("arrow" "autoscale" "border" "clabel" "clip" "contour" "dgrid3d" "grid"
"hidden3d" "historysize" "key" "label" "linestyle" "logscale" "mouse"
"multiplot" "mx2tics" "mxtics" "my2tics" "mytics" "mztics" "offsets" "polar"
"surface" "timestamp" "title" "x2dtics" "x2mtics" "x2tics" "x2zeroaxis"
"xdtics" "xmtics" "xtics" "xzeroaxis" "y2dtics" "y2mtics" "y2tics"
"y2zeroaxis" "ydtics" "ymtics" "ytics" "yzeroaxis" "zdtics" "zmtics" "ztics"
"zzeroaxis")
"List of gnuplot options which can be negated using `gnuplot-negate-option'.")
(defvar gnuplot-negatable-options-regexp
(gnuplot-make-regexp gnuplot-keywords-negatable-options))
;; Set up colorization for gnuplot.
(defvar gnuplot-font-lock-keywords
(list
;; stuff in brackets, sugg. by <LB>
'("\\[\\([^]]+\\)\\]" 1 font-lock-constant-face)
;; variable/function definitions
'("\\(\\(\\sw\\|\\s_\\)+\\s-*\\((\\s-*\\(\\sw\\|\\s_\\)*\\s-*\\(,\\s-*\\sw*\\)*\\s-*)\\)?\\s-*=\\)[^=]"
1 font-lock-variable-name-face)
;; built-in function names
(cons (gnuplot-make-regexp gnuplot-keywords-builtin-functions)
font-lock-function-name-face)
;; reserved words associated with plotting <AL>
(cons (gnuplot-make-regexp gnuplot-keywords-plotting)
font-lock-type-face)
(cons (gnuplot-make-regexp gnuplot-keywords-plotting-styles)
font-lock-function-name-face)
;; (s)plot -- also thing (s)plotted
'("\\<s?plot\\>" . font-lock-keyword-face)
;; '("\\<s?plot\\s-+\\([^'\" ]+\\)[) \n,\\\\]"
;; 1 font-lock-variable-name-face)
;; other common commands
(cons (gnuplot-make-regexp gnuplot-keywords-misc)
font-lock-constant-face)
(cons "!.*$" font-lock-constant-face))) ; what is this for? jjo
(defvar gnuplot-font-lock-defaults
'(gnuplot-font-lock-keywords
nil ; Use syntactic fontification
t ; Use case folding
nil ; No extra syntax
;; calls `gnuplot-beginning-of-continuation'
;; to find a safe place to begin syntactic highlighting
beginning-of-defun))
;; Some corner cases in Gnuplot's comment and string syntax are
;; difficult to handle accurately using Emacs's built-in syntax tables
;; and parser:
;;
;; - strings can continue over several lines, but only by using a
;; backslash to escape the newline
;;
;; - double-quoted strings can contain escaped quotes, \", and escaped
;; backslashes, \\; but in single-quoted strings the quote is
;; escaped by doubling it, '', and backslash is only special at
;; end-of-line
;;
;; - either type of string can end at newline without needing a
;; - closing delimiter
;;
;; - comments continue over continuation lines
;;
;; The following syntax-propertize rules should accurately mark string
;; and comment boundaries using the "generic string fence" and
;; "generic comment fence" syntax properties.
(defalias 'gnuplot-syntax-propertize
(syntax-propertize-rules
;; Double quoted strings
((rx
(group "\"")
(* (or (seq "\\" anything)
(not (any "\"" "\n"))))
(group (or "\"" "\n" buffer-end)))
(1 "|") (2 "|"))
;; Single quoted strings