(require 'compile)
(defvar gretl-mode-hook nil)
(add-to-list 'auto-mode-alist '("\\.inp$" . gretl-mode))
(defvar gretl-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?@ "w" table)
(modify-syntax-entry ?# "<" table)
(modify-syntax-entry ?\n ">" table)
(modify-syntax-entry ?\{ "(} " table)
(modify-syntax-entry ?\} "){ " table)
(modify-syntax-entry ?\[ "(] " table)
(modify-syntax-entry ?\] ")[ " table)
(modify-syntax-entry ?\( "() " table)
(modify-syntax-entry ?\) ")( " table)
(modify-syntax-entry ?\r " " table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?* "." table)
(modify-syntax-entry ?/ "." table)
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?< "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
(modify-syntax-entry ?! "." table)
(modify-syntax-entry ?\\ "\\" table)
(modify-syntax-entry ?\' "." table)
(modify-syntax-entry ?\` "w" table)
(modify-syntax-entry ?\" "\"" table)
(modify-syntax-entry ?. "w" table)
(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?\% "." table)
(modify-syntax-entry ?\# "<" table)
(modify-syntax-entry ?\n ">" table)
table)
"Syntax table for `gretl-mode'.")
(defvar gretl-mode-string-syntax-table
(let ((table (make-syntax-table)))
table)
"Syntax table for `gretl-mode' that holds within strings.")
(defcustom gretl-continuation-offset 4
"*Extra indentation applied to Gretl continuation lines."
:type 'integer
:group 'ess-gretl)
(defvar gretl-continuation-regexp
"[^#%\n]*\\(\\\\\\|\\.\\.\\.\\)\\s-*\\(\\s<.*\\)?$")
(defcustom gretl-continuation-string "\\"
"*Character string used for Gretl continuation lines. Normally \\."
:type 'string
:group 'ess-gretl)
(defconst gretl-function-header-regexp
(concat "^\\s-*\\<\\(function\\)\\>"
"\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\w+\\)\\>")
"Regexp to match a Gretl function header.
The string `function' and its name are given by the first and third
parenthetical grouping.")
(defvar gretl-command-words
'("add" "adf" "anova" "append" "ar" "ar1" "arbond" "arch"
"arima" "biprobit" "break" "boxplot" "chow" "clear" "coeffsum" "coint"
"coint2" "corr" "corrgm" "cusum" "data" "dataset" "delete" "diff"
"difftest" "discrete" "dpanel" "dummify" "duration" "elif" "else" "end"
"endif" "endloop" "eqnprint" "equation" "estimate" "fcast" "foreign" "fractint"
"freq" "function" "funcerr" "garch" "genr" "gmm" "gnuplot" "graphpg"
"hausman" "heckit" "help" "hsk" "hurst" "if" "include" "info"
"intreg" "kalman" "kpss" "labels" "lad" "lags" "ldiff" "leverage"
"levinlin" "logistic" "logit" "logs" "loop" "mahal" "makepkg" "meantest"
"mle" "modeltab" "modprint" "modtest" "mpols" "negbin" "nls" "normtest"
"nulldata" "ols" "omit" "open" "orthdev" "outfile" "panel" "pca"
"pergm" "textplot" "poisson" "print" "printf" "probit" "pvalue" "quantreg"
"qlrtest" "qqplot" "quit" "rename" "reset" "restrict" "rmplot" "run"
"runs" "scatters" "sdiff" "set" "setinfo" "setobs" "setmiss" "shell"
"smpl" "spearman" "sprintf" "square" "sscanf" "store" "summary" "system"
"tabprint" "tobit" "tsls" "var" "varlist" "vartest" "vecm" "vif"
"wls" "xcorrgm" "xtab" "debug" "return" "catch" "for" "foreach"
"funcerr" "return" "while" "elif" "const" "3sls" "liml" "fiml"
"sur" "params" "deriv" "orthog" "weights" "series" "scalar" "genr")
"Commands in Gretl (these names are also reserved).")
(defvar gretl-genr-functions
'("abs" "sin" "cos" "tan" "asin" "acos" "atan" "sinh"
"cosh" "tanh" "asinh" "acosh" "atanh" "log" "ln" "log10"
"log2" "exp" "sqrt" "diff" "ldiff" "sdiff" "lags" "int"
"round" "ceil" "floor" "sort" "dsort" "sortby" "ranking" "orthdev"
"nobs" "firstobs" "lastobs" "uniform" "normal" "cum" "missing" "ok"
"misszero" "lrvar" "quantile" "median" "gini" "zeromiss" "sum" "mean"
"min" "max" "sd" "var" "sst" "cnorm" "dnorm" "qnorm"
"gammafun" "lngamma" "digamma" "resample" "pnobs" "pmin" "pmax" "pmean"
"psd" "hpfilt" "bkfilt" "bwfilt" "fracdiff" "boxcox" "cov" "corr"
"movavg" "I" "zeros" "ones" "seq" "replace" "muniform" "mnormal"
"sumc" "sumr" "meanc" "meanr" "sdc" "minc" "maxc" "minr"
"maxr" "iminc" "imaxc" "iminr" "imaxr" "fft" "ffti" "cmult"
"cdiv" "mcov" "mcorr" "mxtab" "cdemean" "cholesky" "psdroot" "inv"
"invpd" "ginv" "diag" "transp" "vec" "vech" "unvech" "upper"
"lower" "rows" "cols" "det" "ldet" "tr" "onenorm" "infnorm"
"rcond" "rank" "qform" "mlag" "qrdecomp" "eigensym" "eigengen" "nullspace"
"princomp" "mexp" "fdjac" "BFGSmax" "obsnum" "isseries" "isscalar" "islist"
"isstring" "isnull" "nelem" "pdf" "cdf" "invcdf" "pvalue" "critical"
"randgen" "urcpval" "values" "mshape" "svd" "mols" "mpols" "mrls"
"mread" "mwrite" "selifc" "selifr" "polroots" "dummify" "wmean" "wvar"
"wsd" "xpx" "filter" "kfilter" "ksmooth" "ksimul" "trimr" "getenv"
"argname" "obslabel" "readfile" "grab" "strstr" "strncmp" "strlen" "sscanf"
"varname" "varnum" "tolower" "colnames" "rownames" "ljungbox" "msortby" "lincomb"
"imhof" "toepsolv" "diagcat" "xmin" "xmax" "corrgm" "mcovg" "fcstats"
"bessel" "fraclag" "mreverse" "deseas" "pergm" "irr" "npv" "logistic"
"weekday" "kdensity" "monthlen" "epochday" "setnote" "invmills" "polyfit" "chowlin"
"varsimul" "strsplit" "inlist" "errmsg" "isconst" "irf" "inbundle")
"Builtin functions for Gretl's genr command.")
(defvar gretl-option-flags
'("addstats" "all" "anova" "append"
"arch" "arma-init" "asymptotic" "autocorr" "auto"
"autocorr" "auxiliary" "balanced" "bartlett"
"between" "bootstrap" "both" "breusch-pagan"
"byobs" "by" "c" "close"
"coded" "cols" "column" "comfac"
"complete" "conditional" "contiguous" "continue"
"continuous" "control" "covariance" "cross"
"cross-section" "crt" "csv" "ct"
"ctt" "cubes-only" "dat" "database"
"dataset" "db" "degrees" "dhansen"
"difference" "diffuse" "discrete" "dpdstyle"
"drop-empty" "drop-first" "drop-last" "dummy"
"dynamic" "equal" "exit" "exponential"
"fcp" "fixed-effects" "from-file" "full"
"func" "gamma" "geomean" "gls"
"gmm" "gnu-R" "gnu-octave" "gph"
"gzipped" "hausman-reg" "hessian" "hilu"
"impulse-responses" "input" "inst" "integrate"
"intervals" "inverse-fit" "iterate" "jackknife"
"jbera" "jitter" "jmulti" "kendall"
"lags" "lagselect" "lbfgs" "lillie"
"liml" "linear-fit" "list" "loess-fit"
"log" "loglogistic" "lognormal" "logs"
"matrix" "matrix-diff" "medians" "ml"
"model1" "multi" "multinomial" "nc"
"next" "no-corc" "no-dates" "no-df-corr"
"no-gradient-check" "no-header" "no-missing" "no-scaling"
"no-stats" "normal" "normality" "notches"
"numerical" "odbc" "omit-obs" "one-scale"
"opg" "orthdev" "other" "out-of-sample"
"output" "overwrite" "p-values" "panel"
"panel-vars" "plot" "pooled" "preserve"
"print-final" "progress-bar" "progressive" "pwe"
"quadratic-fit" "quiet" "quit" "radians"
"random" "random-effects" "rank-sum" "raw"
"rc" "replace" "restrict" "restructure"
"reverse" "robust" "rolling" "row"
"rtf" "save" "save-all" "save-ehat"
"save-xbeta" "scalars" "seasonals" "send-data"
"sign" "signed-rank" "silent" "simple"
"simple-print" "single-yaxis" "skip-df" "spearman"
"special-time-series" "squares" "squares-only" "stacked-cross-section"
"stacked-time-series" "static" "stdresid" "suppress-fitted"
"swilk" "system" "t-ratios" "tall"
"test-down" "tex" "time-dummies" "time-series"
"to-file" "to_file" "traditional" "trend"
"two-step" "unequal-vars" "uniform" "unit-weights"
"variance-decomp" "vcv" "verbose" "wald"
"weibull" "weights" "white" "white-nocross"
"with-impulses" "with-lines" "write" "www"
"x-12-arima" "y-diff-only" "z-scores" "zeros")
"Gretl option flags.")
(defvar gretl-internal-vars
'("Fstat" "T" "ahat" "aic" "bic" "chisq" "coeff_ci"
"coeff" "compan" "datatype" "df" "dwpval" "ec" "ehat"
"error" "ess" "fcast" "fcerr" "gmmcrit" "hausman" "hqc"
"h" "jalpha" "jbeta" "jvbeta" "kalman_llt" "kalman_lnl" "kalman_s2"
"kalman_t" "kalman_uhat" "llt" "lnl" "mnlprobs" "ncoeff" "nobs"
"nscan" "nvars" "obs" "pd" "pvalue" "rho" "rlnl"
"rsq" "s00" "s01" "s11" "sample" "sargan" "sigma"
"stderr" "stopwatch" "sysA" "sysB" "sysGamma" "t1" "t2"
"test" "trsq" "uhat" "unit" "vcv" "version" "vma"
"windows" "xlist" "xtxinv" "yhat" )
"Model- and dataset-related variables.")
(defconst gretl-block-start-keywords
(list "loop" "foreign" "function" "gmm" "if" "system" "mle" "nls" "restrict"))
(defconst gretl-block-other-keywords
(list "else" "elif"))
(defconst gretl-block-end-keywords
(list "end" "endif" "endloop"))
(defvar gretl-keywords
(append gretl-block-start-keywords
gretl-block-other-keywords
gretl-block-end-keywords
'("break"))
"Reserved words in Gretl.")
(defun gretl-at-keyword (kw-list)
(and (or (= (point) 1)
(and (not (equal (char-before (point)) ?.))
(not (equal (char-before (point)) ?:))))
(not (ess-inside-string-or-comment-p (point)))
(not (ess-inside-brackets-p (point)))
(member (current-word) kw-list)))
(defconst gretl-font-lock-defaults
(list
(cons (concat "\\<\\("
(mapconcat 'identity gretl-keywords "\\|")
"\\)\\>")
'font-lock-keyword-face)
(cons (concat "[ \t]--\\("
(mapconcat 'identity gretl-option-flags "\\|")
"\\)")
'font-lock-constant-face)
(cons (concat "\\<\\("
(mapconcat 'identity gretl-command-words "\\|")
"\\)\\>")
'font-lock-builtin-face)
(cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
(if (boundp 'font-lock-builtin-face)
'font-lock-builtin-face
'font-lock-preprocessor-face))
(cons (concat "\\$\\("
(mapconcat 'identity gretl-internal-vars "\\|")
"\\)\\>")
'font-lock-variable-name-face)
(cons (concat "\\<\\("
(mapconcat 'identity gretl-genr-functions "\\|")
"\\)\\>")
'font-lock-variable-name-face)
(list gretl-function-header-regexp
'(1 font-lock-keyword-face)
'(3 font-lock-function-name-face nil t)))
"Additional Gretl expressions to highlight.")
(defvar gretl-block-begin-regexp
(concat "\\<\\("
(mapconcat 'identity gretl-block-start-keywords "\\|")
"\\)\\>"))
(defvar gretl-block-else-regexp
(concat "\\<\\("
(mapconcat 'identity gretl-block-other-keywords "\\|")
"\\)\\>"))
(defvar gretl-block-end-regexp
(concat "\\<\\("
(mapconcat 'identity gretl-block-end-keywords "\\|")
"\\)\\>"))
(defvar gretl-block-begin-or-end-regexp
(concat gretl-block-begin-regexp "\\|" gretl-block-end-regexp))
(defvar gretl-block-else-or-end-regexp
(concat gretl-block-else-regexp "\\|" gretl-block-end-regexp))
(defvar gretl-block-match-alist
'(("loop" . ("endloop"))
("if" . ("else" "elif" "endif"))
("nls" . ("end"))
("mle" . ("end"))
("gmm" . ("end"))
("foreign" . ("end"))
("restrict" . ("end"))
("kalman" . ("end"))
("system" . ("end")))
"Alist with Gretl's matching block keywords.
Has Gretl's begin keywords as keys and a list of the matching else or
end keywords as associated values.")
(defun gretl-last-open-block-pos (min)
(let ((count 0))
(while (not (or (> count 0) (<= (point) min)))
(backward-word 1)
(setq count
(cond ((gretl-at-keyword gretl-block-start-keywords)
(+ count 1))
((and (zerop (string-match "\\(?:e\\(?:l\\(?:if\\|se\\)\\|nd\\(?:if\\|loop\\)?\\)\\)" (current-word)))
(not (ess-inside-comment-p)) (not (ess-inside-brackets-p)))
(- count 1))
(t count))))
(if (> count 0)
(point)
nil)))
(defun gretl-last-open-block (min)
(let ((pos (gretl-last-open-block-pos min)))
(and pos
(progn
(goto-char pos)
(+ gretl-basic-offset (current-indentation))))))
(defun gretl-form-indent ()
(forward-line -1)
(end-of-line)
(backward-sexp)
(if (gretl-at-keyword gretl-block-other-keywords)
(+ gretl-basic-offset (current-indentation))
(if (char-equal (char-after (point)) ?\()
(progn
(backward-word 1)
(let ((cur (current-indentation)))
(if (gretl-at-keyword gretl-block-start-keywords)
(+ gretl-basic-offset cur)
nil)))
nil)))
(defun gretl-indent-line ()
"Indent current line of gretl code"
(interactive)
(end-of-line)
(indent-line-to
(or (and (ess-inside-string-p (point-at-bol)) 0)
(save-excursion (ignore-errors (gretl-form-indent)))
(save-excursion
(let ((endtok (progn
(beginning-of-line)
(forward-to-indentation 0)
(gretl-at-keyword gretl-block-end-keywords))))
(ignore-errors (+ (gretl-last-open-block (point-min))
(if endtok (- gretl-basic-offset) 0)))))
(save-excursion
(if (and (not (equal (point-min) (line-beginning-position)))
(progn
(forward-line -1)
(end-of-line) (backward-char 1)
(equal (char-after (point)) ?=)))
(+ gretl-basic-offset (current-indentation))
nil))
(save-excursion (forward-line -1)
(current-indentation))
0))
(when (gretl-at-keyword gretl-block-end-keywords)
(forward-word 1)))
(defvar gretl-editing-alist
'((paragraph-start . (concat "\\s-*$\\|" page-delimiter))
(paragraph-separate . (concat "\\s-*$\\|" page-delimiter))
(paragraph-ignore-fill-prefix . t)
(require-final-newline . mode-require-final-newline)
(comment-start . "# ")
(comment-add . 1)
(comment-start-skip . "\\s<+\\s-*")
(comment-column . 40)
(ess-calculate-indent . 'ess-calculate-indent)
(ess-indent-line-function . 'gretl-indent-line)
(parse-sexp-ignore-comments . t)
(ess-style . ess-default-style)
(ess-local-process-name . nil)
(ess-mode-syntax-table . gretl-syntax-table)
(font-lock-defaults . '(gretl-font-lock-defaults))
)
"General options for gretl source files.")
(autoload 'inferior-ess "ess-inf" "Run an ESS process.")
(autoload 'ess-mode "ess-mode" "Edit an ESS process.")
(defun gretl--get-words-from-command (command start-reg end-reg)
(with-current-buffer (ess-command command)
(goto-char (point-min))
(let ((beg (or (re-search-forward start-reg nil t)
(point-min)))
(end (progn (goto-char (point-max))
(or (re-search-backward end-reg)
(point-max))))
acum)
(goto-char beg)
(skip-chars-forward "\n")
(while (re-search-forward "[^ \t\n]+" end t)
(push (match-string-no-properties 0) acum))
acum)))
(defun gretl-get-help-topics-function (name)
(delete-dups
(append gretl-command-words gretl-genr-functions
gretl-block-end-keywords gretl-block-other-keywords
gretl-block-start-keywords
(gretl--get-words-from-command "help\n" "are:" "^For")
(gretl--get-words-from-command "help functions\n" "Accessors:" "^Functions")
(gretl--get-words-from-command "help functions\n" "^Functions" "^For")
)))
(defvar gretl-customize-alist
'((comint-use-prompt-regexp . t)
(inferior-ess-primary-prompt . "\\? ")
(inferior-ess-secondary-prompt . "\\ ")
(inferior-ess-prompt . "\\? ")
(ess-local-customize-alist . 'gretl-customize-alist)
(inferior-ess-program . "gretlcli")
(inferior-ess-font-lock-defaults . gretl-font-lock-defaults)
(ess-get-help-topics-function . 'gretl-get-help-topics-function)
(ess-load-command . "open \"%s\"\n")
(ess-send-string-function . 'gretl-send-string-function)
(inferior-ess-help-command . "help %s\n")
(ess-language . "gretl")
(ess-dialect . "gretl")
(ess-suffix . "inp")
(ess-dump-filename-template . (ess-replace-regexp-in-string
"S$" ess-suffix
ess-dump-filename-template-proto))
(ess-mode-syntax-table . gretl-syntax-table)
(ess-mode-editing-alist . gretl-editing-alist)
(ess-change-sp-regexp . nil )
(ess-help-sec-regex . ess-help-R-sec-regex)
(ess-help-sec-keys-alist . ess-help-R-sec-keys-alist)
(ess-loop-timeout . ess-S-loop-timeout)
(ess-cmd-delay . ess-R-cmd-delay)
(ess-function-pattern . ess-R-function-pattern)
(ess-object-name-db-file . "ess-r-namedb.el" )
(ess-smart-operators . ess-R-smart-operators)
(inferior-ess-help-filetype . nil)
(inferior-ess-exit-command . "exit\n")
(inferior-ess-start-file . nil)
(inferior-ess-start-args . "")
(inferior-ess-language-start . nil)
(ess-STERM . "iESS")
)
"Variables to customize for Gretl -- set up later than emacs initialization.")
(defcustom inferior-gretl-args ""
"String of arguments used when starting gretl.
These arguments are currently not passed to other versions of gretl that have
been created using the variable `ess-r-versions'."
:group 'ess-gretl
:type 'string)
(defvar gretl-basic-offset 4)
(defun gretl-mode (&optional proc-name)
"Major mode for editing gretl source. See `ess-mode' for more help."
(interactive "P")
(ess-mode gretl-customize-alist proc-name)
(if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
(set (make-local-variable 'end-of-defun-function) 'ess-end-of-function)
(run-hooks 'gretl-mode-hook))
(defvar ess-gretl-post-run-hook nil
"Functions run in process buffer after the initialization of
Gretl process.")
(defun gretl (&optional start-args)
"Call 'gretl',
Optional prefix (C-u) allows to set command line arguments, such as
--vsize. This should be OS agnostic.
If you have certain command line arguments that should always be passed
to gretl, put them in the variable `inferior-gretl-args'."
(interactive "P")
(setq ess-customize-alist gretl-customize-alist)
(ess-write-to-dribble-buffer
(format
"\n(Gretl): ess-dialect=%s, buf=%s"
ess-dialect (current-buffer)))
(let* ((r-start-args
(concat inferior-gretl-args " "
(if start-args
(read-string
(concat "Starting Args [other than `"
inferior-gretl-args
"'] ? "))
nil))))
(inferior-ess r-start-args)
(set (make-local-variable 'indent-line-function) 'gretl-indent-line)
(set (make-local-variable 'gretl-basic-offset) 4)
(setq indent-tabs-mode nil)
(goto-char (point-max))
(with-ess-process-buffer nil
(run-mode-hooks 'ess-gretl-post-run-hook))
))
(provide 'ess-gretl)
(provide 'ess-gretl)