PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/pflotran.el

https://bitbucket.org/bjandre/pflotran-mode
Emacs Lisp | 913 lines | 584 code | 105 blank | 224 comment | 5 complexity | 23c35527a6d5f577249f7192650bb1a7 MD5 | raw file
  1. ;;; pflotran.el --- emacs mode for editing pflotran input files
  2. ;;
  3. ;;; Copyright (c) 2013 Ben Andre <bjandre@gmail.com>
  4. ;;
  5. ;; Author: Ben Andre
  6. ;; Version: 0.1
  7. ;; Keywords: pflotran
  8. ;;
  9. ;; This program is free software: you can redistribute it and/or
  10. ;; modify it under the terms of the GNU Lesser General Public License
  11. ;; as published by the Free Software Foundation, either version 2 of
  12. ;; the License, or (at your option) any later version.
  13. ;;
  14. ;; This program is distributed in the hope that it will be useful, but
  15. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. ;; Lesser General Public License for more details.
  18. ;;
  19. ;; You should have received a copy of the GNU Lesser General Public
  20. ;; License along with this program. If not, see
  21. ;; <http://www.gnu.org/licenses/>.
  22. ;;
  23. ;;; Usage:
  24. ;;
  25. ;; TAB : indent line
  26. ;; M-TAB : keyword completion
  27. ;;
  28. ;;; Known Issues:
  29. ;;
  30. ;; * pflotran reuses some words as both keywords and section
  31. ;; names. This meas that regexp based syntax highlighting will
  32. ;; occasionally do the wrong thing.
  33. ;;
  34. ;; * Species names can be essentially anything, so regexp will
  35. ;; catch just about anything. Most species names in the database
  36. ;; start with a capitaly letter, so we require all species names
  37. ;; to start with a capital letter. This causes keywords that
  38. ;; aren't explicitly listed to be highlighted as species names,
  39. ;; but allows other words that start with a lower case to be
  40. ;; visable.
  41. ;;
  42. ;; * Indentation is currently based on looking at regexp on previous
  43. ;; lines, it will occasionally do the wrong thing when a word is
  44. ;; both a keyword and a section heading. It will also fail for
  45. ;; things like mineral kinetics where a species name starts a new
  46. ;; indentation block. When either of these happens, just manually
  47. ;; indent the first incorrect line and all following lines should
  48. ;; be determined correctly.
  49. ;;
  50. ;;; Commentary:
  51. ;;
  52. ;; * copy pflotran.el into ~/.emacs.d/
  53. ;;
  54. ;; * edit your init.el and add: (load pflotran.el)
  55. ;;
  56. ;; * PFloTran's ".in" suffix maybe too generic to be useful. You can
  57. ;; disable automatic pflotran mode by commenting the "auto-mode" lines
  58. ;; below, then enable pflotran mode manually by opening a pflotran
  59. ;; input file and typing:
  60. ;;
  61. ;; M-x pflotran-mode
  62. ;;
  63. ;; Or by adding a mode line comment to the first line of your inputfile:
  64. ;;
  65. ;; : -*- mode: pflotran -*-
  66. ;;
  67. ;; Notes:
  68. ;;
  69. ;; Inspired by:
  70. ;; http://www.emacswiki.org/emacs/ModeTutorial
  71. ;; http://www.emacswiki.org/emacs/DerivedMode
  72. ;; http://ergoemacs.org/emacs/elisp_keyword_completion.html
  73. ;;; Code:
  74. (defvar pflotran-mode-hook nil)
  75. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  76. ;;
  77. ;; Open all ".in" files and pflotran input files
  78. ;;
  79. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80. ;;;###autoload
  81. (add-to-list 'auto-mode-alist '("\\.in\\'" . pflotran-mode))
  82. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  83. ;;
  84. ;; Special key bindings for the mode
  85. ;;
  86. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  87. (defvar pflotran-mode-map
  88. (let ((map (make-sparse-keymap)))
  89. (define-key map "\C-j" 'newline-and-indent)
  90. map)
  91. "Keymap for pflotran major mode.")
  92. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  93. ;;
  94. ;; Define the pflotran sections and keywords for syntax highlighting
  95. ;; and indenting
  96. ;;
  97. ;; Notes:
  98. ;;
  99. ;; * sections are keywords that also control indentation. keywords
  100. ;; don't effect indentation. we highlight both sections and keywords
  101. ;;
  102. ;; * if a word is both a keyword and a section name, then the special
  103. ;; section name rules need to go first (top level sections are the
  104. ;; first word on a line)
  105. ;;
  106. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  107. (defvar end-section '("END" "/"))
  108. (defvar toplevel-keywords
  109. '("CHECKPOINT"
  110. "MODE"
  111. "MINIMUM_HYDROSTATIC_PRESSURE"
  112. "MULTIPLE_CONTINUUM"
  113. "PROC"
  114. "REFERENCE_POROSITY"
  115. "REFERENCE_PRESSURE"
  116. "RESTART"
  117. "UNIFORM_VELOCITY"
  118. "WALLCLOCK_STOP"
  119. ))
  120. (defvar toplevel-sections
  121. '("BOUNDARY_CONDITION"
  122. "CHEMISTRY"
  123. "CONSTRAINT"
  124. "DATASET"
  125. "DEBUG"
  126. "FLOW_CONDITION"
  127. "FLUID_PROPERTY"
  128. "GRID"
  129. "INITIAL_CONDITION"
  130. "LINEAR_SOLVER"
  131. "MATERIAL_PROPERTY"
  132. "MODE"
  133. "NEWTON_SOLVER"
  134. "OBSERVATION"
  135. "OUTPUT"
  136. "REGION"
  137. "REGRESSION"
  138. "SATURATION_FUNCTION"
  139. "SECONDARY_CONSTRAINT"
  140. "SOURCE_SINK"
  141. "STRATA"
  142. "TIMESTEPPER"
  143. "TIME"
  144. "TRANSPORT_CONDITION"
  145. ))
  146. (defvar toplevel-all
  147. (append toplevel-keywords toplevel-sections end-section))
  148. (defvar toplevel-sections-re "")
  149. (loop for s in toplevel-sections do
  150. (setq toplevel-sections-re (concat toplevel-sections-re "^" s "\\|")))
  151. ;;
  152. ;; chemistry
  153. ;;
  154. (defvar chemistry-keywords
  155. '("DATABASE"
  156. "LOG_FORMULATION"
  157. "ACTIVITY_COEFFICIENTS" "LAG" "NEWTON" "TIMESTEP" "NEWTON_ITERATION"
  158. "NO_CHECKPOINT_ACT_COEFS"
  159. "NO_BDOT"
  160. "UPDATE_POROSITY"
  161. "UPDATE_PERMEABILITY"
  162. "UPDATE_TORTUOSITY"
  163. "UPDATE_MINERAL_SURFACE_AREA"
  164. "ACTIVITY_H2O" "ACTIVITY_WATER"
  165. "MOLAL" "MOLARITY" "MOLALITY"
  166. "MAX_DLNC"
  167. "MAX_RELATIVE_CHANGE_TOLERANCE"
  168. "MAX_RESIDUAL_TOLERANCE"
  169. "REACTION" "FORWARD_RATE" "BACKWARD_RATE"
  170. "RATE_CONSTANT" "ACTIVATION_ENERGY" "AFFINITY_THRESHOLD"
  171. "RATE_LIMITER" "IRREVERSIBLE" "SURFACE_AREA_POROSITY_POWER"
  172. "SURFACE_AREA_VOL_FRAC_POWER"
  173. "PREFACTOR_SPECIES" "ALPHA" "BETA" "ATTENUATION_COEF"
  174. "MINERAL" "CEC" "DISTRIBUTION_COEFFICIENT" "TYPE" "LINEAR"
  175. "LANGMUIR" "FREUNDLICH" "LANGMUIR_B" "FREUNDLICH_N"
  176. "EQUILIBRIUM" "MULTIRATE_KINETIC" "KINETIC" "COMPLEX_KINETICS"
  177. "MULTIRATE_SCALE_FACTOR" "COLLOID" "SITE"
  178. "OFF" "ALL" "All" "GASES" "PH" "KD" "COLLOIDS" "TOTAL_SORBED_MOBILE"
  179. "TOTAL_SORBED" "FREE_ION" "SITE_DENSITY" "AGE"
  180. ))
  181. (defvar chemistry-sections
  182. '("PRIMARY_SPECIES"
  183. "SECONDARY_SPECIES"
  184. "GAS_SPECIES"
  185. "REDOX_SPECIES"
  186. "GENERAL_REACTION"
  187. "MINERALS"
  188. "MINERAL_KINETICS" "PREFACTOR"
  189. "SORPTION"
  190. "ION_EXCHANGE_RXN" "CATIONS"
  191. "ISOTHERM_REACTIONS"
  192. "SURFACE_COMPLEXATION_RXN" "COMPLEXES" "SITE_FRACTION" "RATES"
  193. "REACTION_SANDBOX"
  194. "OUTPUT"
  195. ))
  196. (defvar chemistry-all
  197. (append chemistry-keywords chemistry-sections))
  198. ;;
  199. ;; constraint
  200. ;;
  201. (defvar constraint-keywords
  202. '("\ F\ "
  203. "\ G\ "
  204. "\ M\ "
  205. "\ P\ "
  206. "\ pH\ "
  207. "\ S\ "
  208. "\ T\ "
  209. "\ Z\ "
  210. ))
  211. (defvar constraint-sections
  212. '("CONCENTRATIONS"
  213. "MINERALS"
  214. ))
  215. (defvar constraint-all
  216. (append constraint-keywords constraint-sections))
  217. ;;
  218. ;; dataset
  219. ;;
  220. (defvar dataset-keywords
  221. '("HDF5_DATASET_NAME"
  222. "MAX_BUFFER_SIZE"
  223. ))
  224. (defvar dataset-sections
  225. '(""
  226. ))
  227. (defvar dataset-all
  228. (append dataset-keywords dataset-sections))
  229. ;;
  230. ;; debug
  231. ;;
  232. (defvar debug-keywords
  233. '("MATVIEW_JACOBIAN"
  234. "VECVIEW_RESIDUAL"
  235. "VECVIEW_SOLUTION"
  236. ))
  237. (defvar debug-sections
  238. '(""
  239. ))
  240. (defvar debug-all
  241. (append debug-keywords debug-sections))
  242. ;;
  243. ;; flow conditions
  244. ;;
  245. (defvar flow-keywords
  246. '(
  247. "DATUM"
  248. "DATUM LIST"
  249. "FLUX"
  250. "INTERPOLATION LINEAR"
  251. "PRESSURE"
  252. "TEMPERATURE"
  253. "CONCENTRATION"
  254. "ENTHALPY"
  255. "RATE"
  256. "TIME_UNITS"
  257. "UNITS"
  258. ))
  259. (defvar flow-sections
  260. '(;;"TYPE" ;; this cause a lot of problems with other keywords...
  261. "GRADIENT"
  262. ))
  263. (defvar flow-all
  264. (append flow-keywords flow-sections))
  265. ;;
  266. ;; fluid properties
  267. ;;
  268. (defvar fluid-property-keywords
  269. '("DIFFUSION_COEFFICIENT"
  270. ))
  271. (defvar fluid-property-sections
  272. '(""
  273. ))
  274. (defvar fluid-property-all
  275. (append fluid-property-keywords fluid-property-sections))
  276. ;;
  277. ;; grid
  278. ;;
  279. (defvar grid-keywords
  280. '("TYPE"
  281. "NXYZ"
  282. "GRAVITY"
  283. "ORIGIN"
  284. "INVERT_Z"
  285. "FILENAME"))
  286. (defvar grid-sections
  287. '("BOUNDS"
  288. "DXYZ"))
  289. (defvar grid-all
  290. (append grid-keywords grid-sections))
  291. ;;
  292. ;; initial/boundary conditions
  293. ;;
  294. (defvar ic-bc-keywords
  295. '("TRANSPORT_CONDITION"
  296. "FLOW_CONDITION"
  297. "REGION"
  298. ))
  299. (defvar ic-bc-sections
  300. '(""
  301. ))
  302. (defvar ic-bc-all
  303. (append ic-bc-keywords ic-bc-sections))
  304. ;;
  305. ;; material properties
  306. ;;
  307. (defvar material-property-keywords
  308. '("ID"
  309. "NAME"
  310. "POROSITY"
  311. "POROSITY DATASET"
  312. "ANISOTROPIC"
  313. "ISOTROPIC"
  314. "PERM_ISO"
  315. "PERM_X"
  316. "PERM_Y"
  317. "PERM_Z"
  318. "VERTICAL_ANISOTROPY_FACTOR"
  319. "DATASET"
  320. "PERMEABILITY_POWER"
  321. "TORTUOSITY"
  322. "TORTUOSITY_POWER"
  323. "SATURATION_FUNCTION"
  324. "ROCK_DENSITY"
  325. "SPECIFIC_HEAT"
  326. "LONGITUDINAL_DISPERSIVITY"
  327. "THERMAL_CONDUCTIVITY_DRY"
  328. "THERMAL_CONDUCTIVITY_WET"
  329. "PORE_COMPRESSIBILITY"
  330. "THERMAL_EXPANSITIVITY"
  331. "TYPE" "SLAB"
  332. "LENGTH"
  333. "AREA"
  334. "NUM_CELLS"
  335. "EPSILON"
  336. ))
  337. (defvar material-property-sections
  338. '("PERMEABILITY"
  339. "SECONDARY_CONTINUUM"
  340. ))
  341. (defvar material-property-all
  342. (append material-property-keywords material-property-sections))
  343. ;;
  344. ;; mode
  345. ;;
  346. (defvar mode-keywords
  347. '("RICHARDS"
  348. "THC"
  349. "TH"
  350. ))
  351. (defvar mode-sections
  352. '(""
  353. ))
  354. (defvar mode-all
  355. (append mode-keywords mode-sections))
  356. ;;
  357. ;; observation
  358. ;;
  359. (defvar observation-keywords
  360. '("REGION"
  361. "VELOCITY"
  362. "AT_CELL_CENTER"
  363. "SECONDARY_CONCENTRATION"
  364. "SECONDARY_MINERAL_VOLFRAC"
  365. ))
  366. (defvar observation-sections
  367. '(""
  368. ))
  369. (defvar observation-all
  370. (append observation-keywords observation-sections))
  371. ;;
  372. ;; output
  373. ;;
  374. (defvar output-keywords
  375. '("NO_PRINT_INITIAL"
  376. "NO_PRINT_FINAL"
  377. "SCREEN PERIODIC"
  378. "PERIODIC_OBSERVATION"
  379. "PERIODIC"
  380. "TIMESTEP"
  381. "TIMES"
  382. "TIME"
  383. "FORMAT"
  384. "MASS_BALANCE"
  385. "FORMAT"
  386. "TECPLOT"
  387. "HDF5"
  388. "MULTIPLE_FILES"
  389. "POINT"
  390. "PRINT_COLUMN_IDS"
  391. "PROCESSOR_ID"
  392. "VELOCITIES"
  393. ))
  394. (defvar output-sections
  395. '(""
  396. ))
  397. (defvar output-all
  398. (append output-keywords output-sections))
  399. ;;
  400. ;; region
  401. ;;
  402. (defvar region-keywords
  403. '("COORDINATE"
  404. "BLOCK"
  405. "FILE"
  406. "FACE"
  407. "NORTH" "SOUTH" "EAST" "WEST" "BOTTOM" "TOP"
  408. ))
  409. (defvar region-sections
  410. '("COORDINATES"
  411. ))
  412. (defvar region-all
  413. (append region-keywords region-sections))
  414. ;;
  415. ;; regression
  416. ;;
  417. (defvar regression-keywords
  418. '("CELLS_PER_PROCESS"
  419. ))
  420. (defvar regression-sections
  421. '("CELLS"
  422. ))
  423. (defvar regression-all
  424. (append regression-keywords regression-sections))
  425. ;;
  426. ;; saturation function
  427. ;;
  428. (defvar saturation-function-keywords
  429. '("SATURATION_FUNCTION_TYPE"
  430. "VAN_GENUCHTEN"
  431. "BROOKS_COREY"
  432. "RESIDUAL_SATURATION"
  433. "LAMBDA"
  434. "ALPHA"
  435. "LIQUID_PHASE"
  436. "GAS_PHASE"
  437. "MAX_CAPILLARY_PRESSURE"
  438. ))
  439. (defvar saturation-function-sections
  440. '(""
  441. ))
  442. (defvar saturation-function-all
  443. (append saturation-function-keywords saturation-function-sections))
  444. ;;
  445. ;; newton and linear solver
  446. ;;
  447. (defvar solver-keywords
  448. '("MATRIX_TYPE"
  449. "PRECONDITIONER_MATRIX_TYPE"
  450. "AIJ"
  451. "RTOL"
  452. "ATOL"
  453. "STOL"
  454. "NO_INFINITY_NORM"
  455. "NO_PRINT_CONVERGENCE"
  456. "PRINT_DETAILED_CONVERGENCE"
  457. "SOLVER DIRECT"
  458. "MAX_NORM"
  459. "ITOL_UPDATE"
  460. "ITOL"
  461. "MAXIT"
  462. "MAXF"
  463. "KSP_TYPE" "PREONLY"
  464. "PC_TYPE" "LU"
  465. ))
  466. (defvar solver-sections
  467. '(""
  468. ))
  469. (defvar solver-all
  470. (append solver-keywords solver-sections))
  471. ;;
  472. ;; strata
  473. ;;
  474. (defvar strata-keywords
  475. '("REGION"
  476. "MATERIAL"
  477. ))
  478. (defvar strata-sections
  479. '(""
  480. ))
  481. (defvar strata-all
  482. (append strata-keywords strata-sections))
  483. ;;
  484. ;; time
  485. ;;
  486. (defvar time-keywords
  487. '("FINAL_TIME"
  488. "INITIAL_TIMESTEP_SIZE"
  489. "MAXIMUM_TIMESTEP_SIZE"
  490. "STEADY_STATE"))
  491. (defvar time-sections
  492. '(""
  493. ))
  494. (defvar time-all
  495. (append time-keywords time-sections))
  496. ;;
  497. ;; time stepper
  498. ;;
  499. (defvar timestepper-keywords
  500. '("FLOW"
  501. "TRANSPORT"
  502. "NUM_STEPS_AFTER_CUT"
  503. "MAX_STEPS"
  504. "TS_ACCELERATION"
  505. "MAX_TS_CUTS"
  506. "CFL_LIMITER"
  507. "DT_FACTOR"
  508. "INITIALIZE_TO_STEADY_STATE"
  509. "RUN_AS_STEADY_STATE"
  510. "MAX_PRESSURE_CHANGE"
  511. "MAX_TEMPERATURE_CHANGE"
  512. "MAKE_CONCENTRATION_CHANGE"
  513. "MAX_SATURATION_CHANGE"
  514. ))
  515. (defvar timestepper-sections
  516. '(""
  517. ))
  518. (defvar timestepper-all
  519. (append timestepper-keywords timestepper-sections))
  520. ;;
  521. ;; transport conditions
  522. ;;
  523. (defvar transport-condition-keywords
  524. '("TYPE"
  525. "dirchlet" "dirchlet_zero_gradient" "zero_gradient" "neumann" "equilibrium"
  526. ))
  527. (defvar transport-condition-sections
  528. '("CONSTRAINT_LIST"
  529. "CONSTRAINT"
  530. ))
  531. (defvar transport-condition-all
  532. (append transport-condition-keywords transport-condition-sections))
  533. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  534. ;;
  535. ;; Create some combined sections and regular expressions
  536. ;;
  537. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  538. (defvar pflotran-all
  539. (append toplevel-all
  540. chemistry-all
  541. constraint-all
  542. debug-all
  543. dataset-all
  544. flow-all
  545. fluid-property-all
  546. grid-all
  547. ic-bc-all
  548. material-property-all
  549. mode-all
  550. observation-all
  551. output-all
  552. region-all
  553. regression-all
  554. saturation-function-all
  555. solver-all
  556. strata-all
  557. time-all
  558. timestepper-all
  559. transport-condition-all
  560. ))
  561. (defvar pflotran-all-re
  562. (regexp-opt pflotran-all 'symbols))
  563. (defvar pflotran-keywords
  564. (append
  565. toplevel-keywords
  566. chemistry-keywords
  567. constraint-keywords
  568. debug-keywords
  569. dataset-keywords
  570. flow-keywords
  571. fluid-property-keywords
  572. grid-keywords
  573. ic-bc-keywords
  574. material-property-keywords
  575. mode-keywords
  576. observation-keywords
  577. output-keywords
  578. region-keywords
  579. regression-keywords
  580. saturation-function-keywords
  581. solver-keywords
  582. strata-keywords
  583. time-keywords
  584. timestepper-keywords
  585. transport-condition-keywords
  586. ))
  587. (defvar pflotran-keywords-re
  588. (regexp-opt pflotran-keywords 'symbols))
  589. (defvar pflotran-sections-re
  590. (concat toplevel-sections-re
  591. (regexp-opt (append
  592. end-section
  593. chemistry-sections
  594. constraint-sections
  595. debug-sections
  596. dataset-sections
  597. flow-sections
  598. fluid-property-sections
  599. grid-sections
  600. ic-bc-sections
  601. material-property-sections
  602. mode-sections
  603. observation-sections
  604. output-sections
  605. region-sections
  606. regression-sections
  607. saturation-function-sections
  608. solver-sections
  609. strata-sections
  610. time-sections
  611. timestepper-sections
  612. transport-condition-sections
  613. ))))
  614. (defvar pflotran-sections
  615. (append
  616. toplevel-sections
  617. chemistry-sections
  618. constraint-sections
  619. debug-sections
  620. dataset-sections
  621. flow-sections
  622. fluid-property-sections
  623. grid-sections
  624. ic-bc-sections
  625. material-property-sections
  626. mode-sections
  627. observation-sections
  628. output-sections
  629. region-sections
  630. regression-sections
  631. saturation-function-sections
  632. solver-sections
  633. strata-sections
  634. time-sections
  635. timestepper-sections
  636. transport-condition-sections
  637. ))
  638. (setq pflotran-sections (delete "" pflotran-sections))
  639. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  640. ;;
  641. ;; Assign keywords to a font lock for syntax highlighting
  642. ;;
  643. ;; Notes:
  644. ;;
  645. ;; * font-lock for sections and keywords go first and species names
  646. ;; go last so that the generic regexp for species names doesn't also
  647. ;; catch the keywords.
  648. ;;
  649. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  650. (defvar integer-re "[ \t]+[0-9]+\\>")
  651. (defvar float-re "\\<[-+]?[0-9]+\.\\([0-9]+\\)?[eEdD]?[-+]?[0-9]+\\>")
  652. (defvar species-name-re ">?[A-Z\(][A-Za-z0-9\(\)_\.]*[-+]*")
  653. ;;font-lock-builtin-face font-lock-keyword-face
  654. (defvar pflotran-font-lock-defaults
  655. `((
  656. ( , pflotran-sections-re . font-lock-type-face)
  657. ( , pflotran-keywords-re . font-lock-keyword-face)
  658. ;; ( , pflotran-all-re . font-lock-keyword-face)
  659. ( , integer-re . font-lock-constant-face)
  660. ( , float-re . font-lock-constant-face)
  661. ( , species-name-re . font-lock-variable-name-face)
  662. )))
  663. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  664. ;;
  665. ;; Create per-line indenting rules
  666. ;;
  667. ;; Rules based on : http://emacswiki.org/emacs/ModeTutorial
  668. ;;
  669. ;; Indentation Rules:
  670. ;;
  671. ;; 1) start with indent = 0 at the begining of the buffer
  672. ;;
  673. ;; 2) if we are at an end of section marker, move indent back
  674. ;;
  675. ;; 3) if the previous line was an end of section, use the same indentation level
  676. ;;
  677. ;; 4) if the previous line was a section, then increase indentation level
  678. ;;
  679. ;; 5) if the previous line is a keyword, use the same indent
  680. ;;
  681. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  682. (defvar pflotran-tab-width 2)
  683. (defvar end-section-re
  684. (concat "^[ \t]*" (regexp-opt end-section)))
  685. (defvar sections-re
  686. "^[ \t]*")
  687. (setq sections-re (concat sections-re (regexp-opt pflotran-sections)))
  688. (defvar keywords-re
  689. "^[ \t]*")
  690. (setq keywords-re (concat keywords-re (regexp-opt pflotran-keywords)))
  691. (defvar debug-indent nil)
  692. (defun pflotran-indent-line ()
  693. "Indent current line in pflotran input."
  694. (interactive)
  695. (beginning-of-line)
  696. (if (bobp) ; rule 1: begining of buffer (line)
  697. (progn
  698. (if debug-indent (print "indent rule 1 (begining of buffer)"))
  699. (indent-line-to 0))
  700. (let ((not-indented t) cur-indent)
  701. (if (looking-at end-section-re) ; rule 2: end section
  702. (progn
  703. (if debug-indent (print "indent rule 2 (current end)"))
  704. (save-excursion
  705. (forward-line -1)
  706. (setq cur-indent (- (current-indentation) pflotran-tab-width)))
  707. (if (< cur-indent 0)
  708. (setq cur-indent 0)))
  709. (save-excursion
  710. (while not-indented
  711. (forward-line -1)
  712. (if (looking-at end-section-re) ; rule 3
  713. (progn
  714. (if debug-indent (print "indent rule 3 (previous end)"))
  715. (setq cur-indent (current-indentation))
  716. (setq not-indented nil))
  717. (if (looking-at "^[ \t]*$")
  718. (progn
  719. ;; can't tell what to do from a blank line, go back further
  720. (if debug-indent (print "indent blank line"))
  721. )
  722. (if (looking-at sections-re) ; rule 4
  723. (progn
  724. (if debug-indent (print "indent rule 4 (section)"))
  725. (setq cur-indent (+ (current-indentation) pflotran-tab-width))
  726. (setq not-indented nil))
  727. (if (looking-at keywords-re)
  728. (progn ; rule 5
  729. (if debug-indent (print "indent rule 5 (keywords)"))
  730. (setq not-indented nil)
  731. (setq cur-indent (current-indentation))
  732. )
  733. (if (bobp)
  734. (progn
  735. ;; all the way back to the beginning of buffer, bail
  736. (if debug-indent (print "indent returned to bobp"))
  737. (setq not-indented nil))
  738. ))))))))
  739. (if cur-indent
  740. (indent-line-to cur-indent)
  741. (indent-line-to 0)))))
  742. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  743. ;;
  744. ;; Keyword completion
  745. ;;
  746. ;; Based on : http://ergoemacs.org/emacs/elisp_keyword_completion.html
  747. ;;
  748. ;; Algorithm notes:
  749. ;;
  750. ;; 1) when the begining of the keyword is empty, set it to empty
  751. ;; string. try-completion will then show all keywords.
  752. ;;
  753. ;; 2) store possible completions in maxMaxResult
  754. ;;
  755. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  756. (defun pflotran-completions ()
  757. "Keyword completion for the word behind the cursor."
  758. (interactive)
  759. (let ((end-point (point))
  760. (begin-keyword (thing-at-point 'symbol))
  761. match-result)
  762. (when (not begin-keyword) (setq begin-keyword "")) ;; note 1
  763. (setq match-result (try-completion begin-keyword pflotran-all))
  764. (cond ((eq match-result t)) ;; already a full keyword w/o another completion
  765. ((null match-result) ;; no match
  766. (message "No completion for '%s'" begin-keyword)
  767. (ding))
  768. ((not (string= begin-keyword match-result)) ;; single match, use it
  769. (delete-region (- end-point (length begin-keyword)) end-point) ;; subtract the alreayd typed region
  770. (insert match-result))
  771. (t (message "Making completion list...")
  772. (with-output-to-temp-buffer "*Completions*"
  773. (display-completion-list
  774. (all-completions begin-keyword pflotran-all)
  775. begin-keyword))
  776. (message "Making completion list...%s" "done")))
  777. )
  778. )
  779. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  780. ;;
  781. ;; Derive pflotran mode from fundamental mode, adding our custom
  782. ;; syntax and indenting rules
  783. ;;
  784. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  785. (define-derived-mode pflotran-mode fundamental-mode "PFloTran"
  786. "Major mode for editing pflotran input files"
  787. (setq font-lock-defaults pflotran-font-lock-defaults)
  788. (set (make-local-variable 'indent-line-function) 'pflotran-indent-line)
  789. (when pflotran-tab-width
  790. (setq tab-width pflotran-tab-width))
  791. (setq-default indent-tabs-mode nil)
  792. (global-set-key (kbd "M-TAB") 'pflotran-completions)
  793. ;; comment syntax
  794. ;(setq comment-start "skip")
  795. ;(setq comment-end "noskip")
  796. (modify-syntax-entry ?: "<" pflotran-mode-syntax-table)
  797. (modify-syntax-entry ?! "<" pflotran-mode-syntax-table)
  798. (modify-syntax-entry ?\n ">" pflotran-mode-syntax-table)
  799. ;; make some symbols word characters so they can be used in keywords
  800. ;; and species names
  801. (modify-syntax-entry ?_ "w" pflotran-mode-syntax-table)
  802. (modify-syntax-entry ?/ "w" pflotran-mode-syntax-table)
  803. (modify-syntax-entry ?+ "w" pflotran-mode-syntax-table)
  804. (modify-syntax-entry ?- "w" pflotran-mode-syntax-table)
  805. (modify-syntax-entry ?. "w" pflotran-mode-syntax-table)
  806. )
  807. (provide 'pflotran-mode)
  808. ;;; pflotran.el ends here