Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1845 lines
77 KiB

4 years ago
  1. ;;; ess-sas-l.el --- SAS customization
  2. ;; Copyright (C) 1997--2009 A.J. Rossini, Richard M. Heiberger, Martin
  3. ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
  4. ;; Authors: Richard M. Heiberger
  5. ;; A.J. Rossini
  6. ;; Rodney Sparapani
  7. ;; Created: 20 Aug 1997
  8. ;; Maintainer: ESS-core <ESS-core@r-project.org>
  9. ;; Keywords: languages
  10. ;; This file is part of ESS (Emacs Speaks Statistics).
  11. ;; This file is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 2, or (at your option)
  14. ;; any later version.
  15. ;; This file is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;; A copy of the GNU General Public License is available at
  20. ;; https://www.r-project.org/Licenses/
  21. ;;; Commentary:
  22. ;; This is based upon Version 1.4 of SAS mode:
  23. ;;; sas-mode: indent, run etc, SAS programs.
  24. ;;; Copyright (C) 1994--1997 Tom Cook
  25. ;;; Author: Tom Cook
  26. ;;; Dept. of Biostatistics
  27. ;;; University of Wisconsin - Madison
  28. ;;; Madison, WI 53706
  29. ;;; cook@biostat.wisc.edu
  30. ;;;
  31. ;;; Acknowledgements:
  32. ;;; Menu code for XEmacs/Lucid emacs and startup mods
  33. ;;; contributed by arossini@biostats.hmc.psu.edu
  34. ;;;
  35. ;;; Last change: 2/1/95
  36. ;;; Last change: 01/15/02
  37. ;;; Code:
  38. (require 'ess-mode)
  39. (require 'ess-sas-a)
  40. (declare-function SAS-mode "ess-sas-d")
  41. (put 'ess-transcript-minor-mode 'permanent-local t)
  42. (or (assq 'ess-transcript-minor-mode minor-mode-alist)
  43. (setq minor-mode-alist
  44. (append minor-mode-alist
  45. (list '(ess-transcript-minor-mode " ESStr")))))
  46. (put 'ess-listing-minor-mode 'permanent-local t)
  47. (or (assq 'ess-listing-minor-mode minor-mode-alist)
  48. (setq minor-mode-alist
  49. (append minor-mode-alist
  50. (list '(ess-listing-minor-mode " ESSlst")))))
  51. (defun ess-transcript-minor-mode (&optional arg)
  52. "Toggle Ess-Transcript minor mode.
  53. With arg, turn Ess-Transcript minor mode on if arg is positive, off
  54. otherwise. See the command `ess-transcript-mode' for more information
  55. on this mode."
  56. (interactive "P")
  57. (setq ess-transcript-minor-mode
  58. (if (null arg) (not ess-transcript-minor-mode)
  59. (> (prefix-numeric-value arg) 0)))
  60. (force-mode-line-update)
  61. (setq mode-line-process
  62. '(" [" ess-local-process-name "]")))
  63. (defun ess-listing-minor-mode (&optional arg)
  64. "Toggle Ess-Listing minor mode.
  65. With arg, turn Ess-Listing minor mode on if arg is positive, off
  66. otherwise. Ess-Listing mode is used solely to place an indicator on
  67. the mode line."
  68. (interactive "P")
  69. (setq ess-listing-minor-mode
  70. (if (null arg) (not ess-listing-minor-mode)
  71. (> (prefix-numeric-value arg) 0)))
  72. (force-mode-line-update)
  73. (setq mode-line-process
  74. '(" [" ess-local-process-name "]")))
  75. (defcustom ess-automatic-sas-log-or-lst-mode t
  76. "Automatically turn on `SAS-log-mode' and `SAS-listing-mode' when enabled."
  77. :type 'boolean
  78. :group 'ess-sas)
  79. (defun ess-SAS-log-mode-p ()
  80. "Return t when when a SAS log file is detected.
  81. A SAS log is defined as having:
  82. 1. The first line matches \"^1[ \t]*The SAS System\"
  83. 2. The file name ends in .log.
  84. "
  85. (and ess-automatic-sas-log-or-lst-mode
  86. (save-excursion
  87. (goto-char (point-min))
  88. (looking-at "1[ \t]*The SAS System"))
  89. (if (buffer-file-name)
  90. (string-match ".log$" (buffer-file-name))
  91. t)))
  92. (defun ess-SAS-listing-mode-p ()
  93. "Return t when SAS listing file is detected.
  94. A .lst file is a SAS listing file when:
  95. 1. The file name ends in .lst
  96. 2. The corresponding log file exists and is a SAS log file.
  97. "
  98. (when ess-automatic-sas-log-or-lst-mode
  99. (let* ((bfn (buffer-file-name))
  100. (log (and bfn
  101. (string-match-p "\\.lst$" bfn)
  102. (replace-regexp-in-string "\\.lst$" ".log" bfn))))
  103. (and log
  104. (file-exists-p log)
  105. (with-temp-buffer
  106. (insert-file-contents log nil 0 200)
  107. (goto-char (point-min))
  108. (looking-at "1[ \t]*The SAS System"))))))
  109. (add-to-list 'magic-mode-alist
  110. '(ess-SAS-log-mode-p . SAS-log-mode))
  111. (add-to-list 'magic-mode-alist
  112. '(ess-SAS-listing-mode-p . SAS-listing-mode))
  113. (define-derived-mode SAS-log-mode SAS-mode "ESS[LOG]"
  114. "`ess-transcript-mode' for SAS."
  115. :group 'ess-sas
  116. (ess-transcript-minor-mode 1)
  117. (setq buffer-read-only t) ;; to protect the buffer.
  118. (buffer-disable-undo))
  119. (defvar sas-mode-local-map nil "contains modified local keymap for SAS")
  120. (define-derived-mode SAS-listing-mode special-mode "ESS[LST]"
  121. "Fundamental mode with `ess-listing-minor-mode' and read-only."
  122. :keymap sas-mode-local-map
  123. :group 'ess-sas
  124. (ess-listing-minor-mode 1)
  125. (buffer-disable-undo))
  126. (fset 'sas-log-mode 'SAS-log-mode)
  127. (fset 'SAS-transcript-mode 'SAS-log-mode)
  128. (fset 'sas-transcript-mode 'SAS-log-mode)
  129. (fset 'sas-mode 'SAS-mode)
  130. (fset 'sas-listing-mode 'SAS-listing-mode)
  131. (defcustom sas-indent-width 4
  132. "Amount to indent sas statements."
  133. :group 'ess-sas
  134. :type 'integer)
  135. (defcustom sas-indent-ignore-comment "\\*"
  136. "Comments that start with this regular expression are ignored in indentation."
  137. :group 'ess-sas
  138. :type 'string)
  139. (defcustom sas-require-confirmation t
  140. "Require confirmation when revisiting a modified sas-output file."
  141. :group 'ess-sas
  142. :type 'boolean)
  143. (defcustom sas-pre-run-hook nil
  144. "Hook to execute prior to running SAS via `submit-sas'."
  145. :group 'ess-sas
  146. :type 'hook)
  147. (defcustom sas-notify t
  148. "Beep and display message when job is done."
  149. :group 'ess-sas
  150. :type 'boolean)
  151. (defcustom sas-error-notify t
  152. "If `sas-notify' t, indicate errors in log file upon completion."
  153. :group 'ess-sas
  154. :type 'boolean)
  155. (defcustom sas-get-options nil
  156. "Options to be passed to SAS in sas-get-dataset."
  157. :group 'ess-sas
  158. :type '(choice (const nil) string))
  159. (defcustom sas-get-options-history nil
  160. "History list of Options passed to SAS in sas-get-dataset."
  161. :type '(choice (const nil)
  162. (string))
  163. :group 'ess-sas)
  164. (defcustom sas-page-number-max-line 3
  165. "Number of lines from the page break, to search for the page
  166. number."
  167. :group 'ess-sas
  168. :type 'integer)
  169. (defcustom sas-notify-popup nil
  170. "If this and `sas-notify' are t), popup a window when SAS job ends."
  171. :group 'ess-sas
  172. :type 'boolean)
  173. (defcustom sas-tmp-libname "_tmp_"
  174. "Libname to use for sas-get-dataset."
  175. :group 'ess-sas
  176. :type 'string)
  177. (defcustom sas-file-name nil
  178. "The name of the current sas file."
  179. :group 'ess-sas
  180. :type '(choice (const nil) file))
  181. ;; The next two are ``the inside of [...] in a regexp'' to be used in
  182. ;; (skip-chars-(for|back)ward SAS-..-chars)
  183. (defcustom sas-white-chars " \t\n\f"
  184. "This does NOT escape blanks (RMH, 2000/03/20)."
  185. :group 'ess-sas
  186. :type 'string)
  187. (defcustom sas-comment-chars (concat sas-white-chars ";")
  188. "Doc?"
  189. :group 'ess-sas
  190. :type 'string)
  191. (defcustom ess-sas-run-regexp-opt t
  192. "If you do not want to run regexp-opt, then set to nil."
  193. :group 'ess-sas
  194. :type 'boolean)
  195. (defvar sas-buffer-name nil)
  196. (defvar sas-file-root nil)
  197. (defvar sas-submitable nil)
  198. (defvar sas-dataset nil)
  199. (defvar SAS-mode-font-lock-defaults
  200. (if ess-sas-run-regexp-opt
  201. (list
  202. ;; .log NOTE: messages
  203. (cons "^NOTE [0-9]+-[0-9]+: Line generated by the invoked macro"
  204. font-lock-comment-face)
  205. (cons "^NOTE: .*$" font-lock-comment-face)
  206. (cons "^ [^ @].*[.]$" font-lock-comment-face)
  207. (cons "^ [a-z].*[a-z][ ]?$" font-lock-comment-face)
  208. (cons "^ Engine:[ ]+V.+$" font-lock-comment-face)
  209. (cons "^ Physical Name:[ ]+.+$" font-lock-comment-face)
  210. (cons "^ \\(cpu\\|real\\) time[ ]+[0-9].*$"
  211. font-lock-comment-face)
  212. (cons "^ decimal may be shifted by the"
  213. font-lock-comment-face)
  214. (cons "^NOTE: The infile " font-lock-comment-face)
  215. (cons "^NOTE: 1 record was read from the infile "
  216. font-lock-comment-face)
  217. (cons "^NOTE: [1-9][0-9]* records were read from the infile "
  218. font-lock-comment-face)
  219. (cons "^ Filename=.*,$" font-lock-comment-face)
  220. (cons "^ File Name=.*,$" font-lock-comment-face)
  221. (cons "^ File $" font-lock-comment-face)
  222. (cons "^ Name=.*,$" font-lock-comment-face)
  223. (cons "^ File List=(" font-lock-comment-face)
  224. (cons "^ List=(" font-lock-comment-face)
  225. (cons "^ Owner Name=.*,$" font-lock-comment-face)
  226. (cons "^ Access Permission=.*,$" font-lock-comment-face)
  227. (cons "^ Last Modified=.*,?$" font-lock-comment-face)
  228. (cons "^ File Size (bytes)=[0-9]+$" font-lock-comment-face)
  229. (cons "^ Pipe command=" font-lock-comment-face)
  230. (cons "^NOTE: The file " font-lock-comment-face)
  231. (cons "^NOTE: 1 record was written to the file "
  232. font-lock-comment-face)
  233. (cons "^NOTE: [1-9][0-9]* records were written to the file "
  234. font-lock-comment-face)
  235. (cons "^NOTE: PROC LOGISTIC is modeling the probability that"
  236. font-lock-comment-face)
  237. (cons "^NOTE: PROC GENMOD is modeling the probability that"
  238. font-lock-comment-face)
  239. (cons "^1[ ]+The SAS System.*$" font-lock-comment-face)
  240. (cons "^\014.*$" font-lock-comment-face)
  241. (cons "[*][*][*] ANNOTATE macros are now available [*][*][*]"
  242. font-lock-comment-face)
  243. (cons "For further information on ANNOTATE macros, enter,"
  244. font-lock-comment-face)
  245. ;; (cons "^SAS/STAT 9.3_M1, SAS/ETS 9.3_M1, SAS/OR 9.3_M1"
  246. ;; font-lock-comment-face)
  247. (cons "\\(or \\)?%HELPANO.*$"
  248. font-lock-comment-face)
  249. (cons "^Local Variables:$" font-lock-comment-face)
  250. (cons "^End:$" font-lock-comment-face)
  251. (cons "^MPRINT([_A-Z0-9]+)" font-lock-comment-face)
  252. ;; .log ERROR: messages
  253. ; (cons "^ERROR\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
  254. (cons "^ERROR\\( [0-9]+-[0-9]+\\)?: .*$"
  255. font-lock-keyword-face)
  256. ; ERROR:
  257. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  258. font-lock-keyword-face)
  259. ; ERROR #-###:
  260. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  261. font-lock-keyword-face)
  262. ; ERROR ##-###:
  263. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  264. font-lock-keyword-face)
  265. ; ERROR ###-###:
  266. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  267. font-lock-keyword-face)
  268. (cons "^ a format name." font-lock-keyword-face)
  269. (cons "^ where a numeric operand is required. The condition was: "
  270. font-lock-keyword-face)
  271. (cons "[ ][_]+$" font-lock-keyword-face)
  272. ;; .log WARNING: messages
  273. ;(cons "^WARNING\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
  274. (cons "^WARNING\\( [0-9]+-[0-9]+\\)?: .*$"
  275. font-lock-function-name-face)
  276. ; WARNING:
  277. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  278. font-lock-function-name-face)
  279. ; WARNING #-###:
  280. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  281. font-lock-function-name-face)
  282. ; WARNING ##-###:
  283. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  284. font-lock-function-name-face)
  285. ; WARNING ###-###:
  286. (cons "^ [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
  287. font-lock-function-name-face)
  288. ;; SAS comments
  289. ;; /* */ style handled by grammar above
  290. (cons "\\(^[0-9]*\\|[:;!]\\)[ \t]*%?\\*[^;/][^;]*;"
  291. font-lock-comment-face)
  292. ; these over-rides need to come before the more general declarations
  293. (cons "\\<and(" font-lock-function-name-face)
  294. (cons "\\<data=" font-lock-keyword-face)
  295. (cons "\\<in:(" font-lock-function-name-face)
  296. (cons "\\<index(" font-lock-function-name-face)
  297. (cons "\\<input(" font-lock-function-name-face)
  298. (cons "\\<libname(" font-lock-function-name-face)
  299. (cons "\\<not(" font-lock-function-name-face)
  300. (cons "\\<or(" font-lock-function-name-face)
  301. (cons "\\<put(" font-lock-function-name-face)
  302. (cons "\\<sum(" font-lock-function-name-face)
  303. ; other idiosyncratic keywords
  304. ;(cons "key=" font-lock-keyword-face)
  305. ;(cons "/unique" font-lock-keyword-face)
  306. ;; SAS execution blocks: DATA, %MACRO/%MEND, %DO/%END, etc.
  307. (cons (regexp-opt '(
  308. "data" "start" "return" ;"proc"
  309. "%macro" "%mend"
  310. "%do" "%to" "%by" "%end"
  311. "%goto" "%go to"
  312. "%if" "%then" "%else"
  313. "%global" "%inc" "%include" "%input" "%local" "%let" "%put" "%sysexec"
  314. ) 'words) font-lock-constant-face)
  315. ;; SAS execution blocks that must be followed by a semi-colon
  316. (cons (concat "\\<"
  317. (regexp-opt
  318. '(
  319. "run;" "quit;" "endsas;" "finish;"
  320. "cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"
  321. )))
  322. font-lock-constant-face)
  323. ;; SAS statements that must be followed by a semi-colon
  324. (cons (concat "\\<"
  325. (regexp-opt
  326. '(
  327. "end;" "list;" "lostcard;" "page;" "stop;" ;"return;"
  328. )))
  329. font-lock-keyword-face)
  330. ;; SAS statements that must be followed by an equal sign
  331. (cons (concat "\\<"
  332. (regexp-opt
  333. '(
  334. "compress=" "in=" "out=" "sortedby="
  335. )))
  336. font-lock-keyword-face)
  337. ;;; ;; SAS procedure names
  338. (cons (concat "\\<proc[ ]+"
  339. (regexp-opt '(
  340. ;; SAS base and SAS/Graph
  341. "append"
  342. "calendar" "catalog" "chart" "cimport" "cport" "compare" "contents" "copy" "corr"
  343. "datasets" "dbcstab" "display"
  344. "explode" "export"
  345. "fcmp" "format" "forms" "freq" "fsbrowse" "fsedit" "fsletter" "fslist" "fsview"
  346. "ganno" "gchart" "gcontour" "gdevice" "geocode" "gfont" "gimport" "ginside"
  347. "gkeymap" "gmap" "goptions" "gplot" "gprint" "gproject" "greduce" "gremove"
  348. "greplay" "gslide" "gtestit" "g3d" "g3grid"
  349. "iml" "import" "insight"
  350. "mapimport" "means"
  351. "options"
  352. "plot" "pmenu" "print" "printto"
  353. "rank" "registry" "report"
  354. "setinit" "sgdesign" "sgmap"
  355. "sgpanel" "sgplot" "sgrender" "sgscatter" "sort" "sql" "standard" "summary"
  356. "tabulate" "template" "timeplot" "transpose" "trantab"
  357. "univariate"
  358. ;;SAS/Stat and SAS/ETS
  359. "aceclus" "anova" "arima" "autoreg"
  360. "bgenmod" "blifereg" "boxplot" "bphreg"
  361. "calis" "cancorr" "candisc" "catmod" "citibase" "cluster" "computab" "corresp" "countreg"
  362. "discrim" "distance"
  363. "entropy" "expand"
  364. "factor" "fastclus" "forecast"
  365. "gam" "gee" "genmod" "glimmix" "glm" "glmmod" "glmpower" "glmselect"
  366. "hpmixed"
  367. "inbreed"
  368. "kde" "krige2d"
  369. "lattice" "lifereg" "lifetest" "loess" "logistic"
  370. "mcmc" "mdc" "mds" "mi" "mianalyze" "mixed" "modeclus" "model" "mortgage" "multtest"
  371. "nested" "nlin" "nlmixed" "npar1way"
  372. "orthoreg"
  373. "panel" "pdlreg" "phreg" "plan" "plm" "pls" "power" "princomp" "prinqual" "probit"
  374. "qlim" "quantreg"
  375. "reg" "risk" "robustreg" "rsreg"
  376. "score" "seqdesign" "seqtest" "severity" "sim2d" "similarity" "simlin" "simnormal"
  377. "spectra" "statespace" "stdize" "stepdisc"
  378. "surveyfreq" "surveylogistic" "surveymeans" "surveyphreg" "surveyreg" "surveyselect" "syslin"
  379. "tcalis" "timeid" "timeseries" "tphreg" "tpspline" "transreg" "tree" "ttest"
  380. "ucm"
  381. "varclus" "varcomp" "variogram" "varmax"
  382. "x11" "x12"
  383. ) 'words)) font-lock-constant-face)
  384. ; (cons (concat
  385. ; "\\<"
  386. ; "do[ \t]*" (regexp-opt '("over" "until" "while") t) "?"
  387. ; "\\>")
  388. ; font-lock-keyword-face)
  389. ;
  390. ;; SAS base and SAS/Graph statements
  391. (cons (concat ;"\\<"
  392. (regexp-opt
  393. '(
  394. "do" "to" "by" "goto" ; "go"
  395. "abort" "and" "array" "assess" "attrib"
  396. "baseline" "bayes" "between" "bivar" "block" "bubble" "bubble2"
  397. "change" "choro" "class" "contains" "contrast"
  398. "delete" "display" "dm" "donut" "drop"
  399. "else" "error" "exchange" "exclude"
  400. "fcs" "file" "filename" "format" "freq"
  401. "footnote" "footnote1" "footnote2" "footnote3" "footnote4" "footnote5"
  402. "footnote6" "footnote7" "footnote8" "footnote9" "footnote10"
  403. "goptions" "grid" ; "ge" "gt"
  404. "hazardratio" "hbar" "hbar3d"
  405. "id" "if" "index" "infile" "informat" "input" ; "is" rarely used, but common false pos.
  406. "keep"
  407. "label" "length" "libname" "like" "link" "lsmeans" ; "le" "lt"
  408. "manova" "means" "merge" "missing" "model" "modify"
  409. "not" "null" ; "ne" "note"
  410. "ods" "options" "output" "otherwise" ; "or"
  411. "pageby" "parms" "pie" "pie3d" "plot" "plot2" "prism" "put"
  412. "random" "rename" "repeated" "retain"
  413. "same" "save" "scatter" "select" "set" "skip" "star" "strata" "sum" "sumby" "surface"
  414. "table" "tables" "test" "then" "time"
  415. "title" "title1" "title2" "title3" "title4" "title5"
  416. "title6" "title7" "title8" "title9" "title10"
  417. "univar" "update"
  418. "value" "var" "vbar" "vbar3d"
  419. "weight" "where" "window" "with"
  420. ; "x"
  421. ) 'words)) ;"\\>")
  422. font-lock-keyword-face)
  423. ;; SAS/GRAPH statements not handled above
  424. (cons (concat "\\<"
  425. (regexp-opt
  426. '("axis" "legend" "pattern" "symbol")) "\\([1-9][0-9]?\\)?"
  427. "\\>")
  428. font-lock-keyword-face)
  429. ;; SAS functions and SAS macro functions
  430. (cons "%[a-z_][a-z_0-9]*[(;]" font-lock-function-name-face)
  431. ;(cons "\\<call[ \t]+[a-z]+(" font-lock-function-name-face)
  432. (cons (concat ;"\\<"
  433. (regexp-opt
  434. '(
  435. "abs" "arcos" "arsin" "atan"
  436. "betainv" "byte"
  437. "call execute" "call label" "call module" "call modulei"
  438. "call poke" "call ranbin" "call rancau" "call ranexp"
  439. "call rangam" "call rannor" "call ranpoi" "call rantbl"
  440. "call rantri" "call ranuni" "call rxchange" "call rxfree"
  441. "call rxsubstr" "call set" "call streaminit" "call symput" "call system"
  442. "cdf" "ceil" "cinv" "collate" "compress" "convx" "convxp" "cos" "cosh" "css" "cv"
  443. "daccdb" "daccdbsl" "daccsl" "daccsyd" "dacctab"
  444. "depdb" "depdbsl" "depsl" "depsyd" "deptab"
  445. "date" "datejul" "datepart" "datetime" "day" "dhms" "dif" "digamma" "dim"
  446. "erf" "erfc" "exp"
  447. "finv" "fipname" "fipnamel" "fipstate" "floor" "fuzz"
  448. "gaminv" "gamma"
  449. "hbound" "hms" "hour"
  450. "in" "index" "indexc" "input" "int" "intck" "intnx" "intrr" "irr"
  451. "juldate"
  452. "kurtosis"
  453. "lag" "lbound" "left" "length" "lgamma" "log" "log10" "log2"
  454. "logcdf" "logpdf" "logsdf"
  455. "max" "mdy" "mean" "min" "minute" "mod" "month" "mort"
  456. "n" "netpv" "nmiss" "normal" "npv"
  457. "ordinal"
  458. "pdf"
  459. "probbeta" "probbnml" "probchi" "probf" "probgam" "probhypr" "probit" "probnegb" "probnorm" "probt"
  460. "poisson" "put"
  461. "qtr" "quantile"
  462. "rand" "range" "rank" "repeat" "reverse" "right" "round" "rxmatch" "rxparse"
  463. "ranbin" "rancau" "ranexp" "rangam" "rannor" "ranpoi" "rantbl" "rantri" "ranuni"
  464. "saving" "scan" "sdf" "second" "sign" "sin" "sinh" "sqrt" "squantile"
  465. "std" "stderr" "stfips" "stname" "stnamel" "substr" "sum" "symget"
  466. "tan" "tanh" "time" "timepart" "tinv" "today" "translate" "trigamma" "trim" "trunc"
  467. "uniform" "until" "upcase" "uss"
  468. "var" "verify"
  469. "weekday" "when" "while"
  470. "year" "yyq"
  471. "zipfips" "zipname" "zipnamel" "zipstate"
  472. ;;; ;; SAS/IML functions
  473. "all" "allcomb" "allperm" "any" "apply" "armasim"
  474. "bin" "blankstr" "block" "branks" "bspline" "btran" "byte"
  475. "char" "choose" "col" "colvec" "concat" "contents" "convexit" "corr" "corr2cov"
  476. "countmiss" "countn" "countunique" "cov" "cov2corr" "covlag" "cshape" "cusum"
  477. "cuprod" "cv" "cvexhull"
  478. "datasets" "design" "designf" "det" "diag" "dimension" "distance" "do" "duration"
  479. "echelon" "eigval" "eigvec" "expmatrix" "expandgrid"
  480. "fft" "fftc" "forward" "froot" "full"
  481. "gasetup" "geomean" "ginv"
  482. "hadamard" "half" "hankel" "harmean" "hdir" "hermite" "homogen"
  483. "i" "ifft" "ifftc" "importtablefromr" "insert" "inv" "invupdt" "isempty" "isskipped"
  484. "j" "jroot"
  485. "kurtosis"
  486. "lambertw" "listgetallnames" "listgetitem" "listgetname" "listgetsubitem" "listindex"
  487. "listlen" "loc" "logabsdet"
  488. "mad" "magic" "mahalanobis" "moduleic" "modulein"
  489. "name" "ncol" "nrow" "ndx2sub" "nleng" "norm" "num"
  490. "opscal" "orpol"
  491. "parentname" "palette" "polyroot" "prod" "product" "pv"
  492. "quartile"
  493. "rancomb" "randdirichlet" "randfun" "randmultinomial" "randmvt" "randnormal" "randwishart"
  494. "ranperk" "ranperm" "ranktie" "rates" "ratio" "remove" "repeat" "root" "row"
  495. "rowcat" "rowcatc" "rowvec" "rsubstr"
  496. "sample" "setdif" "shape" "shapecol" "skewness" "solve" "sparse" "splinev" "spot"
  497. "sqrsym" "sqrvech" "ssq" "standard" "storage" "sub2ndx" "sweep" "symsqr"
  498. "t" "tablecreate" "tablecreatefromdataset" "tablegetvardata" "tablegetvarformat"
  499. "tablegetvarindex" "tablegetvarinformat" "tablegetvarlabel" "tablegetvarname"
  500. "tablegetvartype" "tableisexistingvar" "tableisvarnumeric" "tfhilbert" "tfpwv"
  501. "tfstft" "tfwindow" "toeplitz" "trace" "trisolv" "type"
  502. "union" "unique" "uniqueby"
  503. "value" "vecdiag" "vech"
  504. "xmult" "xsect"
  505. "yield"
  506. ;;; ;; SAS functions introduced in Technical Report P-222
  507. "airy"
  508. "band" "blshift" "brshift" "bnot" "bor" "bxor"
  509. "cnonct" "compbl"
  510. "dairy" "dequote"
  511. "fnonct"
  512. "ibessel" "indexw" "inputc" "inputn"
  513. "jbessel"
  514. "lowcase"
  515. "putc" "putn"
  516. "quote"
  517. "resolve"
  518. "soundex" "sysprod"
  519. "tnonct" "tranwrd" "trimn"
  520. ;;; ;; SCL functions that are known to work with SAS macro function %sysfunc
  521. "attrc" "attrn"
  522. "cexist" "close"
  523. "dclose" "dnum" "dopen" "dread"
  524. "exist"
  525. "fclose" "fetchobs" "fileexist" "finfo" "fopen" "fput" "fwrite"
  526. "getoption" "getvarc" "getvarn"
  527. "libname" "libref"
  528. "open" "optgetn" "optsetn"
  529. "pathname"
  530. "sysmsg"
  531. "varfmt" "varlabel" "varnum" "vartype"
  532. ) 'words) ;"\\>"
  533. "("); "[ \t]*(")
  534. font-lock-function-name-face)
  535. )
  536. (list
  537. ;; .log NOTE: messages
  538. (cons "^NOTE: .*$" font-lock-constant-face)
  539. ;; .log ERROR: messages
  540. (cons "^ERROR: .*$" font-lock-keyword-face)
  541. ;; .log WARNING: messages
  542. (cons "^WARNING: .*$" font-lock-function-name-face)
  543. ;; SAS comments
  544. ;; /* */ handled by grammar above
  545. ;; (list "/\\*.*\\*/" 0 font-lock-comment-face t)
  546. (cons "\\(^[0-9]*\\|;\\)[ \t]*\\(%?\\*\\|comment\\).*\\(;\\|$\\)" font-lock-comment-face)
  547. ;; SAS execution blocks, DATA/RUN, PROC/RUN, SAS Macro Statements
  548. (cons "\\<%do[ \t]*\\(%until\\|%while\\)?\\>"
  549. font-lock-constant-face)
  550. ;;(cons (concat "\\(^[0-9]*\\|;\\)[ \t]*"
  551. ;;"%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)"
  552. ;;"\\>") font-lock-constant-face)
  553. (cons "\\<%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)\\>"
  554. font-lock-constant-face)
  555. (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
  556. "\\(data\\|endsas\\|finish\\|quit\\|run\\|start\\)[ \t\n;]")
  557. font-lock-constant-face)
  558. (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
  559. ;;"proc[ \t]+[a-z][a-z_0-9]+") font-lock-constant-face)
  560. "proc[ \t]+"
  561. ;;SAS/Base, SAS/Graph, SAS/FSP and common add-ons
  562. "\\(append"
  563. "\\|b\\(genmod\\|lifereg\\|phreg\\)"
  564. "\\|c\\(a\\(lendar\\|talog\\)\\|port\\|o\\(mpare\\|ntents\\|py\\|rr\\)\\)"
  565. "\\|d\\(atasets\\|bcstab\\|isplay\\)\\|ex\\(plode\\|port\\)"
  566. "\\|f\\(orm\\(at\\|s\\)\\|req\\|s\\(browse\\|edit\\|l\\(etter\\|ist\\)\\|view\\)\\)"
  567. "\\|g?\\(chart\\|p\\(lot\\|rint\\)\\)"
  568. "\\|g\\(anno\\|contour\\|device\\|font\\|\\(key\\)?map\\|options\\|project"
  569. "\\|re\\(duce\\|move\\|play\\)\\|slide\\|testit\\|3\\(d\\|grid\\)\\)"
  570. "\\|\\(map\\|[cg]\\)?import\\|i\\(ml\\|nsight\\)"
  571. "\\|means\\|options\\|p\\(menu\\|rintto\\)"
  572. "\\|r\\(ank\\|e\\(gistry\\|port\\)\\)"
  573. "\\|s\\(ort\\|ql\\|tandard\\|ummary\\)"
  574. "\\|t\\(abulate\\|emplate\\|imeplot\\|ran\\(spose\\|tab\\)\\)\\|univariate"
  575. ;;SAS/Stat and SAS/ETS
  576. "\\|a\\(ceclus\\|nova\\|rima\\|utoreg\\)\\|boxplot"
  577. "\\|c\\(a\\(lis\\|n\\(corr\\|disc\\)\\|tmod\\)\\|itibase\\|luster\\|o\\(mputab\\|rresp\\)\\)"
  578. "\\|discrim\\|expand\\|f\\(a\\(ctor\\|stclus\\)\\|orecast\\|req\\)"
  579. "\\|g\\(enmod\\|l\\(immix\\|m\\(mod\\|power\\|select\\)?\\)\\)\\|inbreed\\|k\\(de\\|rige2d\\)"
  580. "\\|l\\(attice\\|ife\\(reg\\|test\\)\\|o\\(ess\\|gistic\\)\\)"
  581. "\\|m\\(ds\\|ixed\\|o\\(de\\(clus\\|l\\)\\|rtgage\\)\\|ulttest\\)"
  582. "\\|n\\(ested\\|l\\(in\\|mixed\\)\\|par1way\\)\\|orthoreg"
  583. "\\|p\\(dlreg\\|hreg\\|l\\(an\\|s\\)\\|ower\\|r\\(in\\(comp\\|qual\\)\\|obit\\)\\)\\|r\\(sr\\)?eg"
  584. "\\|s\\(core\\|im\\(2d\\|lin\\)\\|pectra\\|t\\(atespace\\|dize\\|epdisc\\)\\|urvey\\(means\\|reg\\|select\\)\\|yslin\\)"
  585. "\\|t\\(phreg\\|pspline\\|r\\(ansreg\\|ee\\)\\|test\\)"
  586. "\\|var\\(clus\\|comp\\|iogram\\)\\|x11"
  587. "\\)") font-lock-constant-face)
  588. ;;(cons (concat "\\(^[0-9]*\\|;\\|%then\\|%else\\)[ \t]*"
  589. ;;"\\(%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\)"
  590. ;;"\\>") font-lock-constant-face)
  591. (cons "\\<%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\>"
  592. font-lock-constant-face)
  593. (cons "\\<%\\(by\\|else\\|t\\(o\\|hen\\)\\)\\>"
  594. font-lock-constant-face)
  595. ;; SAS dataset options/PROC statements followed by an equal sign/left parentheses
  596. (cons (concat
  597. "[ \t(,]"
  598. "\\(attrib\\|by\\|compress\\|d\\(ata\\|rop\\)\\|f\\(irstobs\\|ormat\\)"
  599. "\\|i\\(d\\|f\\|n\\)\\|ke\\(ep\\|y\\)\\|l\\(abel\\|ength\\)"
  600. "\\|o\\(bs\\|rder\\|ut\\)\\|rename\\|s\\(ortedby\\|plit\\)"
  601. "\\|var\\|where\\)"
  602. "[ \t]*=")
  603. font-lock-keyword-face)
  604. (cons "\\<\\(in\\(:\\|dex[ \t]*=\\)?\\|until\\|wh\\(en\\|ile\\)\\)[ \t]*("
  605. font-lock-keyword-face)
  606. ;; SAS statements
  607. (cons (concat
  608. "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
  609. "\\(a\\(bort\\|rray\\|ttrib\\)\\|b\\(ayes\\|y\\)"
  610. "\\|c\\(hange\\|lass\\|ontrast\\)"
  611. "\\|d\\(elete\\|isplay\\|m\\|o\\([ \t]+\\(data\\|over\\)\\)?\\|rop\\)"
  612. "\\|e\\(rror\\|stimate\\|xc\\(hange\\|lude\\)\\)"
  613. "\\|f\\(ile\\(name\\)?\\|o\\(otnote\\(10?\\|[2-9]\\)?\\|rmat\\)\\|req\\)"
  614. "\\|go\\([ \t]*to\\|ptions\\)"
  615. "\\|hazardratio\\|[hv]bar\\(3d\\)?"
  616. "\\|i\\(d\\|f\\|n\\(dex\\|f\\(ile\\|ormat\\)\\|put\\|value\\)\\)"
  617. "\\|keep\\|l\\(abel\\|ength\\|i\\(bname\\|nk\\|st\\)\\|smeans\\)"
  618. "\\|m\\(anova\\|e\\(ans\\|rge\\)\\|issing\\|od\\(el\\|ify\\)\\)\\|note"
  619. "\\|o\\(ds\\|ptions\\|therwise\\|utput\\)\\|p\\(arms\\|lot2?\\|ut\\)"
  620. "\\|r\\(andom\\|e\\(name\\|peated\\|tain\\)\\)"
  621. "\\|s\\(ave\\|e\\(lect\\|t\\)\\|kip\\|trata\\|um\\(by\\)?\\)"
  622. "\\|t\\(ables?\\|i\\(me\\|tle\\(10?\\|[2-9]\\)?\\)\\)\\|update"
  623. "\\|va\\(lue\\|r\\)\\|w\\(eight\\|here\\|i\\(ndow\\|th\\)\\)"
  624. ;; IML statements that are not also SAS statements
  625. "\\|append\\|c\\(lose\\(file\\)?\\|reate\\)\\|edit\\|f\\(ind\\|orce\\|ree\\)"
  626. "\\|insert\\|load\\|mattrib\\|p\\(a[ru]se\\|rint\\|urge\\)"
  627. "\\|re\\(move\\|peat\\|place\\|set\\|sume\\)"
  628. "\\|s\\(et\\(in\\|out\\)\\|how\\|ort\\|tore\\|ummary\\)\\|use\\)?"
  629. "\\>") font-lock-keyword-face)
  630. ;; (cons "\\<\\(\\(then\\|else\\)[ \t]*\\)?\\(do\\([ \t]*over\\)?\\|else\\)\\>"
  631. ;; font-lock-keyword-face)
  632. ;; SAS statements that must be followed by a semi-colon
  633. (cons (concat
  634. "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
  635. "\\(cards4?\\|datalines\\|end\\|l\\(ostcard\\)\\|page\\|stop\\)?"
  636. "[ \t]*;") font-lock-keyword-face)
  637. ;; SAS/GRAPH statements not handled above
  638. (cons (concat
  639. "\\(^[0-9]*\\|):\\|[;,]\\)[ \t]*"
  640. "\\(axis\\|legend\\|pattern\\|symbol\\)"
  641. "\\([1-9][0-9]?\\)?\\>") font-lock-keyword-face)
  642. ;; SAS Datastep functions and SAS macro functions
  643. ;(cons "%[a-z_][a-z_0-9]*[ \t]*[(;]"
  644. ;; SAS macro functions occasionally defined with no arguments
  645. ;; which means they can be followed by any character that can
  646. ;; separate tokens, however, they are most likely to be followed
  647. ;; by operat-ions/ors
  648. (cons "%[a-z_][a-z_0-9]*[- \t();,+*/=<>]"
  649. font-lock-function-name-face)
  650. (cons "\\<call[ \t]+[a-z_][a-z_0-9]*[ \t]*("
  651. font-lock-function-name-face)
  652. (cons (concat
  653. "\\<"
  654. "\\(a\\(bs\\|r\\(cos\\|sin\\)\\|tan\\)\\|b\\(etainv\\|yte\\)"
  655. "\\|c\\(eil\\|inv\\|o\\(llate\\|mpress\\|sh?\\)\\|ss\\|v\\)"
  656. "\\|dacc\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
  657. "\\|dep\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
  658. "\\|d\\(a\\(te\\(\\|jul\\|part\\|time\\)\\|y\\)\\|hms\\|i\\(f[0-9]*\\|m\\|gamma\\)\\)"
  659. "\\|e\\(rfc?\\|xp\\)"
  660. "\\|f\\(i\\(nv\\|p\\(namel?\\|state\\)\\)\\|loor\\|uzz\\)\\|gam\\(inv\\|ma\\)"
  661. "\\|h\\(bound\\|ms\\|our\\)\\|i\\(n\\(dexc?\\|put\\|t\\(\\|ck\\|nx\\|rr\\)\\)\\|rr\\)"
  662. "\\|juldate\\|kurtosis\\|l\\(ag[0-9]*\\|bound\\|e\\(ft\\|ngth\\)\\|gamma\\|og\\(\\|10\\|2\\)\\)"
  663. "\\|m\\(ax\\|dy\\|ean\\|in\\(\\|ute\\)\\|o\\(d\\|nth\\|rt\\)\\)"
  664. "\\|n\\(\\|etpv\\|miss\\|o\\(rmal\\|t\\)\\|pv\\)"
  665. "\\|prob\\([ft]\\|b\\(eta\\|nml\\)\\|chi\\|gam\\|hypr\\|it\\|n\\(egb\\|orm\\)\\)"
  666. "\\|ordinal\\|p\\(oisson\\|ut\\)\\|qtr\\|r\\(e\\(peat\\|verse\\)\\|ight\\|ound\\)"
  667. "\\|ran\\(bin\\|cau\\|exp\\|g\\(am\\|e\\)\\|k\\|nor\\|poi\\|t\\(bl\\|ri\\)\\|uni\\)"
  668. "\\|s\\(aving\\|can\\|econd\\|i\\(gn\\|nh?\\)\\|qrt\\|t\\(d\\(\\|err\\)\\|fips\\|namel?\\)\\|u\\(bstr\\|m\\)\\|ymget\\)"
  669. "\\|t\\(anh?\\|i\\(me\\(\\|part\\)\\|nv\\)\\|oday\\|r\\(anslate\\|i\\(gamma\\|m\\)\\|unc\\)\\)"
  670. "\\|u\\(niform\\|pcase\\|ss\\)\\|v\\(ar\\|erify\\)"
  671. "\\|weekday\\|y\\(ear\\|yq\\)\\|zip\\(fips\\|namel?\\|state\\)"
  672. ;;; ;; SAS functions introduced in Technical Report P-222
  673. "\\|airy\\|b\\(and\\|lshift\\|not\\|or\\|rshift\\|xor\\)"
  674. "\\|c\\(nonct\\|ompbl\\)\\|d\\(airy\\|equote\\)\\|fnonct\\|tnonct"
  675. "\\|i\\(bessel\\|n\\(dexw\\|put[cn]\\)\\)\\|jbessel\\|put[cn]"
  676. "\\|lowcase\\|quote\\|resolve\\|s\\(oundex\\|ysprod\\)\\|tr\\(anwrd\\|imn\\)"
  677. ;;; ;; IML functions that are not also Datastep functions
  678. "\\|a\\(ll\\|ny\\|pply\\|rmasim\\)\\|b\\(lock\\|ranks\\|tran\\)"
  679. "\\|c\\(har\\|hoose\\|on\\(cat\\|tents\\|vexit\\|vmod\\)\\|ovlag\\|shape\\|usum\\|vexhull\\)"
  680. "\\|d\\(atasets\\|esignf?\\|et\\|iag\\|o\\|uration\\)"
  681. "\\|e\\(chelon\\|igv\\(al\\|ec\\)\\)\\|f\\(ft\\|orward\\)\\|ginv"
  682. "\\|h\\(alf\\|ankel\\|dir\\|ermite\\|omogen\\)"
  683. "\\|i\\(\\|fft\\|nsert\\|nv\\(updt\\)?\\)\\|j\\(\\|root\\)\\|loc\\|mad"
  684. "\\|n\\(ame\\|col\\|leng\\|row\\|um\\)\\|o\\(pscal\\|rpol\\)"
  685. "\\|p\\(olyroot\\|roduct\\|v\\)\\|r\\(anktie\\|ates\\|atio\\|emove\\|eturn\\|oot\\|owcatc?\\)"
  686. "\\|s\\(etdif\\|hape\\|olve\\|plinev\\|pot\\|qrsym\\|ssq\\|torage\\|weep\\|ymsqr\\)"
  687. "\\|t\\(\\|eigv\\(al\\|ec\\)\\|oeplitz\\|race\\|risolv\\|ype\\)"
  688. "\\|uni\\(on\\|que\\)\\|v\\(alue\\|ecdiag\\)\\|x\\(mult\\|sect\\)\\|yield"
  689. ;;; ;; SCL functions that are known to work with SAS macro function %sysfunc
  690. "\\|attr[cn]\\|c\\(exist\\|lose\\)\\|d\\(close\\|num\\|open\\|read\\)"
  691. "\\|exist\\|f\\(close\\|etchobs\\|i\\(leexist\\|nfo\\)\\|open\\|put\\|write\\)"
  692. "\\|get\\(option\\|var[cn]\\)\\|lib\\(name\\|ref\\)\\|op\\(en\\|t\\(getn\\|setn\\)\\)"
  693. "\\|pathname\\|sysmsg\\|var\\(fmt\\|l\\(abel\\|en\\)\\|n\\(ame\\|um\\)\\|type\\)\\)"
  694. "[ \t]*(") font-lock-function-name-face)
  695. ))
  696. "Font Lock regexs for SAS.")
  697. (defun beginning-of-sas-statement (arg &optional comment-start)
  698. "Move point to beginning of current sas statement."
  699. (interactive "P")
  700. (let ((pos (point))
  701. )
  702. (if (search-forward ";" nil 1) (forward-char -1))
  703. (re-search-backward ";[ \n*/]*$" (point-min) 1 arg)
  704. (skip-chars-forward sas-comment-chars)
  705. (if comment-start nil
  706. (if (looking-at "\\*/")
  707. (progn (forward-char 2)
  708. (skip-chars-forward sas-comment-chars)))
  709. (while (looking-at "/\\*")
  710. (if (not (search-forward "*/" pos t 1)) ;;(;; (point-max) 1 1)
  711. (forward-char 2))
  712. (skip-chars-forward sas-white-chars)))))
  713. (defun sas-indent-line ()
  714. "Indent function for SAS mode."
  715. (interactive)
  716. (let (indent prev-end
  717. (pos (- (point-max) (point)))
  718. (case-fold-search t)
  719. (cur-ind (current-indentation))
  720. (comment-col (sas-comment-start-col))) ;; 2/1/95 TDC
  721. (save-excursion
  722. (cond ((progn
  723. (back-to-indentation)
  724. (or (bobp)
  725. (looking-at
  726. "data[ ;]\\|proc[ ;]\\|run[ ;]\\|quit[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\|%mend[ ;]")))
  727. ;; Case where current statement is DATA, PROC, etc...
  728. (setq prev-end (point))
  729. (goto-char (point-min))
  730. ;; Added 6/27/94
  731. ;; May get fooled if %MACRO, %DO, etc embedded in comments
  732. (setq indent
  733. (+ (* (- (sas-how-many "^[ \t]*%macro\\|[ \t]+%do"
  734. prev-end)
  735. (sas-how-many "^[ \t]*%mend\\|%end" prev-end))
  736. sas-indent-width) comment-col))) ;; 2/1/95 TDC
  737. ;; Case where current line begins with sas-indent-ignore-comment
  738. ;; added 6/27/94 to leave "* ;" comments alone.
  739. ((progn
  740. (back-to-indentation)
  741. (and (not (looking-at "\\*/"))
  742. (looking-at (concat sas-indent-ignore-comment "\\|/\\*"))))
  743. (setq indent (current-indentation)))
  744. ;; Case where current statement not DATA, PROC etc...
  745. (t (beginning-of-line 1)
  746. (skip-chars-backward sas-white-chars)
  747. (if (bobp) nil
  748. (backward-char 1))
  749. (cond
  750. ((looking-at ";") ; modified 1/31/95
  751. (setq indent (sas-next-statement-indentation)))
  752. ((save-excursion;; added 4/28/94 to properly check
  753. (if (bobp) () (backward-char 1));; for end of comment
  754. (setq prev-end (point))
  755. (looking-at "\\*/"));; improved 1/31/95
  756. (save-excursion
  757. (search-backward "*/"
  758. (point-min) 1 1); comment start is first /*
  759. (search-forward "/*"
  760. prev-end 1 1) ; after previous */
  761. (backward-char 2) ; 2/1/95 TDC
  762. (skip-chars-backward sas-white-chars)
  763. (setq indent
  764. (if (bobp) 0
  765. (if (looking-at ";")
  766. (sas-next-statement-indentation)
  767. ;;(+ (current-indentation) sas-indent-width)
  768. (current-indentation))))))
  769. ;; added 6/27/94 to leave "* ;" comments alone
  770. ((save-excursion
  771. (progn
  772. (beginning-of-sas-statement 1 t)
  773. (and (not (looking-at "\\*/"))
  774. (looking-at sas-indent-ignore-comment))))
  775. (setq indent cur-ind))
  776. ((progn
  777. (beginning-of-sas-statement 1)
  778. (bobp));; added 4/13/94
  779. (setq indent sas-indent-width));; so the first line works
  780. ((save-excursion
  781. (beginning-of-sas-statement 2)
  782. (looking-at "cards4?;\\|datalines4?;\\|lines4?;"))
  783. (setq indent (current-indentation))) ; So cards keep indentation.
  784. (t
  785. (if (progn
  786. (save-excursion
  787. (beginning-of-line 1)
  788. (skip-chars-backward sas-white-chars)
  789. (if (bobp) nil (backward-char 1))
  790. (or (looking-at ";")
  791. (bobp) (backward-char 1) (looking-at "\\*/"))))
  792. (setq indent (+ (current-indentation) sas-indent-width))
  793. (setq indent (current-indentation))))))))
  794. (save-excursion
  795. (let (beg end)
  796. (back-to-indentation)
  797. (setq end (point))
  798. (beginning-of-line 1)
  799. (setq beg (point))
  800. (delete-region beg end)
  801. (indent-to indent)))
  802. (if (> (- (point-max) pos) (point))
  803. (goto-char (- (point-max) pos)))))
  804. ;;(defun sas-indent-region (start end)
  805. ;; "Indent a region of SAS code."
  806. ;; (interactive "r")
  807. ;; (save-excursion
  808. ;; (let ((endmark (copy-marker end)))
  809. ;; (goto-char start)
  810. ;; (and (bolp) (not (eolp))
  811. ;; (sas-indent-line))
  812. ;; (indent-sexp endmark)
  813. ;; (set-marker endmark nil))))
  814. (defun indent-sas-statement (arg)
  815. "Indent all continuation lines sas-indent-width spaces from first
  816. line of statement."
  817. (interactive "p")
  818. (let (end)
  819. (save-excursion
  820. (if (> arg 0)
  821. (while (and (> arg 0) (search-forward ";" (point-max) 1 1))
  822. (setq end (point))
  823. (if (bobp) nil (backward-char 1))
  824. (beginning-of-sas-statement 1)
  825. (forward-char 1)
  826. (indent-region (point)
  827. end
  828. (+ (current-column) (1- sas-indent-width)))
  829. (search-forward ";" (point-max) 1 1)
  830. (setq arg (1- arg)))))))
  831. ;; added 9/31/94
  832. (defun sas-next-statement-indentation ()
  833. "Returns the correct indentation of the next sas statement.
  834. The current version assumes that point is at the end of the statement.
  835. This will (hopefully) be fixed in later versions."
  836. (if (bobp) 0
  837. (save-excursion
  838. (let ((prev-end (point)))
  839. (beginning-of-sas-statement 1)
  840. (while (and (not (bobp))
  841. (not (looking-at "\\*/"))
  842. (looking-at sas-indent-ignore-comment))
  843. (skip-chars-backward sas-white-chars)
  844. (if (bobp) nil
  845. (backward-char 1))
  846. (setq prev-end (point))
  847. (beginning-of-sas-statement 1 t))
  848. (if (or
  849. (looking-at
  850. (concat "data[ \n\t;]\\|"
  851. (regexp-opt '("cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"))
  852. "\\|proc[ \n\t]\\|%?do[ \n\t;]\\|%macro[ \n\t]\\|/\\*"))
  853. (save-excursion
  854. (re-search-forward
  855. "\\b%?then\\>[ \n\t]*\\b%?do\\>\\|\\b%?else\\>[ \n\t]*\\b%?do\\>"
  856. prev-end 1 1))) ; fixed 1/30/95 to avoid being fooled by
  857. ; variable names starting with "do"
  858. (+ (current-indentation) sas-indent-width)
  859. (if (looking-at "%?end[ ;\n]\\|%mend[ ;\n]\\|\\*/")
  860. (max (- (current-indentation) sas-indent-width) 0)
  861. (current-indentation)))))))
  862. ;; added 2/1/95
  863. (defun sas-comment-start-col ()
  864. "If the current line is inside a /* */ comment, returns column in which the
  865. opening /* appears. returns 0 otherwise."
  866. (let ((pos (point)))
  867. (save-excursion
  868. (if (and (search-backward "*/" (point-min) 1 1)
  869. (search-forward "/*" pos 1 1))
  870. (current-indentation)
  871. 0))))
  872. ;; Created 6/27/94 to verify that RUN; statements match PROC and DATA
  873. ;; statements. Useful since indentation my be goofy w/o "RUN;"
  874. (defun sas-check-run-statements ()
  875. "Check to see that \"run\" statements are matched with proc, data statements."
  876. (interactive)
  877. (let (pos
  878. (ok t)
  879. (eob-ok t))
  880. (save-excursion
  881. (beginning-of-line)
  882. (while ok
  883. (if (re-search-forward
  884. "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
  885. nil 1)
  886. (if (match-beginning 2)
  887. (if (re-search-forward
  888. "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
  889. nil t)
  890. (progn (setq pos (point))
  891. (setq ok (match-beginning 1)))
  892. (setq eob-ok nil pos (point-max))))
  893. (setq ok nil)))
  894. (setq ok (eobp)))
  895. (if (and ok eob-ok) (message "Run statements match")
  896. (goto-char pos)
  897. (beep)
  898. (message "Missing Run Statement."))))
  899. (defun sas-fix-life-tables ()
  900. "Remove censored and duplicate observations from life tables generated by
  901. Proc Lifetest. Operates on current region. A major space saver if there is
  902. heavy censoring."
  903. (interactive)
  904. (if buffer-read-only (setq buffer-read-only nil))
  905. (goto-char (point-min))
  906. (while (re-search-forward "^.*[ ]+[.][ ]+[.][ ]+[.][ ]+.*$" nil t)
  907. (replace-match "" nil nil)))
  908. ; (save-excursion
  909. ; (shell-command-on-region
  910. ; start end
  911. ; "sed '/[ ][.][ ]/d'" t)))
  912. ;;"sed \"\\? *\\. *\\. *\\. ?d\"" t)))
  913. ;;(vip-goto-line 1)
  914. ;;(setq ex-g-flag nil
  915. ;;ex-g-variant nil)
  916. ;;(vip-ex "1,$g/ \\. \\. \\. /d")))
  917. (defun sas-fix-page-numbers (offset &optional page-num)
  918. "Fix number of current page in sas output files after editing. Add
  919. OFFSET to actual page number."
  920. (interactive "P")
  921. (if (not offset) (setq offset 0))
  922. (if (not page-num) (setq page-num (sas-page-number)))
  923. (save-excursion
  924. (if (/= (preceding-char) ?\C-l) (backward-page 1))
  925. (let (end len mstart mend)
  926. (save-excursion
  927. (forward-line sas-page-number-max-line)
  928. (setq end (point)))
  929. (if (re-search-forward
  930. "\\(^[0-9]+[ ]\\)\\|\\([ ][0-9]+$\\)"
  931. end t)
  932. (progn (setq len (- (match-end 0) (match-beginning 0))
  933. mstart (match-beginning 0)
  934. mend (match-end 0))
  935. (delete-region mstart mend)
  936. (if (eolp)
  937. (insert (format
  938. (concat "%" len "d") (+ page-num offset)))
  939. (insert (substring
  940. (concat (+ (sas-page-number) offset) " ")
  941. 0 len))))))))
  942. (defun sas-page-fix (start)
  943. "Fix page numbers in sas output from point to end of file.
  944. If START is given this will be the number for the current page."
  945. (interactive "P")
  946. (let (offset (pnum (sas-page-number)))
  947. (if (not start) (setq offset 0)
  948. (setq offset (- start pnum)))
  949. (while (not (eobp))
  950. (sas-fix-page-numbers offset pnum)
  951. (setq pnum (1+ pnum))
  952. (forward-page 1))))
  953. (defun fix-page-breaks ()
  954. "Fix page breaks in SAS 6 print files."
  955. (interactive)
  956. (save-excursion
  957. (goto-char (point-min))
  958. (if (looking-at "\f") (delete-char 1))
  959. ;(replace-regexp "^\\(.+\\)\f" "\\1\n\f\n")
  960. (while (re-search-forward "^\\(.+\\)\f" nil t)
  961. (replace-match "\\1\n\f\n" nil nil))
  962. (goto-char (point-min))
  963. ;(replace-regexp "^\f\\(.+\\)" "\f\n\\1")
  964. (while (re-search-forward "^\f\\(.+\\)" nil t)
  965. (replace-match "\f\n\\1" nil nil))
  966. ; (goto-char (point-min))
  967. ;(replace-regexp " $" "")
  968. ;(while (re-search-forward "$" nil t)
  969. ; (replace-match "" nil nil))
  970. (goto-char (point-min))
  971. ;(replace-regexp " \\([^\\$]+\\)" "\n\\1")
  972. (while (re-search-forward " \\([^\\$]+\\)" nil t)
  973. (replace-match "\n\\1" nil nil))
  974. (goto-char (point-max))
  975. (if (not (bobp))
  976. (progn (backward-char 1)
  977. (if (not (looking-at "\n"))
  978. (progn (forward-char 1) (open-line 1)))))))
  979. (defun sas-page-number ()
  980. ;; like what-page except it returns an integer page number
  981. "Return page number of point in current buffer."
  982. (let ((opoint (point))) (save-excursion
  983. (goto-char (point-min))
  984. (1+ (sas-how-many page-delimiter opoint)))))
  985. (defun sas-how-many (regexp &optional end)
  986. ;; a copy of `how-many' which returns an integer
  987. ;; rather than a message
  988. "Return number of matches for REGEXP following point."
  989. (let ((count 0) opoint)
  990. (save-excursion
  991. (while (and (not (eobp))
  992. (progn (setq opoint (point))
  993. (re-search-forward regexp end t)))
  994. (if (= opoint (point))
  995. (forward-char 1)
  996. (setq count (1+ count))))
  997. count)))
  998. (defun beginning-of-sas-proc ()
  999. "Move point to beginning of sas proc, macro or data step."
  1000. (interactive)
  1001. (let ((case-fold-search t))
  1002. (forward-char -1)
  1003. (while (not (or (looking-at "data\\|proc\\|%macro")
  1004. (bobp)))
  1005. (re-search-backward "proc\\|data\\|%macro" (point-min) 1)
  1006. (beginning-of-sas-statement 1))))
  1007. (defun next-sas-proc (arg)
  1008. "Move point to beginning of next sas proc."
  1009. (interactive "P")
  1010. (let ((case-fold-search t))
  1011. (forward-char 1)
  1012. (if (re-search-forward
  1013. "^[ \t]*\\(data[ ;]\\|proc[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\)"
  1014. nil t arg)
  1015. (beginning-of-sas-statement 1)
  1016. (forward-char -1))))
  1017. (defun set-sas-file-name ()
  1018. "Stores the name of the current sas file."
  1019. (let ((name (buffer-file-name)))
  1020. (cond ((not name))
  1021. ((string-match (substring name -4 nil)
  1022. "\\.sas\\|\\.lst\\|\\.log")
  1023. (setq sas-file-name (substring name 0 (- (length name) 4)))
  1024. (setq sas-buffer-name (buffer-name))
  1025. (setq sas-file-root (substring sas-buffer-name 0
  1026. (- (length sas-buffer-name) 4))))
  1027. (t (message "This file does not have a standard suffix")))))
  1028. ;; created 6/27/94
  1029. (defun sas-set-alternate-file-name (name)
  1030. "Stores the NAME of an alternate sas file.
  1031. When this file is submitted with `submit-sas', the alternate file will
  1032. be submitted instead. `sas-submitable' is automatically sets to t."
  1033. (interactive "f")
  1034. (cond ((string-match (substring name -4 nil)
  1035. "\\.sas\\|\\.lst\\|\\.log")
  1036. (setq sas-file-name (substring name 0 (- (length name) 4)))
  1037. (setq sas-submitable t))
  1038. (t (message "This file does not have a standard suffix"))))
  1039. (defun switch-to-sas-source ()
  1040. "Switches to sas source file associated with the current file."
  1041. (interactive)
  1042. (switch-to-sas-file "sas"))
  1043. (defun switch-to-sas-lst ()
  1044. "Switches to sas source file associated with the current file."
  1045. (interactive)
  1046. (switch-to-sas-file "lst"))
  1047. (defun switch-to-sas-log ()
  1048. "Switches to sas source file associated with the current file."
  1049. (interactive)
  1050. (switch-to-sas-file "log"))
  1051. (defun switch-to-sas-source-other-window ()
  1052. "Switches to sas source file associated with the current file."
  1053. (interactive)
  1054. (switch-to-sas-file-other-window "sas"))
  1055. (defun switch-to-sas-lst-other-window ()
  1056. "Switches to sas source file associated with the current file."
  1057. (interactive)
  1058. (switch-to-sas-file-other-window "lst"))
  1059. (defun switch-to-sas-log-other-window ()
  1060. "Switches to sas source file associated with the current file."
  1061. (interactive)
  1062. (switch-to-sas-file-other-window "log"))
  1063. ;;(defun switch-to-sas-file (suff &optional revert silent)
  1064. ;; "Switches to sas \"SUFF\" file associated with the current file"
  1065. ;; (let* ((sfile sas-file-name)
  1066. ;; (buf (get-file-buffer (concat sfile "." suff)))
  1067. ;; (sas-require-confirmation
  1068. ;; (and sas-require-confirmation (not revert))))
  1069. ;; (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
  1070. ;; (find-file (concat sfile "." suff))
  1071. ;; (progn (switch-to-buffer buf)
  1072. ;; (if (not (verify-visited-file-modtime (current-buffer)))
  1073. ;; (progn (revert-buffer t t)
  1074. ;; (if (not silent)
  1075. ;; (message "File has changed on disk. Buffer automatically updated."))))))
  1076. ;; (setq sas-file-name sfile))
  1077. ;; (if (string-equal suff "sas")
  1078. ;; (if (not (string-equal major-mode "sas-mode"))
  1079. ;; (sas-mode))
  1080. ;; (if (not (string-equal major-mode "sasl-mode"))
  1081. ;; (sasl-mode))))
  1082. ;;
  1083. ;;(defun switch-to-sas-file-other-window (suff)
  1084. ;; "Switches to sas \"SUFF\" file associated with the current file"
  1085. ;; (let* ((sfile sas-file-name)
  1086. ;; (buf (get-file-buffer (concat sfile "." suff))))
  1087. ;; (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
  1088. ;; (find-file-other-window (concat sfile "." suff))
  1089. ;; (progn (switch-to-buffer-other-window buf)
  1090. ;; (if (not (verify-visited-file-modtime (current-buffer)))
  1091. ;; (progn (revert-buffer t t)
  1092. ;; (message "File has changed on disk. Buffer automatically updated.")))))
  1093. ;; (setq sas-file-name sfile))
  1094. ;; (if (string-equal suff "sas")
  1095. ;; (if (not (string-equal major-mode "sas-mode"))
  1096. ;; ;;(sas-mode)
  1097. ;; )
  1098. ;; (if (not (string-equal major-mode "sasl-mode"))
  1099. ;; ;;(sasl-mode)
  1100. ;; )))
  1101. (defun switch-to-sas-file (suff)
  1102. "Switches to sas \"SUFF\" file associated with the current file."
  1103. (switch-to-buffer (set-sas-file-buffer suff)))
  1104. (defun switch-to-sas-file-other-window (suff)
  1105. "Switches to sas \"SUFF\" file associated with the current file."
  1106. (switch-to-buffer-other-window (set-sas-file-buffer suff)))
  1107. ;; The following was created 6/7/94 to handle buffers without messing up
  1108. ;; windows.
  1109. (defun set-sas-file-buffer (suff &optional revert silent)
  1110. "Sets current buffer to sas \"SUFF\" file associated with the current file."
  1111. (let* ((sfile sas-file-name)
  1112. (buf (get-file-buffer (concat sfile "." suff)))
  1113. (sas-require-confirmation
  1114. (and sas-require-confirmation (not revert))))
  1115. (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
  1116. (set-buffer (find-file-noselect (concat sfile "." suff)))
  1117. (progn (set-buffer buf)
  1118. (if (not (verify-visited-file-modtime (current-buffer)))
  1119. (progn (revert-buffer t t)
  1120. (if (not silent)
  1121. (message "File has changed on disk. Buffer automatically updated."))))))
  1122. (setq sas-file-name sfile))
  1123. ;;(if (string-equal suff "sas")
  1124. ;; (if (not (string-equal major-mode "sas-mode")) (sas-mode))
  1125. ;; (if (not (string-equal major-mode "sasl-mode"))(sasl-mode))
  1126. (current-buffer))
  1127. (defun switch-to-sas-process-buffer ()
  1128. "Switch to sas-process-buffer."
  1129. (interactive)
  1130. (let (buf proc-name)
  1131. (setq proc-name (concat "SAS" sas-file-name)
  1132. buf (concat "*" proc-name "*"))
  1133. (switch-to-buffer-other-window buf)))
  1134. (defun submit-sas ()
  1135. ;; 6/17/94 added sas-submitable local variable.
  1136. "Submit SAS file as shell command."
  1137. (interactive)
  1138. (if ;; can file be run, or is it only for inclusion?
  1139. (or sas-submitable
  1140. (progn
  1141. (beep)
  1142. (y-or-n-p
  1143. (format
  1144. "Submission is disabled for this file. Submit it anyway? "))))
  1145. (progn
  1146. ;; if buffer name has changed, tell user
  1147. (if (or
  1148. (string-equal sas-buffer-name (buffer-name))
  1149. (not
  1150. (y-or-n-p
  1151. (format
  1152. "The name of this buffer has changed. Submit the new file? "))))
  1153. (setq sas-buffer-name (buffer-name))
  1154. (set-sas-file-name))
  1155. (let ((sas-file sas-file-name)
  1156. (sas-root sas-file-root)
  1157. ;;(sas-buf sas-buffer-name)
  1158. proc-name
  1159. buf)
  1160. ;; Save buffer to SAS the right file :-).
  1161. (if (buffer-modified-p)
  1162. (if (y-or-n-p (format "Buffer %s is modified. Save it? "
  1163. (buffer-name)))
  1164. (save-buffer)))
  1165. (setq proc-name (concat "SAS" sas-file)
  1166. buf (concat "*" proc-name "*"))
  1167. (if (get-buffer buf)
  1168. (save-window-excursion (switch-to-buffer buf)
  1169. (erase-buffer)
  1170. (setq default-directory
  1171. (file-name-directory sas-file))))
  1172. (run-hooks 'sas-pre-run-hook) ;; added 8/24/94
  1173. (message "---- Submitting SAS job ----")
  1174. ;; (switch-to-buffer buf)
  1175. (make-comint proc-name
  1176. sas-program ;added sas-program 4/29/94
  1177. nil
  1178. sas-root)
  1179. (save-window-excursion
  1180. (switch-to-buffer buf)
  1181. (setq sas-file-name sas-file)
  1182. (bury-buffer buf))
  1183. (message "---- SAS job submitted ---- ")
  1184. (if sas-notify;; added 4/7/94
  1185. (set-process-sentinel (get-process proc-name) 'sas-sentinel)
  1186. (display-buffer buf t))))
  1187. (message "---- File not submitted ----")))
  1188. ;; 5/2/94 Modified sas-sentinel to check for errors in log file upon
  1189. ;; completion.
  1190. (defun sas-sentinel (proc arg);; created 4/7/94
  1191. "Notify user that SAS run is done."
  1192. (beep)
  1193. ;;(if (string-equal arg "finished\n")
  1194. (save-excursion
  1195. (let (msg buf win (sbuf (concat "*" (process-name proc) "*")))
  1196. (setq msg
  1197. (format "SAS %s %s"
  1198. (substring arg 0 -1)
  1199. (if sas-error-notify
  1200. ;;(save-window-excursion
  1201. (progn
  1202. (set-buffer sbuf)
  1203. (setq buf (set-sas-file-buffer "log" t t))
  1204. (goto-char (point-min))
  1205. (setq win (get-buffer-window buf))
  1206. (save-window-excursion
  1207. (if win
  1208. (progn
  1209. (select-window win)
  1210. (if (re-search-forward "^ERROR" nil t)
  1211. " (See .log file for errors)"
  1212. ""))
  1213. (switch-to-buffer buf)
  1214. (if (re-search-forward "^ERROR" nil t)
  1215. " (See .log file for errors)"
  1216. ""))))
  1217. "")))
  1218. (set-buffer sbuf)
  1219. (goto-char (point-max))
  1220. (insert msg)
  1221. (bury-buffer (get-buffer sbuf))
  1222. ;;(if (and sas-notify-popup window-system)
  1223. ;; (x-popup-dialog t
  1224. ;; (list "SAS Menu" (cons msg nil) )))
  1225. ;;(if (not (minibuffer-window-active-p)) (princ msg))
  1226. (princ msg))))
  1227. ;; 5/2/94 Modified run-sas-on-region to separate log and output buffers.
  1228. ;;
  1229. ;;(defun run-sas-on-region (start end append &optional buffer)
  1230. ;; "Submit region to SAS"
  1231. ;; (interactive "r\nP")
  1232. ;; (message "---- Running SAS ----")
  1233. ;; (let ((sfile sas-file-name)
  1234. ;; (shell-file-name "/bin/sh")
  1235. ;; serror buff)
  1236. ;; (setq buffer (or buffer "*SAS output*"))
  1237. ;; (save-excursion
  1238. ;; (shell-command-on-region
  1239. ;; start end;; added sas-program
  1240. ;; (concat sas-program " -nonews -stdio 2> /tmp/_temp_.log" nil))
  1241. ;; (get-buffer-create "*SAS Log*")
  1242. ;; (save-window-excursion
  1243. ;; (switch-to-buffer "*SAS Log*")
  1244. ;; (erase-buffer)
  1245. ;; (insert-file-contents "/tmp/_temp_.log")
  1246. ;; (delete-file "/tmp/_temp_.log")
  1247. ;; (setq serror (re-search-forward "^ERROR" nil t))
  1248. ;; (if serror () (bury-buffer)))
  1249. ;; (setq buff (get-buffer-create buffer))
  1250. ;; (save-window-excursion
  1251. ;; (switch-to-buffer buff)
  1252. ;; (setq sas-file-name sfile)
  1253. ;; (if append
  1254. ;; (progn
  1255. ;; (end-of-buffer)
  1256. ;; (insert "\f\n"))
  1257. ;; (erase-buffer))
  1258. ;; (if (get-buffer "*Shell Command Output*")
  1259. ;; (progn (insert-buffer "*Shell Command Output*")
  1260. ;; (kill-buffer "*Shell Command Output*"))
  1261. ;; (insert "SAS completed with no output."))
  1262. ;; (if append () (sasl-mode))
  1263. ;; (message "---- SAS Complete ----")))
  1264. ;; (if (not serror)
  1265. ;; (switch-to-buffer-other-window buff)
  1266. ;; (switch-to-buffer-other-window "*SAS Log*")
  1267. ;; (goto-char serror)
  1268. ;; (beep)
  1269. ;; (message "Error found in log file.")
  1270. ;; )))
  1271. (defun switch-to-dataset-log-buffer ()
  1272. "Switch to log buffer for run-sas-on-region."
  1273. (interactive)
  1274. (switch-to-buffer-other-window "*SAS Log*"))
  1275. (defun switch-to-dataset-source-buffer ()
  1276. "Switch to source buffer for run-sas-on-region."
  1277. (interactive)
  1278. (switch-to-buffer-other-window (format " *sas-tmp-%s*" sas-dataset)))
  1279. ;;(defun sas-get-dataset (filename &optional arg opts-p append buffer vars)
  1280. ;; "Run proc contents and proc print on SAS dataset. Automatically prompts
  1281. ;;for SAS options to use. Default options are defined by the variable
  1282. ;;`sas-get-options'. Output may be updated from within output buffer with
  1283. ;;C-cr if dataset changes. Also, the source code which generates the output
  1284. ;;may be edited with C-cs. Typing C-cr within the output buffer reexecutes
  1285. ;;the (modified) source code."
  1286. ;; (interactive "fName of SAS dataset (file name):")
  1287. ;; (let ((file (file-name-nondirectory filename))
  1288. ;; (dir (file-name-directory filename))
  1289. ;; (opts sas-get-options)
  1290. ;; (minibuffer-history sas-get-options-history)
  1291. ;; buf); fsize)
  1292. ;; (setq buffer (or buffer (concat "*" file "*")))
  1293. ;; (setq opts (if opts-p opts (read-string "SAS options: " opts)))
  1294. ;; (setq sas-get-options-history minibuffer-history)
  1295. ;; (cond ((string-match (substring file -6 nil) "\\.ssd01")
  1296. ;; (setq file (substring file 0 (- (length file) 6))))
  1297. ;; (t (error "This file is not a SAS dataset.")))
  1298. ;; (setq buf (format " *sas-tmp-%s*" file))
  1299. ;; (get-buffer-create buf)
  1300. ;; (save-window-excursion
  1301. ;; (switch-to-buffer buf)
  1302. ;; (erase-buffer)
  1303. ;; (setq default-directory dir)
  1304. ;; (if opts
  1305. ;; (insert (format "options %s ;\n" opts)))
  1306. ;; (insert (format "title \"Contents of SAS dataset `%s'\" ;\n" file))
  1307. ;; (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
  1308. ;; (if (not (equal arg 1))
  1309. ;; (insert (format "proc contents data = %s.%s ;\n" sas-tmp-libname file)))
  1310. ;; (if (equal arg 2) ()
  1311. ;; (insert (format "proc print data = %s.%s ;\n" sas-tmp-libname file))
  1312. ;; (if vars (insert (format " var %s ;\n" vars))))
  1313. ;; (run-sas-on-region (point-min) (point-max) append
  1314. ;; buffer)
  1315. ;; (get-buffer buffer)
  1316. ;; (if append () (sasd-mode)) ;; added 5/5/94
  1317. ;; (setq sas-dataset file))
  1318. ;; (if (get-buffer-window buffer t)
  1319. ;; (raise-frame (window-frame (get-buffer-window buffer t)))
  1320. ;; (display-buffer buffer (not append)))
  1321. ;; ))
  1322. ;;(defun revert-sas-dataset ()
  1323. ;; "Revert current sas dataset from disk version"
  1324. ;; (interactive)
  1325. ;; (let* ((file sas-dataset)
  1326. ;; (buf (format " *sas-tmp-%s*" file))
  1327. ;; (pos (point)))
  1328. ;; (save-window-excursion
  1329. ;; (switch-to-buffer buf)
  1330. ;; (run-sas-on-region (point-min) (point-max) nil
  1331. ;; (concat "*" file ".ssd01*"))
  1332. ;; )
  1333. ;; (goto-char pos) ;; added 6/9/94
  1334. ;; (sasd-mode) ;; added 5/5/94
  1335. ;; (setq sas-dataset file)))
  1336. (defun sas-insert-local-variables () ;; created 6/17/94
  1337. "Add local variables code to end of sas source file."
  1338. (interactive)
  1339. (save-excursion
  1340. (if (re-search-forward "\\* *Local Variables: *;" nil t)
  1341. ()
  1342. (goto-char (point-max))
  1343. (insert "
  1344. ** Local Variables: ;
  1345. ** End: ;
  1346. page ;
  1347. "))))
  1348. ;;-*-emacs-lisp-*-
  1349. ;;; file name: sas-data.el
  1350. ;;;
  1351. ;;; Version 1.0
  1352. ;;;
  1353. ;;; sas-data-mode: manage sas datasets
  1354. ;;; Copyright (C) 1994 Tom Cook
  1355. ;;;
  1356. ;;; This program is free software; you can redistribute it and/or modify
  1357. ;;; it under the terms of the GNU General Public License as published by
  1358. ;;; the Free Software Foundation; either version 2 of the License, or
  1359. ;;; (at your option) any later version.
  1360. ;;;
  1361. ;;; This program is distributed in the hope that it will be useful,
  1362. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  1363. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1364. ;;; GNU General Public License for more details.
  1365. ;;;
  1366. ;;; A copy of the GNU General Public License is available at
  1367. ;;; https://www.r-project.org/Licenses/
  1368. ;;;
  1369. ;;; Author: Tom Cook
  1370. ;;; Dept. of Biostatistics
  1371. ;;; University of Wisconsin - Madison
  1372. ;;; Madison, WI 53706
  1373. ;;; cook@biostat.wisc.edu
  1374. ;; Created: 8/11/94
  1375. ;; variables section
  1376. (defvar sas-dir-mode-map nil)
  1377. (defvar-local sas-directory-name nil
  1378. "Name of directory associated with this buffer.")
  1379. (defvar-local sas-dir-buf-end nil)
  1380. (defvar-local sas-sorted-by-num nil)
  1381. ;; user variables
  1382. ;; keymaps etc...
  1383. (if sas-dir-mode-map ()
  1384. (setq sas-dir-mode-map (make-sparse-keymap))
  1385. ;;(define-key sas-dir-mode-map "c" 'sas-contents)
  1386. (define-key sas-dir-mode-map "p" 'sas-print)
  1387. (define-key sas-dir-mode-map "m" 'sas-mark-item)
  1388. (define-key sas-dir-mode-map "u" 'sas-unmark-item)
  1389. (define-key sas-dir-mode-map " " 'sas-next-line)
  1390. (define-key sas-dir-mode-map "\C-n" 'sas-next-line)
  1391. (define-key sas-dir-mode-map "\C-p" 'sas-prev-line)
  1392. (define-key sas-dir-mode-map "\177" 'sas-prev-line-undo)
  1393. (define-key sas-dir-mode-map "\C-b" 'sas-backward-page-narrow)
  1394. (define-key sas-dir-mode-map "\C-v" 'sas-forward-page-narrow)
  1395. (define-key sas-dir-mode-map "\C-m" 'sas-goto-dataset)
  1396. (define-key sas-dir-mode-map [mouse-2] 'sas-mouse-goto-dataset)
  1397. (define-key sas-dir-mode-map "t" 'sas-dir-goto-page)
  1398. (define-key sas-dir-mode-map "q" 'bury-buffer)
  1399. (define-key sas-dir-mode-map "g" 'sas-revert-library)
  1400. (define-key sas-dir-mode-map "1" 'digit-argument)
  1401. (define-key sas-dir-mode-map "2" 'digit-argument)
  1402. (define-key sas-dir-mode-map "3" 'digit-argument)
  1403. (define-key sas-dir-mode-map "4" 'digit-argument)
  1404. (define-key sas-dir-mode-map "5" 'digit-argument)
  1405. (define-key sas-dir-mode-map "6" 'digit-argument)
  1406. (define-key sas-dir-mode-map "7" 'digit-argument)
  1407. (define-key sas-dir-mode-map "8" 'digit-argument)
  1408. (define-key sas-dir-mode-map "9" 'digit-argument)
  1409. (define-key sas-dir-mode-map [menu-bar sas run]
  1410. '("Submit File " . submit-sas))
  1411. )
  1412. (define-derived-mode sas-dir-mode special-mode "SAS"
  1413. "Major mode for managing sas files."
  1414. :group 'ess-sas
  1415. (setq sas-directory-name (expand-file-name default-directory)))
  1416. ;;(defun sas-make-library (directory &optional update)
  1417. ;; "Create a buffer with the names of all sas datasets from DIRECTORY."
  1418. ;; (interactive "DDirectory Name: ")
  1419. ;; (let ((dir (expand-file-name directory)) buf out cont pos)
  1420. ;; (setq buf (format " *sas-tmp-%s*" dir))
  1421. ;; (setq out (concat "*SAS-dir-" dir))
  1422. ;; (setq cont (concat "*SAS-cont-" dir))
  1423. ;; (get-buffer-create buf)
  1424. ;; (if (get-buffer out)
  1425. ;; (if update
  1426. ;; (progn
  1427. ;; (set-buffer out)
  1428. ;; (setq buffer-read-only nil)))
  1429. ;; (setq update t))
  1430. ;; (pop-to-buffer out)
  1431. ;; (setq default-directory dir)
  1432. ;; (setq pos (point))
  1433. ;; (if update
  1434. ;; (progn
  1435. ;; (save-window-excursion
  1436. ;; (set-buffer buf)
  1437. ;; (erase-buffer)
  1438. ;; (setq default-directory dir)
  1439. ;; (insert "options linesize=70 pagesize=1000 ;\n")
  1440. ;; (insert (format "title \"Contents of SAS directory `%s'\" ;\n"
  1441. ;; dir))
  1442. ;; (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
  1443. ;; (insert (format "proc contents data = %s._all_ directory details memtype=data ;\n" sas-tmp-libname))
  1444. ;; (run-sas-on-region (point-min) (point-max) nil
  1445. ;; out)
  1446. ;; (set-buffer out)
  1447. ;; (goto-char (point-min))
  1448. ;; (if (= (sas-how-many page-delimiter (point-max)) 0)
  1449. ;; (let ((buffer-read-only nil))
  1450. ;; (erase-buffer)
  1451. ;; (insert "There are no SAS datasets in this directory")
  1452. ;; (pop-to-buffer out))
  1453. ;; (save-excursion
  1454. ;; (set-buffer (get-buffer-create cont))
  1455. ;; (setq buffer-read-only t)
  1456. ;; (let ((buffer-read-only nil))
  1457. ;; (erase-buffer)
  1458. ;; (insert-buffer out)
  1459. ;; (delete-region (point-min)
  1460. ;; (or (re-search-forward page-delimiter nil t)
  1461. ;; (point-min)))
  1462. ;; (sas-page-fix 1)
  1463. ;; (goto-char (point-min))
  1464. ;; (sas-dir-mode)
  1465. ;; (sas-narrow-to-page)))
  1466. ;; (if (re-search-forward page-delimiter nil t)
  1467. ;; (delete-region (progn (beginning-of-line) (point))
  1468. ;; (point-max)))
  1469. ;; (sas-insert-set-properties (point-min) (point-max))
  1470. ;; )
  1471. ;; (switch-to-buffer out t)
  1472. ;; (goto-char (point-min))
  1473. ;; (sas-dir-mode)
  1474. ;; (setq sas-dir-buf-end (point-max)))
  1475. ;; (goto-char pos)
  1476. ;; (sas-move-to-filename (point-max))))))
  1477. (defun sas-move-to-filename (&optional eol)
  1478. (or eol (setq eol (progn (end-of-line) (point))))
  1479. (beginning-of-line)
  1480. (if (re-search-forward "\\(^ *[0-9]+ *<*\\)[^:0-9\n]" eol t)
  1481. (goto-char (match-end 1))))
  1482. (defun sas-next-line (arg)
  1483. "Move down one line."
  1484. (interactive "p")
  1485. (forward-line arg)
  1486. (sas-move-to-filename (point-max)))
  1487. ;;(and (< (point) sas-dir-buf-end)
  1488. ;;(forward-line arg)
  1489. ;;(sas-move-to-filename sas-dir-buf-end)))
  1490. (defun sas-prev-line (arg)
  1491. "Move up one line."
  1492. (interactive "p")
  1493. (beginning-of-line)
  1494. (re-search-backward "^ *[0-9]+ *<*[^:0-9\n]" (point-min) t)
  1495. (sas-move-to-filename sas-dir-buf-end))
  1496. (defun sas-insert-set-properties (beg end)
  1497. (save-excursion
  1498. (goto-char beg)
  1499. (while (< (point) end)
  1500. (if (sas-move-to-filename)
  1501. (put-text-property (point)
  1502. (+ 8 (point))
  1503. 'mouse-face 'highlight))
  1504. (forward-line 1))))
  1505. (defun sas-get-filename ()
  1506. "Return name of dataset on current line."
  1507. (interactive)
  1508. (save-excursion
  1509. (if (string-equal "*SAS-dir" (substring (buffer-name) 0 8))
  1510. (sas-move-to-filename)
  1511. (goto-char (point-min))
  1512. (re-search-forward "Data Set Name: [^.]*\\."))
  1513. (expand-file-name
  1514. (downcase (concat sas-directory-name
  1515. (buffer-substring
  1516. (point)
  1517. (save-excursion
  1518. (skip-chars-forward "A-Z0-9_")
  1519. (point))) ".ssd01")))))
  1520. (defun sas-get-file-number ()
  1521. "Return name of dataset on current line."
  1522. (interactive)
  1523. (if (sas-move-to-filename)
  1524. (progn (forward-word -1)
  1525. (re-search-forward "[0-9]*")
  1526. (string-to-number
  1527. (buffer-substring (match-beginning 0)
  1528. (match-end 0))))))
  1529. ;;(defun sas-contents ()
  1530. ;; "Run proc contents on current file."
  1531. ;; (interactive)
  1532. ;; (let ((buffer-read-only nil) (sas-get-options "linesize=70"))
  1533. ;; (sas-get-dataset (sas-get-filename) 2 t t (buffer-name))
  1534. ;; (end-of-buffer)
  1535. ;; (backward-page-top-of-window 1)))
  1536. ;;
  1537. ;;(defun sas-print ()
  1538. ;; "Run proc contents on current file."
  1539. ;; (interactive)
  1540. ;; (sas-get-dataset (sas-get-filename) 1 nil nil nil
  1541. ;; (sas-create-var-string)))
  1542. (defun sas-goto-page (arg)
  1543. "Goto top of page ARG. If no ARG, then goto top of file."
  1544. (interactive "P")
  1545. (goto-char 1)
  1546. (if arg
  1547. (if (> arg 1)
  1548. (progn
  1549. (re-search-forward page-delimiter (point-max) 1 (1- arg)))))
  1550. (skip-chars-forward sas-white-chars); was " \f\n" till 5.1.13
  1551. (recenter 1))
  1552. (defun forward-page-top-of-window (arg)
  1553. "Move forward to page boundary and leave first line at top of window.
  1554. With arg, repeat, or go back if negative. A page boundary is any line
  1555. whose beginning matches the regexp `page-delimiter'."
  1556. (interactive "p")
  1557. (forward-page arg)
  1558. (recenter 0))
  1559. (defun backward-page-top-of-window (arg)
  1560. "Move backward to page boundary and leave first line at top of window.
  1561. With arg, repeat, or go back if negative. A page boundary is any line
  1562. whose beginning matches the regexp `page-delimiter'."
  1563. (interactive "p")
  1564. (forward-page (- arg))
  1565. (recenter 0))
  1566. (defun sas-narrow-to-page ()
  1567. (save-excursion
  1568. (let* ((min (point-min))
  1569. (max (point-max)))
  1570. ;;(omin (point-min))
  1571. ;;(omax (point-max)))
  1572. (if (or (bolp) (beginning-of-line)
  1573. (looking-at page-delimiter))
  1574. (forward-char 1)
  1575. (forward-page -1))
  1576. (setq min (point))
  1577. (forward-page 1)
  1578. (beginning-of-line)
  1579. (setq max (point))
  1580. (narrow-to-region min max))))
  1581. (defun sas-forward-page-narrow (arg)
  1582. "Move forward to page boundary and narrow to page.
  1583. With arg, repeat, or go back if negative. A page boundary is any line
  1584. whose beginning matches the regexp `page-delimiter'."
  1585. (interactive "p")
  1586. (widen)
  1587. (forward-page arg)
  1588. (sas-narrow-to-page)
  1589. (goto-char (point-min)))
  1590. (defun sas-backward-page-narrow (arg)
  1591. "Move backward to page boundary and narrow to page.
  1592. With arg, repeat, or go back if negative. A page boundary is any line
  1593. whose beginning matches the regexp `page-delimiter'."
  1594. (interactive "p")
  1595. (goto-char (point-min))
  1596. (widen)
  1597. (forward-page (- arg))
  1598. (sas-narrow-to-page))
  1599. (defun sas-goto-dataset (&optional page)
  1600. (interactive)
  1601. (and sas-directory-name
  1602. (let ((page (or page (sas-get-file-number))))
  1603. ;;(dir sas-directory-name))
  1604. (if page
  1605. (progn
  1606. (switch-to-buffer-other-window
  1607. (concat "*SAS-cont-" sas-directory-name))
  1608. (widen)
  1609. (sas-goto-page page)
  1610. (sas-narrow-to-page)
  1611. (goto-char (point-min)))))))
  1612. ;;(defun sas-mouse-goto-dataset (event)
  1613. ;; (interactive "e")
  1614. ;; (let (page buf)
  1615. ;; (save-window-excursion
  1616. ;; (save-excursion
  1617. ;; (set-buffer (window-buffer (posn-window (event-end event))))
  1618. ;; (save-excursion
  1619. ;; (goto-char (posn-point (event-end event)))
  1620. ;; (setq page (sas-get-file-number)))
  1621. ;; (sas-goto-dataset page)
  1622. ;; (setq buf (buffer-name))))
  1623. ;; (set-buffer buf)
  1624. ;; (goto-char (point-min))
  1625. ;; (display-buffer buf)))
  1626. (defun sas-dir-goto-page (page)
  1627. (interactive "p")
  1628. (widen)
  1629. (sas-goto-page page)
  1630. (sas-narrow-to-page))
  1631. (defun sas-mark-item (&optional next)
  1632. (interactive)
  1633. (sas-move-to-filename)
  1634. (beginning-of-line)
  1635. (let ((buffer-read-only nil))
  1636. (if (re-search-forward "^\\( *[0-9]+ *\\) \\([A-Z][A-Z_0-9]*\\) "
  1637. (save-excursion (end-of-line) (point)) t)
  1638. (replace-match "\\1<\\2>")))
  1639. (or next (sas-next-line 1)))
  1640. (defun sas-unmark-item ()
  1641. (interactive)
  1642. (save-excursion
  1643. (beginning-of-line)
  1644. (let ((buffer-read-only nil))
  1645. (if (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
  1646. (save-excursion (end-of-line) (point)) t)
  1647. (replace-match "\\1 \\2 ")))))
  1648. (defun sas-prev-line-undo (arg)
  1649. (interactive "p")
  1650. (sas-prev-line arg)
  1651. (sas-unmark-item)
  1652. (sas-move-to-filename))
  1653. (defun sas-create-var-string ()
  1654. (and (string-equal "*SAS-cont" (substring (buffer-name) 0 9))
  1655. (let (str)
  1656. (goto-char (point-min))
  1657. (while
  1658. (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
  1659. nil t)
  1660. (setq str (concat str " " (buffer-substring (match-beginning 2)
  1661. (match-end 2)))))
  1662. str)))
  1663. (defun ess-imenu-SAS (&optional arg)
  1664. "SAS language Imenu support for ESS."
  1665. (interactive)
  1666. (setq imenu-generic-expression
  1667. '( (nil "[ \t\n=]\\([a-zA-Z_][a-zA-Z_0-9]*[.][a-zA-Z_][a-zA-Z_0-9]*\\)[ ,()\t\n;]" 1)))
  1668. (imenu-add-to-menubar "SAS Datasets"))
  1669. ;;(defun sas-revert-library ()
  1670. ;; "Update current library."
  1671. ;; (interactive)
  1672. ;; (if sas-directory-name
  1673. ;; (sas-make-library sas-directory-name t)))
  1674. (provide 'ess-sas-l)
  1675. ;;; ess-sas-l.el ends here