-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathapdl-mode.el
3635 lines (3311 loc) · 140 KB
/
apdl-mode.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
;;; apdl-mode.el --- Major mode for the scripting language APDL -*- lexical-binding: t -*-
;; Time-stamp: <2021-10-23>
;; Copyright (C) 2006 - 2021 H. Dieter Wilhelm GPL V3
;; Author: H. Dieter Wilhelm <[email protected]>
;; Version: 20.7.0
;; Package-Requires: ((emacs "25.1"))
;; Keywords: languages, convenience, tools, Ansys, APDL
;; URL: https://github.com/dieter-wilhelm/apdl-mode
;; Maintainer: H. Dieter Wilhelm
;; Parts of this mode were originally base on octave-mod.el: Copyright
;; (C) 1997 Free Software Foundation, Inc. Author: Kurt Hornik
;; <[email protected]> Author: John Eaton
;; <[email protected]>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This code 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, or (at your
;; option) any later version.
;;
;; This lisp script 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.
;;
;; Permission is granted to distribute copies of this lisp script
;; provided the copyright notice and this permission are preserved in
;; all copies.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, you can either send email to this
;; program's maintainer or write to: The Free Software Foundation,
;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Commentary:
;; The GNU-Emacs major mode for the programming language APDL
;; APDL (Ansys Parametric Design Language) is the solver scripting
;; language of the FEA (Finite Element Analysis) suite Ansys (ANalysis
;; SYStem, registered TM https://www.ansys.com).
;; APDL-Mode (formerly ANSYS-Mode) represents, in conjunction with the
;; GNU-Emacs editor, an advanced APDL environment with features like
;; keyword completion, code templates, solver communication (GNU-Linux
;; only), license reporting, dedicated keybindings, etc.
;; Nowadays - with the advent of modern GUIs - I find APDL-Mode also
;; useful for studying solver (.dat) files which were created by
;; WorkBench. Likewise for writing WorkBench `Command' snippets and
;; inspecting longer snippets from other sources. Accessing swiftly the
;; Ansys APDL reference documentation alone is worth using APDL-Mode!
;; ------------------------------
;; First usage:
;; Please type `M-x apdl' to open a buffer under APDL-Mode. From this
;; buffer you can investigate the menu entries `APDL' and `Ansys' and
;; testing some APDL code.
;; The APDL-Mode help you'll find with typing `C-c C-h' together with a
;; brief tutorial.
;;; History:
;; Created: 2006-02
;; Please check the accompanying NEWS.org.
;;; Code:
(require 'apdl-keyword)
(require 'apdl-initialise)
(require 'apdl-process)
(require 'apdl-template)
(require 'apdl-wb-template)
(require 'outline)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; --- constants ---
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconst apdl-parameter-substitution-commands-regexp
"/TITLE\\|/STITLE\\|/COM\\|/AXLAB\\|/GCOLUMN\\|/TLABEL\\|/AN3D"
"Regexp of command names which have a string behind them.")
(defconst apdl-string-commands-regexp
"C\\*\\*\\*\\|/TITLE\\|/STITLE\\|/COM\\|/AXLAB\\|\
/GCOLUMN\\|/TLABEL\\|\\*ABBR\\|/AN3D"
"Regexp of command names which have a string behind them.")
(defconst apdl-variable-defining-commands ; association list
'(
("\\*ask\\w*" . "*ASK")
("\\<cm\\>" . "CM")
("\\<cmblock\\w*" . "CMBLOCK")
("\\*dim\\w*"."\\*DIM")
("/dir\\w*" . "/DIRECTORY")
("\\*do\\>" . "\\*DO")
("\\*dow\\w*" . "\\*DOWHILE")
("\\*get\\w*". "\\*GET")
("/inq\\w*"."/INQUIRE")
("\\*mfu\\w*"."*MFUN")
("\\*mop\\w*"."*MOPER")
("\\<path\\w*"."PATH")
("\\<page\\w*" "PAGET")
("\\<pdef\\w*"."PDEF")
("\\*sre\\w*"."*SREAD")
("\\*set.?"."*SET") ; Ansys inconsistency *SET works only with one
; additional character
("\\*top\\*w"."*TOPER")
("\\*vge\\w*"."*VGET") ; Not true in 14.0 variable must be
; dimensiond with *dim
("\\*vfu\\w*"."*VFUN")
("\\*vit\\w*"."*VITRP")
("\\*vop\\w*"."*VOPER")
("\\*vsc\\w*"."*VSCFUN")
("\\*vfi\\w*"."*vfill"))
"Alist for commands which define user variables.
In the form of (regexp . command_string), intentionally excluded
is the \"=\" assignment command.")
(defconst apdl-use-variables
'("ARG[1-9]" "AR[1][0-9]")
"Variable containing the APDL *USE variables regexp.
ARG[1-9] and AR[1][0-9] are macro local variables and can be
passed to the *USE command. Additionally AR[2-9][0-9] are pure
macro local variables.")
(defconst apdl-format-commands-regexp
"\\*[mM][sS][gG]\\|\\*[vV][rR][eE]\\|\\*[vV][wW][rR]\\|\\*[mM][wW][rR]"
"Regexp of command names which have one or more format lines.")
(defconst apdl-maintainer-address
"Dieter Wilhelm <[email protected]>" ; [email protected]
"Address of current maintainer of the APDL-Mode.")
(defconst apdl-comment-char ?!
"The APDL comment character.")
;; \sCODE,code
;; -:whitespace
;; <:commentstart
;; whitespace +
;; $
;; comment
;; digits
;; "^\\s-*\\($\\|\\s<\\|[+[:digit:]-]\\)"
(defconst apdl-non-code-line-regexp "^\\s-*\\($\\|\\s<\\|[+[:digit:]-]\\)"
"Regexp indicating a comment -, number - or an empty line.
A comment line contrasting a \"code comment\" which follows code
to be analysed from the Ansys solver/interpreter. A \"number
line\" is a line beginning with a number e. g. from an element
block or with a `+' or `-' sign.")
(defconst apdl-condensed-input-line-regexp ".*\\$"
"Regexp indicating a condensed input line.")
(defconst apdl-comment-start-skip "\\S<+\\S-*"
"Regexp to match the start of an APDL comment up to its body.
Used for the variable `comment-start-skip'.")
;; --- defcustoms ---
(require 'custom)
(defgroup APDL nil
"Customisation group for the APDL-Mode."
:version "20.5.0"
:link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
:link '(url-link :tag "Online documentation"
"https://dieter-wilhelm.github.io/apdl-mode ")
:link '(url-link :tag "Code on GitHub"
"https://github.com/dieter-wilhelm/apdl-mode")
:group 'Languages)
;; two minutes was too long, 2021-08-12
(defcustom apdl-parameter-help-duration "30"
"Duration for showing the `apdl-show-command-parameters' overlay.
The value is a string expressing a relative time span like \"2
hours 35 minutes\" or a number of seconds (\"30\") from now.
Acceptable time formats are those recognised by the function
`timer-duration'."
:type '(string number)
:group 'APDL)
(defcustom apdl-hide-region-before-string "![ ... hidden"
"String to mark the beginning of an invisible region.
This string is not really placed in the text, it is just shown in an
overlay"
:type '(string)
:group 'hide-region)
(defcustom apdl-hide-region-after-string " region ... ]"
"String to mark the beginning of an invisible region.
This string is not really placed in the text, it is just shown in an overlay"
:type '(string)
:group 'hide-region)
(defcustom apdl-hide-region-propertize-markers t
"If non-nil, add text properties (colour) to the region markers."
:type 'boolean
:group 'hide-region)
(defcustom apdl-highlighting-level 2
"This variable sets the level of highlighting.
There are three levels available, please see the variable
`font-lock-maximum-decoration'. Level 0 means a minimalist level
optimised for speed and working with very large files (like
solver input files from WorkBench), 1 and 2. Level 0 highlights
only the minimum (unambiguous) length of APDL command names and
variable definitions with the '=' operator. Level 1 highlights
complete command names, together with functions, elements,
deprecated elements, undocumented commands, strings from string
commands and the APDL operators. Level 2 is the same as 1,
except that all defined user variables and unambiguous command
names (also interpreter-ignored characters behind them) are
highlighted as well. The user variables are highlighted
\"statically\" only, newly defined variables are only taken into
account after `apdl-display-variables'
\(\\[apdl-display-variables]) is called, this updating is done
dynamically i. e. during editing when the variable
`apdl-dynamic-highlighting-flag' is set to t."
:type 'integer
:group 'APDL
:link '(variable-link 'font-lock-maximum-decoration))
;; link is only linked in the customisation buffer, sadly not it's
;; documentation string!
(defcustom apdl-dynamic-highlighting-flag t
"Non-nil means that APDL-Mode highlights user defined variables.
Warning: This option is computational expensive and --depending
on the file size and your hardware --it might make your editing
experience rather sluggish. Currently dynamic highlighting of
user variables is only implemented for files with the extensions
either \".mac\" \".inp\" or \".ans\". To take effect after
setting this variable you might have to restart `apdl-mode'."
:type 'boolean
:group 'APDL)
(defcustom apdl-indicate-empty-lines-flag nil
"Non-nil means indicate empty lines on window systems.
Do this visually at the end of an APDL buffer in the left
fringe. You have to reload function `apdl-mode' for this
variable to take effect."
:type 'boolean
:group 'APDL)
(defcustom apdl-comment-padding " "
"Padding string that `comment-dwim' puts between comment chars and text.
Extra spacing between the comment character(s) and the comment
text makes the comment easier to read. This padding is not
effective for code comments (comments behind code)."
:type 'string
:group 'APDL)
(defcustom apdl-comment-add 1
"How many additional comment characters are inserted by \\[comment-dwim].
This determines the default value of the numeric argument of
`comment-dwim'. It should generally stay 0, except for a few
modes like Lisp where it can be convenient to set it to 1 so that
regions are commented with two semi-colons."
:type 'integer
:group 'APDL)
;; nowadays (2021-08-16) 25 seems ugly and disconnected to the code
(defcustom apdl-code-comment-column 15
"Column where APDL code comments (behind code) are placed."
:type 'integer
:group 'APDL)
(defcustom apdl-auto-indent-flag t
"Non-nil means indent line when typing the SPC key.
The space character is also inserted."
:type 'boolean
;; :options '(t nil) ; not necessary with boolean in Customise
:group 'APDL)
(defcustom apdl-indent-comment-suffix ""
"String placed after the APDL comment char in an code comment.
See `apdl-indent-comment-string'."
:type 'string
:group 'APDL)
(defcustom apdl-ruler-wide-flag nil
"Non-nil means show a 80 characters wide temporary ruler.
Nil means show a narrower temporary ruler with 50 characters."
:type 'boolean
:group 'APDL)
(defcustom apdl-require-spaces-flag nil
"Non-nil means \\[insert-parentheses] inserts whitespace before ().
When there is a region marked then function `insert-parentheses'
inserts the parentheses around the active region."
:type 'boolean
:group 'APDL)
(defcustom apdl-blink-matching-block-flag t
"Non-nil means blinking of matching APDL block keywords.
Skip temporary to the matching beginning of the block when
inserting a newline after an *ELSE or *END keyword."
:type 'boolean
:group 'APDL)
(defcustom apdl-blink-matching-delay .7
"Time in seconds for skipping to a matching block.
See also the variable `apdl-blink-matching-block-flag'."
:type 'number
:group 'APDL)
(defcustom apdl-block-offset 2
"Indentation column(s) for statements in a block structure."
:type 'integer
;; :options only for types hook, plist and alist
:group 'APDL)
(defcustom apdl-outline-string "@"
"String specifying outline headings (see `outline-regexp').
Together with the Ansys comment sign '!' at a line beginning.
Per default, the outline heading looks like '!@', subheadings
'!@@' and so forth."
:type 'string
:group 'APDL)
(defcustom apdl-mode-hook '(apdl-outline-minor-mode)
"Normal hook run before entering APDL-Mode.
A hook is a variable which holds a collection of functions."
:type 'hook
:options '(apdl-show-paren-mode apdl-outline-minor-mode
apdl-ruler-mode apdl-auto-insert-mode)
:group 'APDL)
(require 'align)
(defcustom apdl-align-rules-list
'(
(apdl-align-=
(regexp . "\\(\\s-*\\)=")
(modes . '(apdl-mode))
(justify . t)
(tab-stop . nil))
(apdl-align-text-column
(regexp . "=\\(\\s-*[0-9]+\\|\\s-*\\)")
(modes . '(apdl-mode))
(justify . t)
(tab-stop . nil))
(apdl-align-comment
(regexp . "[0-9.)]+\\(\\s-*\\)\\!")
(modes . '(apdl-mode))
(tab-stop . nil)))
"Rules for aligning APDL variable definitions."
:type align-rules-list-type
:group 'apdl-mode)
;; (put 'my-align-rules-list 'risky-local-variable t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; --- variables ---
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar apdl-overlay-str ""
"Variable to store previous overlay string.")
(defvar apdl-hide-region-overlays nil
"Variable to store the regions we put an overlay on.")
(defvar apdl-help-overlay nil
"Overlay for displaying the Ansys parameter help.")
(defvar apdl-timer nil
"Timer variable to set up a timer for overlay clearing.
Please have a look at the function `apdl-manage-overlay'.")
(defvar apdl-indent-comment-string
(concat (char-to-string apdl-comment-char) apdl-indent-comment-suffix)
"String to insert when creating an APDL code comment.")
(defvar apdl-user-variables nil
"Variable containing the user variables and line No of first occurrence.
The list is used for the display of these
variables (`apdl-display-variables').")
(defvar apdl-user-variable-regexp nil
"Variable containing the user variables regexp.
The regexp is used for the
fontification (`apdl-highlight-variable') of these variables.")
(defvar apdl-is-unix-system-flag nil
"Non-nil means the computer runs a Unix system.
Any of GNU-Linux, aix, berkeley-unix, hpux, irix, lynxos 3.0.1 or
usg-unix-v.")
(defvar apdl-previous-major-mode ""
"The buffer's previous major mode (before APDL-Mode).")
(defvar apdl-mode-abbrev-table nil
"Abbreviation definition table for the APDL-Mode.
All APDL abbrevs start with a grave accent \"`\". \"`?\" lists
the currently defined abbreviations.")
(defvar apdl-parameter-help-position) ; for the compiler
(defvar-local apdl-parameter-help-position 1
"Cursor position in -show-command-parameters.")
;;; --- constants ---
(defconst apdl-continuation-line-regexp ".*?&\\s-*$"
"Regexp indicating a continuation line (of the *MSG command).")
(defconst apdl-else-keywords
'("\\*[eE][lL][sS][eE][iI][fF]" "\\*[eE][lL][sS][eE]"
"\\*[cC][yY][cC][lL][eE]")
"Regexps describing APDL block else keywords.")
(defconst apdl-end-keywords
'("\\*[eE][nN][dD][dD][oO]" "\\*[eE][nN][dD][iI][fF]"
"\\*[eE][nN][dD]")
"Regexps describing APDL end keywords.")
(defconst apdl-number-line-regexp
"^\\s-*[(+-]?[[:digit:]]"
"Regexp describing an APDL number line.
Used for skipping pure number lines and CMBLOCK format strings")
(defconst apdl-block-else-regexp
(concat "\\("
(mapconcat #'identity apdl-else-keywords "\\|")
"\\)\\>")
"Regexp containing the APDL else keywords.")
(defconst apdl-block-end-regexp
(concat "\\("
(mapconcat #'identity apdl-end-keywords "\\|")
"\\)\\>")
"Regexp containing the APDL end keywords.")
(defconst apdl-block-begin-or-end-regexp
(concat apdl-block-begin-regexp "\\|" apdl-block-end-regexp)
"Regexp containing APDL begin and end keywords.")
(defconst apdl-block-else-or-end-regexp
(concat apdl-block-else-regexp "\\|" apdl-block-end-regexp)
"Regexp containing the APDL else or end keywords.")
(defconst apdl-block-match-alist
'(("*IF" . ("THEN" "*ELSE" "*ELSEIF" "*ENDIF"))
("*DO" . ("*ENDDO"))
("*DOWHILE" . ("*ENDDO"))
("*CREATE" . ("*END")))
"Alist with APDL's matching block keywords.
It has APDL's begin keywords as keys and a list of the
corresponding else or end keywords as associated values.")
(defconst apdl-column-ruler-wide
(propertize
(concat
"0 10 20 30 40 50 60 \
70 80\n"
"| | | | | | | | | | | | | | \
| | |\n")
'font-lock-face 'bold)
"Contains the string for the wide ruler.
Ruler strings are displayed above the current line with
\\[apdl-column-ruler].")
(defconst apdl-column-ruler-narrow
(propertize
(concat
"0 10 20 30 40 50\n"
"| | | | | | | | | | |\n")
'font-lock-face 'bold)
"Narrow ruler string.
Ruler strings are displayed above the current line with \\[apdl-column-ruler].")
(when (> emacs-major-version 21)
(add-to-list 'insert-pair-alist '(?\* ?\*))
(add-to-list 'insert-pair-alist '(?\$ ?\$))
(add-to-list 'insert-pair-alist '(?\% ?\%)))
(defconst apdl-mode-map ;keybindings, keyboard shortcuts
(let ((map (make-sparse-keymap)))
(define-key map "`" 'apdl-abbrev-start) ; ``?' lists abbrevs
(define-key map "\M-?" 'apdl-show-command-parameters)
(define-key map "\C-\M-i" 'apdl-complete-symbol)
;; --- changed standard Emacs keybindings ---
(define-key map " " 'apdl-electric-space) ; needed for abbrevs
(define-key map "\M-j" 'apdl-indent-format-line)
(define-key map "\n" 'apdl-reindent-then-newline-and-indent)
;; end block indentation
;; --- especially interesting for continuation lines and condensed
;; --- input
(define-key map "\M-a" 'apdl-command-start)
(define-key map "\M-e" 'apdl-command-end)
;; -- adaption of mark-paragraph
(define-key map "\M-h" 'apdl-mark-paragraph)
;; --- command movement --- (like defuns), skip comments and empty
;; --- lines
(define-key map "\M-n" 'apdl-next-code-line)
(define-key map "\M-p" 'apdl-previous-code-line)
;; --- block movements ---
(define-key map "\C-\M-b" 'apdl-previous-block-start-and-conditional)
(define-key map "\C-\M-d" 'apdl-down-block)
(define-key map "\C-\M-f" 'apdl-next-block-end)
(define-key map "\C-\M-h" 'apdl-mark-block) ; formerly mark defun
(define-key map "\C-\M-n" 'apdl-skip-block-forward)
(define-key map "\C-\M-p" 'apdl-skip-block-backwards)
(define-key map "\C-\M-u" 'apdl-up-block)
;; --- further block keys ---
(define-key map "\C-c]" 'apdl-close-block)
(define-key map "\C-c}" 'apdl-number-block-end)
(define-key map "\C-c{" 'apdl-number-block-start)
;; --- pairs
(define-key map [?\M-\"] 'insert-pair)
(define-key map "\C-c[" 'insert-pair)
(define-key map "\C-c'" 'insert-pair)
(define-key map "\C-c%" 'insert-pair)
;; (define-key map [?\C-c?\C-%] 'insert-pair)
;; (define-key map [?\C-c?\C-[] 'insert-pair)
;; (define-key map [?\C-c?\C-'] 'insert-pair)
;; --- miscellaneous ---
;; for emacs < 28
(when (version< "28" emacs-version)
(define-key map (kbd "TAB")
`(menu-item "" outline-cycle
:filter ,(lambda (cmd)
(when (apdl-on-heading-p) cmd))))
(when (fboundp 'outline-cycle-buffer) ; sooth compiler version < emacs-28
(define-key map (kbd "<backtab>") #'outline-cycle-buffer)))
;; above is not set by outline-minor-mode!! Borrowed from
;; outline.el emacs-28.1
(define-key map [?\C-c?\C-+] 'apdl-zoom-in)
(define-key map [?\C-c?\C--] 'apdl-zoom-out)
(define-key map [?\C-c?\C-<] 'apdl-move-left)
(define-key map [?\C-c?\C->] 'apdl-move-right)
(define-key map [?\C-c?\C-^] 'apdl-move-up)
(define-key map [?\C-c?\C-_] 'apdl-move-down)
(define-key map "\C-x4k" 'apdl-delete-other-window)
(define-key map "\C-c\C-a" 'apdl-align)
(define-key map "\C-c\C-b" 'apdl-browse-apdl-help)
(define-key map "\C-c\C-c" 'apdl-send-to-ansys)
(define-key map "\C-c\C-d" 'apdl-do)
(define-key map "\C-c\C-e" 'apdl-display-error-file)
(define-key map "\C-c\C-f" 'apdl-fit)
;; (define-key map "\C-c\C-g" 'apdl-start-graphics) ; reserved
(define-key map "\C-c\C-h" 'apdl-mode-help) ; reserved, C-h no
;; (define-key map "\C-c\C-i" 'apdl-iso-view) ; reserved: C-tab
;; (define-key map "\C-c\C-i" 'apdl-if)
(define-key map "\C-c\C-j" 'apdl-send-to-apdl-and-proceed) ; same as ESS
;; was: (define-key map "\C-c\C-j" (if (boundp 'apdl-job) 'apdl-job))
(define-key map "\C-c\C-k" 'apdl-kill-ansys)
(define-key map "\C-c\C-l" 'apdl-license-status)
(define-key map "\C-c\C-m" 'apdl-start-ansys) ; == C-c RET!!
(define-key map "\C-c\C-n" 'apdl-no-of-processors)
(define-key map "\C-c\C-o" 'apdl-display-out-file)
(define-key map "\C-c\C-p" 'apdl-start-pzr-box) ; pan-zoom-rotate
(define-key map "\C-c\C-q" 'apdl-query-apdl-command)
(define-key map "\C-c\C-r" 'apdl-replot)
(define-key map "\C-c\C-s" 'apdl-display-skeleton)
(define-key map "\C-c\C-t" 'apdl-license)
(define-key map "\C-c\C-u" 'apdl-copy-or-send-above)
(define-key map "\C-c\C-v" 'apdl-display-variables)
(define-key map "\C-c\C-w" 'apdl-display-wb-skeleton) ; or aim:
; runwb2--aim?
(define-key map "\C-c\C-x" 'apdl-start-classics)
(define-key map "\C-c\C-y" 'apdl-start-batch-run)
;; (define-key map "\C-c\C-z" 'apdl-start-anslic_admin)
;; redundant with C-c C-l
(define-key map "\C-c\C-z" 'apdl-user-license-status)
;; (define-key map "\C-c\C-z" 'apdl-start-aim)
;; (define-key map [f1] 'describe-mode) ; [f1] reserved for user
map)
"Keymap for the APDL-Mode.")
;; borrowed from outline.el 2021-09
(defun apdl-on-heading-p (&optional invisible-ok)
"Return t if point is on a (visible) heading line.
If INVISIBLE-OK is non-nil, an invisible heading line is ok too."
(save-excursion
(beginning-of-line)
(and (bolp) (or invisible-ok (not (outline-invisible-p)))
(looking-at outline-regexp))))
(defun apdl-toggle-mode nil ; -FIXME- this toggles also all ansys
; minor-hooks?
"Restore the buffer's previous major mode, if possible."
(interactive)
(if (or (string= apdl-previous-major-mode "apdl-mode")
(string= apdl-previous-major-mode ""))
(error "There was no previous major mode except \"APDL-Mode\"")
;; buffers opened with auto-mode
(funcall apdl-previous-major-mode)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- font locking stuff ---
(defvar apdl-command-regexp)
(defvar apdl-command-regexp)
(defvar apdl-deprecated-element-regexp)
(defvar apdl-undocumented-command-regexp)
(defvar apdl-get-function-regexp)
(defvar apdl-command-regexp-1)
(defvar apdl-command-regexp-2a)
(defvar apdl-command-regexp-2b)
(defvar apdl-command-regexp-2c)
(defvar apdl-element-regexp)
(defvar apdl-parametric-function-regexp)
(defvar apdl-dynamic-prompt)
(defvar apdl-completions)
(defface apdl-arg-face
'((((min-colors 88) (class color) (background light))
:foreground "red1")
(((class color) (background light))
:foreground "red")
(((min-colors 88) (class color) (background dark))
:foreground "yellow1")
(((class color) (background dark))
:foreground "yellow")
(t
:weight bold))
"Face for highlighting local variables AR(G), _return, ..."
:group 'apdl-faces)
(defvar apdl-arg-face 'apdl-arg-face
"Face name to use for local vars AR(G), _return, ...")
(let (;; = variable defs + reserved _names
;; we need something behind the = otherwise it's a cleanup
;; variables + reserved _names (max. 32 chars long)
(variable_r
"^\\s-*\\([[:alpha:]_][[:alnum:]_]\\{0,31\\}\\)\\s-*=")
;; reserved vars consisting of a single "_" are valid in Ansys 12.1
(reserved_vars_r
"\\_<\\(_[[:alnum:]_]\\{0,31\\}\\>\\)"))
;; font-lock-keyword-face is the default face
(defconst apdl-font-lock-keywords
`(
(,variable_r 1 font-lock-variable-name-face); overwriting commands
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-command-regexp
"\\)") 1 font-lock-keyword-face)))
(defconst apdl-font-lock-keywords-1
`(
;; /eof is special: it crashes Ansys in interactive mode
;; -TODO- /eof is highlighted only first in line not behind $
("\\(?:^\\|\\$\\)\\s-*\\(/[eE][oO][fF].*\\)" 1 'trailing-whitespace t)
;; deprecated ansys * comment with 12.1 fini * bla : returns "* no
;; longer valid as comment character - please use !" * bla :
;; returns a warning *bla is not a command bla = 3 * 4 : returns
;; still 3!
("[[:alnum:]_]+\\s-+\\(\\*.*$\\)" 1 font-lock-comment-face prepend)
;; ^[:alnum:] to avoid spurious
;; asterisk command fontification
;; some string faces
("\\(?:^\\|\\$\\)\\s-*\\(?:/TIT\\|/TITL\\|/TITLE\\)\\s-*,\\(.*\\)$" 1
font-lock-doc-face t) ; titles
("\\(?:^\\|\\$\\)\\s-*/[cC][oO][mM].?\\(.\\{0,75\\}\\)"
1 font-lock-doc-face t)
;; highlight message of comment command /COM (no comment (!)
;; is possible behind /COM), no separating comma necessary
(apdl-higlight-percent-and-ampersand (0 'font-lock-type-face t))
;; /SYS command sends string to OP,no parameter substitution!
("^\\s-*/[sS][yY][sS]\\s-*,\\(.\\{1,75\\}\\)$" 1
font-lock-doc-face t)
;; TODO: c*** should get fontification from command regexp
("^\\s-*\\([cC]\\*\\*\\*\\)[ ,]?\\(.\\{1,75\\}\\)"
(1 font-lock-keyword-face t) (2 font-lock-doc-face t))
;; only 75 characters possible no separator necessary
("\\<\\(ARG[1-9]\\|AR[1][0-9]\\)\\>" . apdl-arg-face)
;; elements
(,apdl-deprecated-element-regexp . font-lock-warning-face)
(,apdl-element-regexp . font-lock-builtin-face)
;; reserved vars consisting of a single "_" are valid in A. 12.1
(,reserved_vars_r 1 font-lock-warning-face)
("_RETURN" 0 apdl-arg-face append)
;; = variable defs (with reserved _names), overwriting commands
(,variable_r 1
font-lock-variable-name-face) ; variables (max. 32 chars long)
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-undocumented-command-regexp
"\\)\\(\\w*\\)") . font-lock-constant-face)
;; get- and parametric-functions
(,(concat "\\<\\("
apdl-get-function-regexp
"\\)(") 1 font-lock-function-name-face)
(,(concat "\\<\\("
apdl-parametric-function-regexp
"\\)(") 1 font-lock-function-name-face)
;; command keywords first
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-command-regexp-1
"\\)\\>") 1 font-lock-keyword-face)
;; some operators
("\\$" . 'font-lock-type-face) ; condensed input line
(":" . 'font-lock-type-face) ; colon loops only
;; deprecated *go labels (max 8 chars including the colon) only at
;; the line beginning because they might clash with 'colon' loops
;; GOTO Labels, branching
("^\\s-*:\\([[:alnum:]_]\\{1,7\\}\\)" 1 font-lock-type-face)))
;; C-u C-x = -- describe char
;; order of execution
;; syntactic overwriting nothing fontification
;; strings and /eof overwriting syntactic fonts and command face
;; respectively
;; /eof warning: overwriting keyword face
;; * comments (must overwrite comments behind it)
;; strings in string commands
;; ?pairs of %VAR% with valid variable symbols
;; %X % with format specifier
;; *msg formatting
;; & only at line endings
;; c*** overwriting everything even %VAR%!
;; /sys command no parameter substitution
;; keep previous stuff
;; *use variables in warning face
;; = defs (overwriting commands)
;; : $ operators
;; elements
;; commands
;; experimental user variables
(defconst apdl-font-lock-keywords-2
`(
;; /eof is special: it crashes Ansys in interactive mode
;; -TODO- /eof is highlighted only first in line not behind $
("\\(?:^\\|\\$\\)\\s-*\\(/[eE][oO][fF].*\\)" 1 'trailing-whitespace t)
;; deprecated ansys * comment with 12.1 fini * bla : returns "* no
;; longer valid as comment character - please use !" * bla :
;; returns a warning *bla is not a command bla = 3 *4 : returns
;; still 3!
("[[:alnum:]_]+\\s-+\\(\\*.*$\\)" 1 font-lock-comment-face prepend)
;; ^[:alnum:] to avoid spurious
;; asterisk command fontification
;; some string faces
("\\(?:^\\|\\$\\)\\s-*\\(?:/TIT\\|/TITL\\|/TITLE\\)\\s-*,\\(.*\\)$" 1
font-lock-doc-face t) ; titles
("\\(?:^\\|\\$\\)\\s-*/[cC][oO][mM].?\\(.\\{0,75\\}\\)" 1
font-lock-doc-face t)
;; highlight message of comment command /COM (no comment (!)
;; is possible behind /COM), no separating comma necessary
;; multi line format constructs
("^\\s-*\\(?:\\*[mM][sS][gG]\\|\\*[vV][rR][eE]\\|\
\\*[vV][wW][rR]\\|\\*[mM][wW][rR]\\).*\n\\(\\(?:.*&\\s-*\n\\)+.*\\)" ; format
; constructs
(1 font-lock-doc-face t))
;; ("&\\s-*$" 0 font-lock-type-face t) ; format continuation char
;; ("%" 0 font-lock-type-face prepend) ; single % acts as a format
;; specifier and pair %.% is a parameter substitution
(apdl-higlight-percent-and-ampersand (0 'font-lock-type-face t))
;; ("%\\|&\\s-*$" (0 'font-lock-type-face t))
;; /SYS command sends string to OP,no parameter substitution!
("^\\s-*/[sS][yY][sS]\\s-*,\\(.\\{1,75\\}\\)$" 1
font-lock-doc-face t)
;; -TODO-: c*** should get fontification from command regexp
("^\\s-*\\([cC]\\*\\*\\*\\)[ ,]?\\(.\\{1,75\\}\\)"
(1 font-lock-keyword-face t) (2 font-lock-doc-face t))
;; only 75 characters possible no separator necessary
;; *use variables, local macro call arguments
;; ("\\<\\(ARG[1-9]\\|AR[1][0-9]\\)\\>" . font-lock-warning-face)
("\\<\\(ARG[1-9]\\|AR[1][0-9]\\)\\>" . apdl-arg-face)
;; elements
(,apdl-deprecated-element-regexp . font-lock-warning-face)
(,apdl-element-regexp . font-lock-builtin-face)
;; reserved vars consisting of a single "_" are valid in A. 12.1
(,reserved_vars_r 1 font-lock-warning-face)
("_RETURN" 0 apdl-arg-face append)
;; = variable defs (with reserved _names), overwriting commands
(,variable_r 1
font-lock-variable-name-face) ; variables (max. 32 chars long)
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-undocumented-command-regexp
"\\)\\(\\w*\\)") . font-lock-constant-face)
;; get- and parametric-functions
(,(concat "\\<\\("
apdl-get-function-regexp
"\\)(") 1 font-lock-function-name-face)
(,(concat "\\<\\("
apdl-parametric-function-regexp
"\\)(") 1 font-lock-function-name-face)
;; command keywords first -2a no characters appended
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-command-regexp-2a
"\\)\\>") 1 font-lock-keyword-face)
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-command-regexp-2b
"\\)\\(\\w*\\)") (1 font-lock-keyword-face)
(2 'font-lock-constant-face))
(,(concat "\\(?:^\\|\\$\\)\\s-*\\("
apdl-command-regexp-2c
"\\)\\(\\w*\\)") (1 font-lock-keyword-face)
(2 'font-lock-constant-face))
;; user variables
(apdl-highlight-variable . font-lock-variable-name-face)
;; some operators
("\\$" . 'font-lock-type-face) ; condensed input line
(":" . 'font-lock-type-face) ; colon loops only
;; deprecated *go labels (max 8 chars including the colon) only at
;; the line beginning because they might clash with 'colon' loops
;; GOTO Labels, branching
("^\\s-*:\\([[:alnum:]_]\\{1,7\\}\\)" 1 font-lock-type-face)))
;; testing
(defconst apdl-font-lock-keywords-3
'(
("%" (0 font-lock-builtin-face keep))
("^/com.*" (0 font-lock-string-face prepend))
("bla" (0 font-lock-variable-name-face prepend)))))
(defconst apdl-font-lock-keyword-list
'(
apdl-font-lock-keywords
apdl-font-lock-keywords-1
apdl-font-lock-keywords-2
;; testing
; apdl-font-lock-keywords-3
))
(defconst apdl-mode-syntax-table ; FIXME check APDL operators and
;; allowed variable characters
(let ((table (make-syntax-table)))
(modify-syntax-entry ?\r " " table)
(modify-syntax-entry ?\t " " 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) ; apdl-mode abbreviation specifier,
;; not an operator but "word".
(modify-syntax-entry ?_ "_" table) ; in APDL symbol component
(modify-syntax-entry ?: "_" table) ; APDL label specifier, not an operator
;; * and ** are operators! But we also want completion of * and / commands
;; took care about this in -complete-symbol
(modify-syntax-entry ?* "." table)
;; with algebraic operators but blink-matching- needs this
(modify-syntax-entry ?/ "." table) ; APDL slash commands
(modify-syntax-entry ?\! "<" table) ; APDL comment character
(modify-syntax-entry ?\n ">" table)
(modify-syntax-entry ?\" "w" table) ; `"' is *not* a string
; delimiter for APDL
(modify-syntax-entry ?' "\"" table); (modify-syntax-entry ?' "." table)
;; Normally APDL string delimiter, but might clash
;; with usages of genitives etc.!
(modify-syntax-entry ?~ "_" table) ; APDL connection commands,
; not an operator
table)
"Syntax table in use in `apdl-mode' buffers.")
(defconst apdl-mode-menu
(list
"APDL"
["Show the Short Command Help" apdl-show-command-parameters
:help "Display a short help for the APDL command near the
cursor with its parameters (apdl-show-command-parameters)"]
["Browse the APDL Keyword Help" apdl-browse-apdl-help
:help "Open the original APDL documentation for a command or
element name near the cursor (apdl-browse-apdl-help)"
:active (or apdl-current-ansys-version apdl-ansys-help-path)]
["Interactively Browse Keywords" (apdl-browse-apdl-help t)
:help "Complete a command, element name or other subjects and
browse its original APDL documentation
(apdl-browse-apdl-help)."
:active (or apdl-current-ansys-version apdl-ansys-help-path)]
["Browse the Ansys APDL Guide" apdl-browse-ansys-apdl-manual
:help "Read the original Ansys Parametric Design Language
Guide in a browser (apdl-browse-ansys-apdl-manual)"
;; :active (file-readable-p apdl-ansys-help-path) ; now also online :-)
]
["Browse Ansys Main Help Page" apdl-start-ansys-help-page
:help "Start the Ansys main help site
(apdl-start-ansys-help-page)."]
["Browse Ansys Customer Portal" apdl-start-ansys-customer-portal-site
:help "Start the Ansys Customer Portal site
(apdl-start-ansys-customer-portal-site)."]
"--"
["Preview Macro Template" apdl-display-skeleton
:help "Preview an APDL code template in another window"]
(list
"Insert Macro Template"
["*IF ... *ENDIF" apdl-if
:help "Insert interactively an *if .. *endif construct"]
["*DO ... *ENDDO" apdl-do
:help "Insert interactively a *do .. *enddo loop"]
["*IF ... *ELSEIF" apdl-if-then
:help "Insert interactively an *if,then .. \
(*elseif .. *else ..) *endif construct."]
["MP" apdl-mp
:help "Insert interactively an mp statement."]
["Header" apdl-skeleton-header
:help "Insert interactively the file header template"]
["Insert Pi" apdl-insert-pi
:help "Insert the variable definition \"Pi = acos(-1) !
3.1415...\" at point and indent this line."]
"--"
["Mark Paragraph" apdl-mark-paragraph
:help "Mark a paragraph, make a region out of it."]
["Comment/Un- Region" comment-dwim
:help "Comment out region or uncomment region, without a
marked region start or realign a code comment in the current
line."]
["Complete APDL Keyword" apdl-complete-symbol
:help "Complete an APDL command, element or function name"]
["Send/Copy Region or Paragraph" apdl-send-to-ansys
:label (if
(or apdl-classics-flag (apdl-process-running-p))
"Send region or paragraph to Ansys"
"Copy region or paragraph to clipboard")
:help "In case of a running solver/interpreter send marked
region or - by default - the current paragraph to the
interpreter, otherwise copy these lines to the system clipboard"]
["Copy/Send above Code to Ansys" apdl-copy-or-send-above
:label (if
(or apdl-classics-flag (apdl-process-running-p))
"Send above Code to Ansys"
"Copy above Code")
:help "Either copy the code up to the beginning of file or,
when a run is active, send it to the solver/interpreter"]
["Close Logical Block" apdl-close-block
:help "Close an open control block with the corresponding end
command"]
;; ["Insert Parentheses" insert-parentheses
;; :help "Insert a pair of parentheses enclosing marked region
;; (insert-parentheses)"] ; -FIXME- redundant, necessary for Emacs-23.1
["Align region or paragraph" apdl-align
:help "Align APDL variable definitions in a marked region or
the current paragraph (apdl-align)"]
["Display Variable Definitions" apdl-display-variables
:help "Display all user variable definitions from the current
file in another window (apdl-display-variables)"]
"--"
["Configuration" apdl-skeleton-configuration
:help "Configuration code template"]
["Get- and Fortran functions" apdl-skeleton-get-and-fortran-function
:help "Get- and Fortran functions template"]
["View Settings" apdl-skeleton-view-settings
:help "View settings like focus point, magnification, ..."]
["Coordinate Sys. Display" apdl-skeleton-coordinates
:help "Template for creating and handling coordinate
systems"]
["Working Plane Operations"
apdl-skeleton-working-plane
:help "Template for creating and handling the working