PageRenderTime 79ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 1ms

/nmcobol-mode.el

https://github.com/emacsmirror/nmcobol-mode
Emacs Lisp | 2162 lines | 1677 code | 166 blank | 319 comment | 78 complexity | 794f099dbe49df543a16b2714595bad2 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. ;;; nmcobol-mode.el --- For use with Tandem Cobol only - Sorry.
  2. ;; Copyright (C) 2006, 2007 Free Software Foundation, Inc.
  3. ;; Author: Rick Bielawski <rbielaws@i1.net>
  4. ;; Keywords: languages, COBOL, Tandem, Guardian, NSK
  5. ;; Maintainer: Rick Bielawski <rbielaws@i1.net>
  6. ;; This file is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation; either version 2, or (at your option)
  9. ;; any later version.
  10. ;; This file is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  16. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. ;; Boston, MA 02110-1301, USA.
  18. ;;; Commentary:
  19. ;; NMCOBOL -- COmmon Business Oriented Language - in ?TANDEM line format.
  20. ;; This is currently a work-in-progress. You are welcome to try it and
  21. ;; submit changes or report bugs but there is no point trying to report
  22. ;; lack of features unless you are including patches that address such
  23. ;; shortcomings.
  24. ;;
  25. ;; Since Tandem's line format is not standard this mode is not likely to
  26. ;; suit the needs of most Cobol progammers. Moreover, Tandem Cobol has
  27. ;; extensions that standard Cobol doesn't have and may not implement
  28. ;; features required or generally available by other Cobol compilers.
  29. ;; I'm happy to add submitted patches to support other compilers only if
  30. ;; such patches don't interfere with support of Tandem Cobol.
  31. ;;; Installing:
  32. ;; Before you can use nmcobol-mode, emacs needs to be able to find it. Place
  33. ;; the nmcobol-mode.el file in a directory on the load-path; typically the
  34. ;; .../site-lisp or perhaps .../lisp/progmods directory. Usually you would
  35. ;; also want to byte compile nmcobol-mode.el but this is not required. To do
  36. ;; this, visit the nmcobol-mode.el file, type: M-x emacs-lisp-byte-compile <ret>
  37. ;; There should be no warnings or errors during byte compilation.
  38. ;;
  39. ;; There are 4 basic ways to use NMCOBOL-MODE on a file. The first method
  40. ;; manually selects nmcobol-mode as the editing mode. The other 3 cause emacs
  41. ;; to recognize automatically that you want to visit the file using
  42. ;; nmcobol-mode.
  43. ;;
  44. ;; Pick one:
  45. ;; 1. While visiting a file, type: M-x nmcobol-mode <ret>
  46. ;; 2. Put the string -*-nmcobol-*- in a comment on the first line of the file.
  47. ;; Save the file and close it. Now any time you open it nmcobol-mode starts.
  48. ;; 3. Create an association between a particular file naming convention and
  49. ;; nmcobol-mode. This is done by adding an association to auto-mode-alist.
  50. ;; For example:
  51. ;; (setq auto-mode-alist
  52. ;; (append
  53. ;; '(("\\.cob\\'" . nmcobol-mode) ;extension of .cob means nmcobol-mode
  54. ;; ("\\([\\/]\\|^\\)[^.]+$" . nmcobol-mode)) ;so does no extension at all.
  55. ;; auto-mode-alist))
  56. ;; 4. Advise set-auto-mode to look at the buffer contents upon loading.
  57. ;; For an example see: http://www.emacswiki.org/cgi-bin/wiki/TandemNskSupport
  58. ;;
  59. ;; The above all tell emacs that you want to use nmcobol-mode but you must load
  60. ;; nmcobol-mode before you can use it. There are 2 methods of telling emacs to
  61. ;; load the nmcobol-mode routines. The first unconditionally loads nmcobol-mode
  62. ;; definitions immediately. The second tells emacs to automatically load
  63. ;; nmcobol-mode only when you try to use it. Add one of the following lines to
  64. ;; your .emacs file.
  65. ;;
  66. ;;(require 'nmcobol-mode) ; Unconditional load
  67. ;;(autoload 'nmcobol-mode "nmcobol-mode" "Major mode for Tandem NMCOBOL files." t nil)
  68. ;;
  69. ;;; Getting eldoc to work in nmcobol-mode:
  70. ;; Open a file containing variable declarations for which you want
  71. ;; help permanently loaded. For example: $SYSTEM.COPYLIBS.COBOLLIB.
  72. ;; The buffer must be in nmcobol-mode or ddl-mode.
  73. ;; Use: M-x nmcobol-mode <ret> if necessary.
  74. ;; Then: M-x nmcobol-eldoc-make-list <ret>
  75. ;; You should now be in a specially formatted buffer containing a list of
  76. ;; the variables declared and their corresponding help strings. You can
  77. ;; modify the strings themselves if desired but do not alter anything
  78. ;; else. Repeat these steps to add more help entries to the file.
  79. ;; Save the file somewhere on your search list like your site-lisp
  80. ;; directory. Example:
  81. ;; C-x C-w ~/../site-lisp/extdecs-help.el <ret>
  82. ;; Now add the file you just saved to the list of nmcobol-mode eldoc help
  83. ;; files to be loaded.
  84. ;; M-x customize-option <ret> nmcobol-eldoc-def-files <ret>
  85. ;; Save the customization for future sessions.
  86. ;; Once you have your help entries defined see help for eldoc-mode for
  87. ;; turing on the mode. Putting (eldoc-mode t) in .emacs might do it.
  88. ;;; History:
  89. ;; 2006-11-07 RGB Started writing this mode using my cobol-mode as skeleton.
  90. ;; 2006-12-18 RGB Added eldoc support.
  91. ;; 2006-12-26 RGB Added nmcobol-addup-pics.
  92. ;; 2006-12-27 RGB Added thing-at-point support for Guardian style 'filename.
  93. ;; 2006-12-29 RGB Added an NMCobol menu and nmcobol-customize-options.
  94. ;; 2007-01-03 RGB Added movement by sentences.
  95. ;; 2007-01-04 RGB Fixed movement by sentences, added paragraphs.
  96. ;; 2007-01-04 RGB Make COUNT argument in movement by functions optional.
  97. ;; 2007-01-09 RGB Added eldoc for variables including a buffer-local obarray.
  98. ;; 2007-01-10 RGB Added Cobol specific support for anchored-transpose.
  99. ;; 2007-01-11 RGB Fixed 66 level handling in paragraph movement and eldoc-scan.
  100. ;; 2007-01-28 RGB Sentence/Paragraph movement now saves match data.
  101. ;; 2007-01-31 RGB Started adding automatic indentation.
  102. ;; 2007-02-01 RGB Made * electric.
  103. ;; 2007-02-05 RGB Auto-indent now operates on regions
  104. ;; 2007-02-07 RGB Fixed customization of nmcobol-keywords-case &
  105. ;; nmcobol-imenu-menubar. Fixed nmcobol-pic-string-regexp
  106. ;; not recognizing 'ZZZ-.' syntax. Fixed
  107. ;; nmcobol-char-maybe-comment which broke numeric
  108. ;; prefix behavior. Doc-string updates.
  109. ;; 2007-02-12 RGB Indentation now handles all the block statements properly.
  110. ;; 2007-02-13 RGB The beginning of secondary indentation started. This
  111. ;; handles alignment of things like picture clauses, TO
  112. ;; statements etc.
  113. ;; 2007-02-19 RGB imenu now ignores xxxx-exit paragraphs. Started trying
  114. ;; to implement paren matching on end-<verb> keywords.
  115. ;; 2007-02-22 RGB nmcobol-get-block-type now ignores keywords in strings.
  116. ;;; Code:
  117. (defgroup nmcobol nil
  118. "Major mode for editing NMCOBOL source files in Emacs.
  119. While in nmcobol-mode use C-h m for a description of the mode's features."
  120. :prefix 'nmcobol-
  121. :group 'languages)
  122. ;;; SYNTAX TABLE
  123. (defvar nmcobol-mode-syntax-table
  124. (let ((st (make-syntax-table)))
  125. (modify-syntax-entry ?\n " " st)
  126. (modify-syntax-entry ?\! "." st)
  127. (modify-syntax-entry ?\" "." st) ; wiki ?" bug workaround comment
  128. (modify-syntax-entry ?\# "w" st)
  129. (modify-syntax-entry ?\$ "w" st)
  130. (modify-syntax-entry ?\% "'" st)
  131. (modify-syntax-entry ?\& "'" st)
  132. (modify-syntax-entry ?\' "." st)
  133. (modify-syntax-entry ?\( "()" st)
  134. (modify-syntax-entry ?\) ")(" st)
  135. (modify-syntax-entry ?\* "." st)
  136. (modify-syntax-entry ?\+ "." st)
  137. (modify-syntax-entry ?\, "." st)
  138. (modify-syntax-entry ?\- "w" st)
  139. (modify-syntax-entry ?\. "." st)
  140. (modify-syntax-entry ?\/ "." st)
  141. (modify-syntax-entry ?\: "." st)
  142. (modify-syntax-entry ?\; "." st)
  143. (modify-syntax-entry ?\< "." st)
  144. (modify-syntax-entry ?\= "." st)
  145. (modify-syntax-entry ?\> "." st)
  146. (modify-syntax-entry ?\? "." st)
  147. (modify-syntax-entry ?\@ "." st)
  148. (modify-syntax-entry ?\[ "(]" st)
  149. (modify-syntax-entry ?\\ "." st)
  150. (modify-syntax-entry ?\] ")[" st)
  151. (modify-syntax-entry ?^ "w" st)
  152. (modify-syntax-entry ?\_ "w" st)
  153. (modify-syntax-entry ?\{ "(}" st)
  154. (modify-syntax-entry ?\| "." st)
  155. (modify-syntax-entry ?\} "){" st)
  156. st)
  157. "Syntax table for `nmcobol-mode'.")
  158. ;;; KEY MAP
  159. (defvar nmcobol-skeleton-map
  160. (let ((map (make-sparse-keymap)))
  161. (define-key map [?i] 'nmcobol-if-skel)
  162. (define-key map [?p] 'nmcobol-paragraph-skel)
  163. map)
  164. "Keymap for `nmcobol-mode'.")
  165. (defvar nmcobol-eldoc-map
  166. (let ((map (make-sparse-keymap)))
  167. (define-key map [?m] 'nmcobol-eldoc-make-list)
  168. (define-key map [?s] 'nmcobol-eldoc-scan-buffer)
  169. (define-key map [?v] 'nmcobol-eldoc-visit-file)
  170. (define-key map [?w] 'nmcobol-eldoc-where-def)
  171. map)
  172. "Keymap for `nmcobol-mode'.")
  173. (defvar nmcobol-mode-map
  174. (let ((map (make-sparse-keymap)))
  175. (define-key map [tab] 'indent-according-to-mode)
  176. (define-key map [?\C-c ?\C-c] 'column-marker-here)
  177. (define-key map [?\C-c ?\C-e] nmcobol-eldoc-map)
  178. (define-key map [?\C-c ?\C-f] 'auto-fill-mode)
  179. (define-key map [?\C-c ?\C-o] 'nmcobol-customize-options)
  180. (define-key map [?\C-c ?\C-r] 'popup-ruler)
  181. (define-key map [?\C-c ?\C-s] nmcobol-skeleton-map)
  182. (define-key map [?\C-c ?=] 'nmcobol-addup-pics)
  183. (define-key map [?\C-c return] 'comment-indent-new-line)
  184. (define-key map [?*] 'nmcobol-char-maybe-comment)
  185. (define-key map [?/] 'nmcobol-char-maybe-comment)
  186. map)
  187. "Keymap for `nmcobol-mode'.")
  188. (defun nmcobol-setup-menu ()
  189. "Adds a menu of NMCOBOL specific functions to the menu bar."
  190. (define-key (current-local-map) [menu-bar nmcobol-menu]
  191. (cons "NMCobol" (make-sparse-keymap "NMCobol")))
  192. (define-key (current-local-map) [menu-bar nmcobol-menu customize]
  193. '(menu-item "Customize" nmcobol-customize-options
  194. :key-sequence [?\C-c ?\C-o]
  195. :help "Customize nmcobol-mode options"))
  196. (define-key (current-local-map) [menu-bar nmcobol-menu comment-eol]
  197. '(menu-item "Comment EOL" comment-indent-new-line
  198. :key-sequence [?\C-c return]
  199. :help "Continues comment on new line"))
  200. (if (featurep 'column-marker)
  201. (define-key (current-local-map) [menu-bar nmcobol-menu column]
  202. '(menu-item "Column Marker" column-marker-here
  203. :key-sequence [?\C-c ?\C-c]
  204. :help "Puts column marker at current column (C-u removes)")))
  205. (define-key (current-local-map) [menu-bar nmcobol-menu ruler]
  206. '(menu-item "Ruler" popup-ruler
  207. :key-sequence [?\C-c ?\C-r]
  208. :help "Inserts temporary ruler"))
  209. (define-key (current-local-map) [menu-bar nmcobol-menu eldoc-show]
  210. '(menu-item "Eldoc Where" nmcobol-eldoc-where-def
  211. :key-sequence [?\C-c ?\C-e ?w]
  212. :help "Shows Where function at point is defined"))
  213. (define-key (current-local-map) [menu-bar nmcobol-menu eldoc-visit]
  214. '(menu-item "Eldoc Visit" nmcobol-eldoc-visit-file
  215. :key-sequence [?\C-c ?\C-e ?v]
  216. :help "Visits file defining function at point"))
  217. (define-key (current-local-map) [menu-bar nmcobol-menu eldoc-update]
  218. '(menu-item "Eldoc Scan" nmcobol-eldoc-scan-buffer
  219. :key-sequence [?\C-c ?\C-e ?s]
  220. :help "Updates buffer-local eldoc entries (in memory)"))
  221. (define-key (current-local-map) [menu-bar nmcobol-menu eldoc-create]
  222. '(menu-item "Eldoc Make List" nmcobol-eldoc-make-list
  223. :key-sequence [?\C-c ?\C-e ?m]
  224. :help "Puts current file eldoc entries in a file."))
  225. (define-key (current-local-map) [menu-bar nmcobol-menu skeletons]
  226. (cons "Skeletons" (make-sparse-keymap "Skeletons")))
  227. (define-key (current-local-map) [menu-bar nmcobol-menu skeletons if]
  228. '(menu-item "If Then" nmcobol-if-skel
  229. :key-sequence [?\C-c ?\C-s ?i]
  230. :help "Inserts an If/Then statement"))
  231. (define-key (current-local-map) [menu-bar nmcobol-menu skeletons paragraph]
  232. '(menu-item "New Paragraph" nmcobol-paragraph-skel
  233. :key-sequence [?\C-c ?\C-s ?p]
  234. :help "Inserts comment bars for new paragraph name")))
  235. ;; All keyword lists get sorted so new words can be anywhere within the
  236. ;; appropriate list. The keywords are currently only used for highlighting but
  237. ;; more uses such as abbrev-mode are in progress.
  238. (defvar nmcobol-keywords-directives ;font-lock-preprocessor-face
  239. '( "ANSI" "BLANK" "CALL-SHARED" "CANCEL"
  240. "CHECK" "CODE" "COLUMNS" "COMPACT"
  241. "COMPILE" "CONSULT" "CROSSREF" "DIAGNOSE-74"
  242. "DIAGNOSE-85" "DIAGNOSEALL" "ENDIF" "ENDUNIT"
  243. "ENV" "ERRORFILE" "ERRORS" "FIPS"
  244. "FMAP" "HEADING" "HEAP" "HIGHPIN"
  245. "HIGHREQUESTERS" "ICODE" "IF" "IFNOT"
  246. "INNERLIST" "INSPECT" "LARGEDATA" "LD"
  247. "LESS-CODE" "LIBRARY" "LINES" "LIST"
  248. "LMAP" "MAIN" "MAP" "NLD"
  249. "NOBLANK" "NOCANCEL" "NOCODE" "NOCOMPACT"
  250. "NOCONSULT" "NOCROSSREF" "NODIAGNOSE-74" "NODIAGNOSE-85"
  251. "NODIAGNOSEALL" "NOFIPS" "NOICODE" "NOINNERLIST"
  252. "NOINSPECT" "NOLIST" "NOLMAP" "NOMAP"
  253. "NON-SHARED" "NONSTOP" "NOPORT" "NOSAVEABEND"
  254. "NOSEARCH" "NOSHOWCOPY" "NOSHOWFILE" "NOSQL"
  255. "NOSUPPRESS" "NOSYMBOLS" "NOTRAP2" "NOTRAP2-74"
  256. "NOWARN" "OPTIMIZE" "PERFORM-TRACE" "PORT"
  257. "RESETTOG" "RUNNABLE" "RUNNAMED" "SAVE"
  258. "SAVEABEND" "SEARCH" "SECTION" "SETTOG"
  259. "SHARED" "SHOWCOPY" "SHOWFILE" "SOURCE"
  260. "SQL" "SQLMEM" "SUBSET" "SUBTYPE"
  261. "SUPPRESS" "SYMBOLS" "SYNTAX" "TANDEM"
  262. "TRAP2" "TRAP2-74" "UL" "WARN")
  263. "List of NMCOBOL compiler directives.
  264. Used to create the `font-lock-keywords' table.")
  265. (defvar nmcobol-keywords-imperatives
  266. '( "ACCEPT" "DISPLAY" "MULTIPLY" "STOP"
  267. "ADD" "DIVIDE" "OPEN" "STRING"
  268. "ALTER" "ENTER" "PERFORM" "SUBTRACT"
  269. "CALL" "EXIT" "READ" "UNLOCKFILE"
  270. "CANCEL" "GO TO" "RELEASE" "UNLOCKRECORD"
  271. "INITIALIZE" "REWRITE" "UNSTRING" "CLOSE"
  272. "INSPECT" "SET" "WRITE" "COMPUTE"
  273. "LOCKFILE" "SORT" "CONTINUE" "MERGE"
  274. "START" "DELETE" "MOVE")
  275. "List of NMCOBOL keywords identifying an imperative statement.
  276. Used by indentation routines in their determination of such."
  277. )
  278. (defvar nmcobol-block-keywords
  279. '("ADD" "COMPUTE" "DELETE" "DIVIDE"
  280. "EVALUATE" "IF" "MULTIPLY" "PERFORM"
  281. "READ" "REWRITE" "SEARCH" "START"
  282. "STRING" "SUBTRACT" "UNSTRING" "WRITE"
  283. )
  284. "A list of words that should have open paren syntax - conditionally.
  285. `nmcobol-get-block-type' determines if they actually require the
  286. END-<word> statement." )
  287. (defvar nmcobol-keywords-statements ;font-lock-keyword-face
  288. '("ACCEPT" "ADD" "ALTER" "CALL"
  289. "CANCEL" "CHECKPOINT" "CLOSE" "COMPUTE"
  290. "CONTINUE" "COPY" "DELETE" "DISPLAY"
  291. "DIVIDE" "ELSE" "END" "END-ADD"
  292. "END-COMPUTE" "END-DELETE" "END-DIVIDE" "END-EVALUATE"
  293. "END-IF" "END-MULTIPLY" "END-OF-PAGE" "END-PERFORM"
  294. "END-READ" "END-RECEIVE" "END-RETURN" "END-REWRITE"
  295. "END-SEARCH" "END-START" "END-STRING" "END-SUBTRACT"
  296. "END-UNSTRING" "END-WRITE" "ENTER COBOL" "ENTER"
  297. "EVALUATE" "EXIT" "FD" "FILE"
  298. "GO TO" "IF" "INITIALIZE" "INSPECT"
  299. "LOCKFILE" "MERGE" "MOVE" "MULTIPLY"
  300. "OPEN" "PERFORM" "READ" "RELEASE"
  301. "REPLACE" "RETURN" "REWRITE" "SD"
  302. "SEARCH" "SELECT" "SET" "SORT"
  303. "START" "STARTBACKUP" "STOP" "STRING"
  304. "SUBTRACT" "THEN" "UNLOCKFILE" "UNLOCKRECORD"
  305. "UNSTRING" "USE" "WHEN" "WRITE" )
  306. "List of NMCOBOL statement keywords.
  307. Used to create the `font-lock-keywords' table.")
  308. (defvar nmcobol-keywords-deprecated ;font-lock-warning-face
  309. '( "STARTBACKUP" "CHECKPOINT")
  310. "List of NMCOBOL keywords and Builtin functions now deprecated.
  311. Used to create the `font-lock-keywords' table")
  312. (defvar nmcobol-keywords-reserved ;font-lock-type-face
  313. '( "ACCEPT" "ACCESS" "ADD"
  314. "ADDRESS" "ADVANCING" "AFTER"
  315. "ALL" "ALPHABET" "ALPHABETIC"
  316. "ALPHABETIC-LOWER" "ALPHABETIC-UPPER" "ALPHANUMERIC"
  317. "ALPHANUMERIC-EDITED" "ALSO" "ALTER"
  318. "ALTERNATE" "AND" "ANY"
  319. "APPROXIMATE" "AREA" "AREAS"
  320. "ASCENDING" "ASSIGN" "AT"
  321. "AUTHOR" "BEFORE" "BINARY"
  322. "BLANK" "BLOCK" "BOTTOM"
  323. "BY" "CALL" "CANCEL"
  324. "CD" "CF" "CH"
  325. "CHARACTER" "CHARACTERS" "CHARACTER-SET"
  326. "CHECKPOINT" "CLASS" "CLOCK-UNITS"
  327. "CLOSE" "COBOL" "CODE"
  328. "CODE-SET" "COLLATING" "COLUMN"
  329. "COMMA" "COMMON" "COMMUNICATION"
  330. "COMP" "COMP-3" "COMP-5"
  331. "COMPUTATIONAL" "COMPUTATIONAL-3" "COMPUTATIONAL-5"
  332. "COMPUTE" "CONFIGURATION" "CONTAINS"
  333. "CONTENT" "CONTINUE" "CONTROL"
  334. "CONTROLS" "CONVERTING" "COPY"
  335. "CORR" "CORRESPONDING" "COUNT"
  336. "CURRENCY" "DATA" "DATE"
  337. "DATE-COMPILED" "DATE-WRITTEN" "DAY"
  338. "DAY-OF-WEEK" "DE" "DEBUG-CONTENTS"
  339. "DEBUG-ITEM" "DEBUG-LINE" "DEBUG-SUB-2"
  340. "DEBUG-SUB-3" "DEBUGGING" "DECIMAL-POINT"
  341. "DECLARATIVES" "DEBUG-NAME" "DEBUG-SUB-1"
  342. "DELETE" "DELIMITED" "DELIMITER"
  343. "DEPENDING" "DESCENDING" "DESTINATION"
  344. "DETAIL" "DISABLE" "DISPLAY"
  345. "DIVIDE" "DIVISION" "DOWN"
  346. "DUPLICATES" "DYNAMIC" "EGI"
  347. "ELSE" "EMI" "ENABLE"
  348. "END" "END-ADD" "END-COMPUTE"
  349. "END-DELETE" "END-DIVIDE" "END-EVALUATE"
  350. "END-IF" "END-MULTIPLY" "END-OF-PAGE"
  351. "END-PERFORM" "END-READ" "END-RECEIVE"
  352. "END-RETURN" "END-REWRITE" "END-SEARCH"
  353. "END-START" "END-STRING" "END-SUBTRACT"
  354. "END-UNSTRING" "END-WRITE" "ENTER"
  355. "EOP" "EQUAL" "ERROR"
  356. "ESI" "EVALUATE" "EVERY"
  357. "EXCEPTION" "EXCLUSIVE" "EXIT"
  358. "EXTEND" "EXTENDED-STORAGE" "EXTERNAL"
  359. "FALSE" "FD" "FILE"
  360. "FILE-CONTROL" "FILLER" "FINAL"
  361. "FIRST" "FOOTING" "FOR"
  362. "FROM" "FUNCTION" "GENERATE"
  363. "GENERIC" "GIVING" "GLOBAL"
  364. "GO" "GREATER" "GROUP"
  365. "GUARDIAN-ERR" "HEADING" "HIGH-VALUE"
  366. "HIGH-VALUES" "I-O" "I-O-CONTROL"
  367. "IDENTIFICATION" "IF" "IN"
  368. "INDEX" "INDEXED" "INDICATE"
  369. "INITIAL" "INITIALIZE" "INITIATE"
  370. "INPUT" "INPUT-OUTPUT" "INSPECT"
  371. "INSTALLATION" "INTO" "INVALID"
  372. "IS" "JUST" "JUSTIFIED"
  373. "KEY" "LABEL" "LAST"
  374. "LEADING" "LEFT" "LENGTH"
  375. "LESS" "LIMIT" "LIMITS"
  376. "LINAGE" "LINAGE-COUNTER" "LINE"
  377. "LINE-COUNTER" "LINKAGE" "LOCK"
  378. "LOCKFILE" "LOW-VALUE" "LOW-VALUES"
  379. "MEMORY" "MERGE" "MESSAGE"
  380. "MODE" "MODULES" "MOVE"
  381. "MULTIPLE" "MULTIPLY" "NATIVE"
  382. "NEGATIVE" "NEXT" "NO"
  383. "NOT" "NULL" "NULLS"
  384. "NUMBER" "NUMERIC" "NUMERIC-EDITED"
  385. "OBJECT-COMPUTER" "OCCURS" "OF"
  386. "OFF" "OMITTED" "ON"
  387. "OPEN" "OPTIONAL" "OR"
  388. "ORDER" "ORGANIZATION" "OTHER"
  389. "OUTPUT" "OVERFLOW" "PACKED-DECIMAL"
  390. "PADDING" "PAGE" "PAGE-COUNTER"
  391. "PERFORM" "PF" "PH"
  392. "PIC" "PICTURE" "PLUS"
  393. "POINTER" "POSITION" "POSITIVE"
  394. "PRINTING" "PROCEDURE" "PROCEDURES"
  395. "PROCEED" "PROGRAM" "PROGRAM-ID"
  396. "PROGRAM-STATUS" "PROGRAM-STATUS-1" "PROGRAM-STATUS-2"
  397. "PROMPT" "PROTECTED" "PURGE"
  398. "QUEUE" "QUOTE" "QUOTES"
  399. "RANDOM" "RD" "READ"
  400. "RECEIVE" "RECEIVE-CONTROL" "RECORD"
  401. "RECORDS" "REDEFINES" "REEL"
  402. "REFERENCE" "REFERENCES" "RELATIVE"
  403. "RELEASE" "REMAINDER" "REMOVAL"
  404. "RENAMES" "REPLACE" "REPLACING"
  405. "REPLY" "REPORT" "REPORTING"
  406. "REPORTS" "RERUN" "RESERVE"
  407. "RESET" "RETURN" "REVERSED"
  408. "REWIND" "REWRITE" "RF"
  409. "RH" "RIGHT" "ROUNDED"
  410. "RUN" "SAME" "SD"
  411. "SEARCH" "SECTION" "SECURITY"
  412. "SEGMENT" "SEGMENT-LIMIT" "SELECT"
  413. "SEND" "SENTENCE" "SEPARATE"
  414. "SEQUENCE" "SEQUENTIAL" "SET"
  415. "SHARED" "SIGN" "SIZE"
  416. "SORT" "SORT-MERGE" "SOURCE"
  417. "SOURCE-COMPUTER" "SPACE" "SPACES"
  418. "SPECIAL-NAMES" "STANDARD" "STANDARD-1"
  419. "STANDARD-2" "START" "STARTBACKUP"
  420. "STATUS" "STOP" "STRING"
  421. "SUB-QUEUE-1" "SUB-QUEUE-2" "SUB-QUEUE-3"
  422. "SUBTRACT" "SUM" "SUPPRESS"
  423. "SYMBOLIC" "SYNC" "SYNCDEPTH"
  424. "SYNCHRONIZED" "TABLE" "TAL"
  425. "TALLYING" "TAPE" "TERMINAL"
  426. "TERMINATE" "TEST" "TEXT"
  427. "THAN" "THEN" "THROUGH"
  428. "THRU" "TIME" "TIMES"
  429. "TO" "TOP" "TRAILING"
  430. "TRUE" "TYPE" "UNIT"
  431. "UNLOCK" "UNLOCKFILE" "UNLOCKRECORD"
  432. "UNSTRING" "UNTIL" "UP"
  433. "UPON" "USAGE" "USE"
  434. "USING" "VALUE" "VALUES"
  435. "VARYING" "WHEN" "WITH"
  436. "WORDS" "WORKING-STORAGE" "WRITE"
  437. "ZERO" "ZEROES")
  438. "List of NMCOBOL keywords reserved only in certain language contexts.
  439. Used to create the `font-lock-keywords' table.")
  440. (defvar nmcobol-keywords-std-fcns ;font-lock-keyword-face
  441. '( "ACOS" "ANNUITY" "ASIN"
  442. "ATAN" "CHAR" "COS"
  443. "CURRENT-DATE" "DATE-OF-INTEGER" "DAY-OF-INTEGER"
  444. "FACTORIAL" "INTEGER" "INTEGER-OF-DATE"
  445. "INTEGER-OF-DAY" "INTEGER-PART" "LENGTH"
  446. "LOG" "LOG10" "LOWER-CASE"
  447. "MAX" "MEAN" "MEDIAN"
  448. "MIDRANGE" "MIN" "MOD"
  449. "NUMVAL" "NUMVAL-C" "ORD"
  450. "ORD-MAX" "ORD-MIN" "PRESENT-VALUE"
  451. "RANDOM" "RANGE" "REM"
  452. "REVERSE" "SIN" "SQRT"
  453. "STANDARD-DEVIATION" "SUM" "TAN"
  454. "UPPER-CASE" "VARIANCE" "WHEN-COMPILED")
  455. "List of NMCOBOL standard functions.
  456. Used to create the `font-lock-keywords' table.")
  457. (defvar nmcobol-keywords-privileged ;font-lock-warning-face
  458. '( "END-EXEC" "EXEC")
  459. "List of NMCOBOL privileged functions.
  460. Used to create the `font-lock-keywords' table.")
  461. (defvar nmcobol-keywords-builtin ;font-lock-variable-name-face
  462. '( "#IN" "#OUT"
  463. "#TERM" "#TEMP"
  464. "#DYNAMIC" "COBOL85^ARMTRAP"
  465. "COBOL85^COMPLETION" "COBOL_COMPLETION_"
  466. "COBOL_CONTROL_" "COBOL_GETENV_"
  467. "COBOL_PUTENV_" "COBOL85^RETURN^SORT^ERRORS"
  468. "COBOL_RETURN_SORT_ERRORS_" "COBOL85^REWIND^SEQUENTIAL"
  469. "COBOL_REWIND_SEQUENTIAL_" "COBOL85^SET^SORT^PARAM^TEXT"
  470. "COBOL_SET_SORT_PARAM_TEXT_" "COBOL85^SET^SORT^PARAM^VALUE"
  471. "COBOL_SET_SORT_PARAM_VALUE_" "COBOL_SET_MAX_RECORD_"
  472. "COBOL_SETMODE_" "COBOL85^SPECIAL^OPEN"
  473. "COBOL_SPECIAL_OPEN_" "COBOLASSIGN"
  474. "COBOL_ASSIGN_" "COBOLFILEINFO"
  475. "COBOL_FILE_INFO_" "COBOLSPOOLOPEN"
  476. "CREATEPROCESS" "ALTERPARAMTEXT"
  477. "CHECKLOGICALNAME" "CHECKMESSAGE"
  478. "DELETEASSIGN" "DELETEPARAM"
  479. "DELETESTARTUP" "GETASSIGNTEXT"
  480. "GETASSIGNVALUE" "GETBACKUPCPU"
  481. "GETPARAMTEXT" "GETSTARTUPTEXT"
  482. "PUTASSIGNTEXT" "PUTASSIGNVALUE"
  483. "PUTPARAMTEXT" "PUTSTARTUPTEXT")
  484. "List of NMCOBOL privileged builtin functions.
  485. Used to create the `font-lock-keywords' table.")
  486. (defcustom nmcobol-block-always-keywords
  487. '("ELSE" "EVALUATE" "IF" "SEARCH" "THEN"
  488. "WHEN" )
  489. "List of keywords that always require and END-<word>. Used in paren matching."
  490. :type '(repeat (string :tag "word"))
  491. :group 'nmcobol)
  492. (defcustom nmcobol-keyword-section-names-regexp
  493. "^\\s-\\{1,3\\}\\(\\w+\\)\\s-+\\(division\\(\\s-+using\\s-+[^.\n]+\\)?\\|section\\) *\\."
  494. "Defines a regexp that finds the names of divisions & sections.
  495. Used to create the `font-lock-keywords' table."
  496. :type 'regexp
  497. :group 'nmcobol)
  498. (defcustom nmcobol-keyword-fcn-names-regexp
  499. "^\\s-\\{1,3\\}\\(\\w+\\)\\s-*\\."
  500. "Defines a regexp that finds the names of paragraphs.
  501. Used by `font-lock-keywords'. See also `nmcobol-imenu-fcn-names-regexp'"
  502. :type 'regexp
  503. :group 'nmcobol)
  504. ;;; Build keyword regexp from keyword lists
  505. (defvar nmcobol-keywords-imperatives-regexp ()
  506. "regexp matching `nmcobol-keywords-imperatives'")
  507. (defvar nmcobol-keywords-statements-regexp ()
  508. "regexp matching `nmcobol-keywords-statements'")
  509. (defvar nmcobol-keywords-reserved-regexp ()
  510. "regexp matching `nmcobol-keywords-reserved'")
  511. (defvar nmcobol-block-always-regexp ()
  512. "regexp matching `nmcobol-block-always-keywords'")
  513. (defvar nmcobol-block-begin-regexp ()
  514. "regexp matching `nmcobol-block-keywords'")
  515. (defvar nmcobol-block-end-regexp ()
  516. "regexp matching \"END-\" + `nmcobol-block-keywords'")
  517. (defvar nmcobol-non-cobol-regexp
  518. "^[*/?]"
  519. "Expression describing comment and compiler directive lines.")
  520. (defun nmcobol-setup-regexp-vars ()
  521. "Rebuilds regexp variables from keyword lists."
  522. (setq nmcobol-keywords-imperatives-regexp
  523. (concat (regexp-opt nmcobol-keywords-imperatives t) "\\(\\s-\\|\\.\\)")
  524. nmcobol-keywords-statements-regexp
  525. (concat "^\\([ \t]+\\)"
  526. (regexp-opt nmcobol-keywords-statements t) "\\(\\s-\\|\\.\\)")
  527. nmcobol-keywords-reserved-regexp ;not used!
  528. (nmcobol-keyword-anywhere-regexp nmcobol-keywords-reserved)
  529. nmcobol-block-always-regexp
  530. (concat (regexp-opt nmcobol-block-always-keywords t) "\\(\\s-\\|\\.\\)")
  531. nmcobol-block-begin-regexp
  532. (regexp-opt nmcobol-block-keywords t)
  533. nmcobol-block-end-regexp
  534. (concat "END-" (regexp-opt nmcobol-block-keywords t))))
  535. ;;; Font lock (highlighting)
  536. (defcustom nmcobol-font-lock-always t
  537. "`nmcobol-mode' makes sure `font-lock-mode' is on for nmcobol-mode buffers.
  538. Some things don't work if it's off so insuring it's on is the default."
  539. :type 'boolean
  540. :group 'nmcobol)
  541. (defcustom nmcobol-primecode-warning t
  542. "Highlight instances of ]a ]d and ]e in column 1 with a warning face.
  543. This alerts you that submission of this file to RMS/PrimeCode will fail
  544. due to invalid contents. nil disables this warning."
  545. :type 'boolean
  546. :group 'nmcobol)
  547. (defun nmcobol-keyword-special-regexp ( word-list )
  548. "Returns a regexp that finds any of the words in WORD-LIST.
  549. But only if the keyword is surrounded by non-word chars."
  550. (concat "\\W"(regexp-opt word-list t)"\\W"))
  551. (defun nmcobol-keyword-anywhere-regexp ( word-list )
  552. "Returns a regexp that finds any of the words in WORD-LIST.
  553. But only if the keyword is surrounded by non-word chars."
  554. (concat "\\b"(regexp-opt word-list t)"\\b"))
  555. ;; The next 4 def's work tightly together and, as coded, cannot be reused for
  556. ;; additional purposes.
  557. (defvar nmcobol-keyword-on-directive-line-regexp () "Internal use only.")
  558. (defun nmcobol-keyword-on-directive-line-regexp ( word-list )
  559. "Returns a function to find WORD-LIST only if line starts with ?"
  560. (setq nmcobol-keyword-on-directive-line-regexp
  561. (concat "\\b"(regexp-opt word-list t)"\\b"))
  562. 'nmcobol-font-lock-directive-line)
  563. (defvar nmcobol-amid-font-lock-excursion nil
  564. "Used by `nmcobol-font-lock-directive-line'. When a line starting with
  565. ? in column 1 is detected this variable holds the context needed to
  566. continue searching for more keywords. If nil a line starting with ?
  567. should be searched for.")
  568. (make-variable-buffer-local 'nmcobol-amid-font-lock-excursion)
  569. (defun nmcobol-font-lock-directive-line ( search-limit )
  570. "This function finds keywords only in lines starting with ?. Valid
  571. keywords are described by `nmcobol-keyword-on-directive-line-regexp'.
  572. First a line beginning with ? is searched for. Once found, point is
  573. moved to the beginning of that area and limit is set to the end.
  574. Keywords are searched for within that range. If found, context is saved
  575. in nmcobol-amid-font-lock-excursion and the match-data is returned. If
  576. not found, another line starting with ? is searched for. If saved
  577. context exists when this function is called then another keyword is
  578. searched for in the previously narrowed region. If none is found the
  579. next region is searched for."
  580. (let ((looking t))
  581. (while
  582. (and looking
  583. (or nmcobol-amid-font-lock-excursion
  584. (when (re-search-forward "^\\?.+\n" search-limit t)
  585. (setq nmcobol-amid-font-lock-excursion (point))
  586. (goto-char (match-beginning 0)))))
  587. (if (re-search-forward nmcobol-keyword-on-directive-line-regexp
  588. nmcobol-amid-font-lock-excursion t)
  589. (setq looking nil)
  590. (goto-char nmcobol-amid-font-lock-excursion)
  591. (setq nmcobol-amid-font-lock-excursion nil)))
  592. (not looking)))
  593. (defvar nmcobol-find-syntactic--state ()
  594. "Used by `nmcobol-find-syntactic-keywords' to find multiple syntactic
  595. elements which all must be anchored to the beginning of a line.
  596. nil = No searches on this line yet. skip line if it's a directive.
  597. 0 = look for sequence number in col 1-6 (removed)
  598. 1 = sequence/label area checked. look at body.
  599. 2 = body not a comment, any trailing comment marked, check for strings
  600. marker = terminated string found check for more.")
  601. (make-variable-buffer-local 'nmcobol-find-syntactic--state)
  602. (defun nmcobol-find-syntactic-keywords ( search-limit )
  603. "Used by `font-lock-syntactic-keywords' to find comments and strings.
  604. Returns t if either a comment or string is found, nil if neither is found.
  605. match-data 1&2 are set for comments, 3&4 are set for a normal string, 5&6 are
  606. set for eol-terminated strings. Where the match pair mark the start character
  607. and end character respectively. Point is moved to the next line during this
  608. function only after the last search completes for the current line. A state
  609. machine, controlled by `nmcobol-find-syntactic--state' sequences the searches."
  610. (let ((found nil)
  611. (save (point)))
  612. (while (and (< (point) search-limit)
  613. (not found))
  614. (cond
  615. ;; no comments or quotes? in compiler directives
  616. ((or (null nmcobol-find-syntactic--state)
  617. (equal nmcobol-find-syntactic--state (make-marker)))
  618. (if (looking-at "^\\?")
  619. (forward-line 1) ;do this state on next line
  620. (setq nmcobol-find-syntactic--state 1) ;do next state on this line
  621. ))
  622. ;; see if entire line is a comment
  623. ((= 1 nmcobol-find-syntactic--state)
  624. (if (not (looking-at "^\\(?:*\\|/\\)"))
  625. (setq nmcobol-find-syntactic--state 2) ;goto next state
  626. ;; else set match data and point to next line
  627. (looking-at "\\(.\\).*\\(\n\\|\\'\\)") ;setup match-data
  628. (forward-line 1) ;next iteration looks at next line
  629. (setq nmcobol-find-syntactic--state ()
  630. found t)))
  631. ;; look for strings only within columns 8-72 inclusive
  632. ((= 2 nmcobol-find-syntactic--state)
  633. (if (looking-at "^[-d D][^\"\n]\\{0,130\\}\"")
  634. (let* ((open-quote (list (copy-marker (1- (match-end 0)))
  635. (copy-marker (match-end 0))))
  636. (leol (copy-marker (line-end-position)))
  637. close-quote)
  638. (setq found t)
  639. (goto-char (cadr open-quote))
  640. (if (search-forward "\"" leol t)
  641. (progn ; normally ending string
  642. (setq close-quote (match-data)
  643. nmcobol-find-syntactic--state (cadr close-quote))
  644. (beginning-of-line)
  645. (set-match-data
  646. `(,(car open-quote) ,(cadr close-quote)
  647. nil nil nil nil ;match-string 1&2 not found
  648. ,@open-quote ,@close-quote)) ;3&4 are normal string
  649. )
  650. ;; implicit string end
  651. (forward-line 1) ;next iteration looks at next line
  652. (setq close-quote (list (copy-marker (1- leol)) leol)
  653. nmcobol-find-syntactic--state ())
  654. (set-match-data
  655. `(,(car open-quote) ,(cadr close-quote)
  656. nil nil nil nil ;match-string 1&2 not found
  657. nil nil nil nil ;match-string 3&4 not found
  658. ,@open-quote ,@close-quote)) ;5&6 unterminated string
  659. ))
  660. ;; no string was found. Start new analysis on next line
  661. (forward-line 1)
  662. (setq nmcobol-find-syntactic--state ())))
  663. ;; a string has been found look for another after it
  664. ((markerp nmcobol-find-syntactic--state)
  665. (let ((leol (copy-marker (line-end-position)))
  666. open-quote close-quote)
  667. (goto-char nmcobol-find-syntactic--state)
  668. (if (search-forward "\"" leol t)
  669. (progn
  670. (setq open-quote (match-data)
  671. found t)
  672. (if (search-forward "\"" leol t)
  673. (progn ; normally ending string
  674. (beginning-of-line) ;next iteration starts here again
  675. (setq close-quote (match-data)
  676. nmcobol-find-syntactic--state (cadr close-quote))
  677. (set-match-data
  678. `(,(car open-quote) ,(cadr close-quote)
  679. nil nil nil nil ;match-string 1&2 not found
  680. ,@open-quote ,@close-quote)) ;3&4 normal string
  681. )
  682. ;; implicit string end
  683. (forward-line 1) ;next iteration looks at next line
  684. (setq close-quote (list (copy-marker (1- leol)) leol)
  685. nmcobol-find-syntactic--state ())
  686. (set-match-data
  687. `(,(car open-quote) ,(cadr close-quote)
  688. nil nil nil nil ;match-string 1&2 not found
  689. nil nil nil nil ;match-string 3&4 not found
  690. ,@open-quote ,@close-quote)) ;5&6 unterminated string
  691. ))
  692. (forward-line 1)
  693. (setq nmcobol-find-syntactic--state ()))))))
  694. ;; Point should not return forward of search-limit
  695. (and (> (point) search-limit) (goto-char search-limit))
  696. ;; point shouldn't move if nothing was found.
  697. (prog1 found (or found (goto-char save)))))
  698. (defvar nmcobol-static-font-lock-keywords
  699. ;; font-lock-keywords is a symbol or list of symbols yielding the keywords to
  700. ;; be fontified. Keywords are listed here using either (MATCHER . FACENAME)
  701. ;; or (MATCHER . (MATCH FACENAME)) syntax. Other options are available but
  702. ;; not used here. For simplicity, all regexp's were designed so MATCH would
  703. ;; be 1. Nothing forced this but to me it makes debug/maintenance easier.
  704. `(("^\\([^ ?Dd*/-]\\)" 1 font-lock-warning-face)
  705. ("^\\([?Dd-]\\)" 1 font-lock-builtin-face)
  706. (,nmcobol-keyword-section-names-regexp
  707. 1 font-lock-function-name-face)
  708. (,(nmcobol-keyword-on-directive-line-regexp nmcobol-keywords-directives)
  709. 1 font-lock-preprocessor-face)
  710. (,(nmcobol-keyword-anywhere-regexp nmcobol-keywords-builtin)
  711. 1 font-lock-variable-name-face)
  712. (,(nmcobol-keyword-special-regexp nmcobol-keywords-statements)
  713. 1 font-lock-keyword-face)
  714. (,(nmcobol-keyword-anywhere-regexp nmcobol-keywords-std-fcns)
  715. 1 font-lock-keyword-face)
  716. (,(nmcobol-keyword-anywhere-regexp (append nmcobol-keywords-deprecated
  717. nmcobol-keywords-privileged))
  718. 1 font-lock-warning-face)
  719. (,(nmcobol-keyword-anywhere-regexp nmcobol-keywords-reserved)
  720. 1 font-lock-type-face)
  721. (,nmcobol-keyword-fcn-names-regexp
  722. 1 font-lock-function-name-face)))
  723. (defvar nmcobol-font-lock-keywords ())
  724. (defun nmcobol-build-font-lock-keywords ()
  725. "Creates `font-lock-keywords' based on current customize settings."
  726. (append nmcobol-static-font-lock-keywords
  727. `(,(when nmcobol-primecode-warning
  728. ;; ]a ]d or ]e cannot appear in col 1-2 if using PrimeCode.
  729. '("^\\][ade]" . font-lock-warning-face)))))
  730. (defvar nmcobol-this-paren-type ()
  731. "Used internally by `nmcobol-font-lock-syntactic-keywords'"
  732. )
  733. (defvar nmcobol-block-symbol-prefix "nmcobol-blk-typ-"
  734. "Paren matching symbols are built using this prefix.
  735. You probably don't want to change it "
  736. )
  737. (defcustom nmcobol-else-gets-paren-syntax t
  738. "When `show-paren-mode' is ON and this is nil, IF always matches END-IF only.
  739. When this variable is non-nil, IF can match ELSE and ELSE matches END-IF."
  740. :type 'boolean
  741. :group 'nmcobol)
  742. (defun nmcobol-find-paren-words (lim)
  743. "Function to set paren syntactic properties for Cobol's block keywords.
  744. Returns t and sets both `nmcobol-this-paren-type' and appropriate match-data
  745. when keywords requiring paren syntax are seen within range of point & lim."
  746. (let ((looking t) ;looping continues until lim or found (not looking)
  747. open-type ;type of paren needed to match this open
  748. close-type ;type of paren needed to match this close
  749. open-loc
  750. close-loc
  751. word)
  752. ;; walk thru each statement
  753. (while (and looking
  754. (re-search-forward nmcobol-keywords-statements-regexp
  755. lim 'move-anyway))
  756. ;; Save the word and it's location in case paren class is to be applied
  757. (setq word (match-string-no-properties 2)
  758. open-loc (match-beginning 2)
  759. close-loc (1- (match-end 2)))
  760. ;; Look for the different types of paren class we might apply
  761. (cond
  762. ;; The ELSE keyword can be ignored or treated as both open and close
  763. ((and nmcobol-else-gets-paren-syntax (string= "ELSE" word))
  764. ;; The leading E of Else will match the I of IF and the trailing
  765. ;; E should match the F of END-IF. When no ELSE is present the I
  766. ;; of IF will match the F of END-IF.
  767. (setq looking nil
  768. word open-loc
  769. open-loc close-loc
  770. close-loc word
  771. close-type (setq open-type
  772. (intern
  773. (concat nmcobol-block-symbol-prefix "IF")))))
  774. ;; close paren keywords always have close paren syntax
  775. ((string-match nmcobol-block-end-regexp word)
  776. (setq close-type
  777. (intern
  778. (concat nmcobol-block-symbol-prefix
  779. (upcase (match-string-no-properties 1 word))))
  780. looking nil))
  781. ;; 'possible' open paren keywords. More checking needed.
  782. ((string-match nmcobol-block-begin-regexp word)
  783. (let ((next (point)))
  784. (if (re-search-forward nmcobol-keywords-statements-regexp
  785. lim 'move-anyway)
  786. (setq next (match-beginning 0)))
  787. (goto-char open-loc)
  788. (if (setq open-type (nmcobol-get-block-type next))
  789. (setq looking nil))
  790. (goto-char (1+ close-loc))))))
  791. ;; Build the response data
  792. (if looking
  793. ;; nil is returned if no paren syntax to apply
  794. (set-match-data ())
  795. ;; both the match data and the paren type data must be set
  796. (set-match-data
  797. (append (list open-loc (1+ close-loc))
  798. (if open-type
  799. (list open-loc (1+ open-loc))
  800. (list () ()))
  801. (if close-type
  802. (list close-loc (1+ close-loc)))))
  803. (setq nmcobol-this-paren-type
  804. (cons
  805. ;; declare the open-paren type
  806. (cons 4 open-type)
  807. ;; declare the close-paren type
  808. (cons 5 close-type)))
  809. ;; t must be returned iff match-data should be acted upon
  810. t)))
  811. (defvar nmcobol-font-lock-syntactic-keywords
  812. `(
  813. ;; nmcobol-find-syntactic-keywords returns matches 1&2 for comments, 3&4
  814. ;; for strings. 5&6 for eol terminated strings. I must use "|"(15)
  815. ;; rather than "\""(7) for eol terminated strings because the begin
  816. ;; and end characters must be the same when "\""(7) is used.
  817. (nmcobol-find-syntactic-keywords (1 "<" t t) (2 ">" t t)
  818. (3 "\"" t t) (4 "\"" t t)
  819. (5 "|" t t) (6 "|" t t))
  820. ;; nmcobol-find-paren-words returns match 1 for open paren syntax and
  821. ;; match 2 for close paren syntax. The car of nmcobol-this-paren-type
  822. ;; is used for open paren type and the cdr for close type. The types
  823. ;; must be configurable due to the large number of them.
  824. (nmcobol-find-paren-words (1 (car nmcobol-this-paren-type) t t)
  825. (2 (cdr nmcobol-this-paren-type) t t)
  826. )
  827. )
  828. "A list of regexp's or functions. Used to add syntax-table properties to
  829. characters that can't be set by the syntax-table alone.")
  830. ;(defun nmcobol-start-of-statement-hook ()
  831. ; "Used as `font-lock-extend-region-functions' hook which see."
  832. ; ;; WARNING - any malfunction in this can cause emacs to enter a loop
  833. ; ;; that C-g will not break out of. Your session (and all edits) will
  834. ; ;; be toast.
  835. ; ;; There seems to be no good way to suppress the warning caused by
  836. ; ;; accessing font-lock-beg. It's required but apparently only
  837. ; ;; defined within a let statement.
  838. ; (goto-char font-lock-beg)
  839. ; (unless (bolp) (beginning-of-line))
  840. ; (unless (or (looking-at nmcobol-non-cobol-regexp)
  841. ; (looking-at nmcobol-keywords-statements-regexp))
  842. ; (let* ((lim (progn (nmcobol-backward-sentence 0)(point))))
  843. ; (goto-char font-lock-beg)
  844. ; (re-search-backward
  845. ; nmcobol-keywords-statements-regexp lim 'move-anyway)
  846. ; ;; If I reached the beginning of the sentence, there may be
  847. ; ;; comments and blank lines: they don't need refontification.
  848. ; (when (= (point) lim)
  849. ; (while (or (looking-at "^[ \t]*$")
  850. ; (looking-at nmcobol-non-cobol-regexp))
  851. ; (forward-line)))))
  852. ; (unless (eq (point) font-lock-beg)
  853. ; (setq font-lock-beg (point))))
  854. (defun nmcobol-start-of-statement ()
  855. "Used as the syntax-begin function of `font-lock-defaults' which see."
  856. ;; WARNING - any malfunction in this can cause emacs to enter a loop
  857. ;; that C-g will not break out of. Your session (and all edits) will
  858. ;; be toast.
  859. (unless (bolp) (beginning-of-line))
  860. (unless (or (looking-at nmcobol-non-cobol-regexp)
  861. (looking-at nmcobol-keywords-statements-regexp))
  862. (let* ((start (point))
  863. (lim (progn (nmcobol-backward-sentence 0)(point))))
  864. (goto-char start)
  865. (re-search-backward
  866. nmcobol-keywords-statements-regexp lim 'move-anyway)
  867. ;; If I reached the beginning of the sentence, there may be
  868. ;; comments and blank lines: they don't need refontification.
  869. (when (= (point) lim)
  870. (while (and (< (point) start)
  871. (or (looking-at "^[ \t]*$")
  872. (looking-at nmcobol-non-cobol-regexp)))
  873. (forward-line))
  874. (if (> (point) start)
  875. (goto-char start))))))
  876. (defun nmcobol-setup-font-lock ()
  877. "Sets up the buffer local value for font-lock-defaults and optionally
  878. turns on font-lock-mode"
  879. ;; I use font-lock-syntactic-keywords to set some properties and I
  880. ;; don't want them ignored.
  881. (set (make-local-variable 'parse-sexp-lookup-properties) t)
  882. ;; I really can't imagine anyone wanting this off.
  883. (set (make-local-variable 'parse-sexp-ignore-comments) t)
  884. ;; This allows column markers to be different in separate buffers.
  885. (set (make-local-variable 'nmcobol-font-lock-keywords)
  886. (nmcobol-build-font-lock-keywords))
  887. ;; make sure the parsing state is reset
  888. (setq nmcobol-find-syntactic--state ())
  889. ; (setq font-lock-extend-region-functions
  890. ; (append font-lock-extend-region-functions
  891. ; '(nmcobol-start-of-statement-hook)))
  892. ;; This is where all the font-lock stuff actually gets set up. Once
  893. ;; font-lock-defaults has it's value, setting font-lock-mode true should
  894. ;; cause all your syntax highlighting dreams to come true.
  895. (setq font-lock-defaults
  896. ;; The first value is all the keyword expressions.
  897. '(nmcobol-font-lock-keywords
  898. ;; keywords-only means no strings or comments get fontified
  899. nil
  900. ;; case-fold (ignore case)
  901. t
  902. ;; syntax-alist. See also imenu-syntax-alist
  903. ;; This can't override syntax applied by font-lock-syntactic-keywords
  904. ;; It only overrides nmcobol-mode-syntax-table.
  905. nil
  906. ;; syntax-begin - function to move outside syntactic block
  907. ;; This doesn't work for some reason. I'm using the hook
  908. ;; font-lock-extend-region-functions for this.
  909. nil ; nmcobol-start-of-statement
  910. ;; font-lock-syntactic-keywords
  911. ;; takes (matcher (match syntax override lexmatch) ...)...
  912. (font-lock-syntactic-keywords . nmcobol-font-lock-syntactic-keywords)))
  913. ; font lock is turned on by default in this mode. Use customize to disable.
  914. (when nmcobol-font-lock-always (font-lo

Large files files are truncated, but you can click here to view the full file