;;; ess-omg-l.el --- Support for editing Omega source code12;; Copyright (C) 1999--2001 A.J. Rossini.3;; Copyright (C) 2002--2004 A.J. Rossini, Richard M. Heiberger, Martin4;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.56;; Author: A.J. Rossini <[email protected]>7;; Created: 15 Aug 19998;; Maintainer: ESS-core <[email protected]>910;; This file is part of ESS (Emacs Speaks Statistics).1112;; This file is free software; you can redistribute it and/or modify13;; it under the terms of the GNU General Public License as published by14;; the Free Software Foundation; either version 2, or (at your option)15;; any later version.1617;; This file is distributed in the hope that it will be useful,18;; but WITHOUT ANY WARRANTY; without even the implied warranty of19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20;; GNU General Public License for more details.2122;; A copy of the GNU General Public License is available at23;; http://www.r-project.org/Licenses/2425;;; Commentary:2627;; Code for general editing Omega source code. This is initially28;; based upon the similarities between Omega and S, but will need to29;; diverge to incorporate the use of Java-style coding.3031;;; Code:3233; Requires and autoloads343536; Specialized functions3738(defun OMG-comment-indent ()39"Indentation for Omega comments."4041(if (looking-at "////")42(current-column)43(if (looking-at "///")44(let ((tem (ess-calculate-indent)))45(if (listp tem) (car tem) tem))46(skip-chars-backward " \t")47(max (if (bolp) 0 (1+ (current-column)))48comment-column))))4950;; (defun OMG-indent-line ()51;; "Indent current line as Omega code.52;; Return the amount the indentation changed by."53;; (let ((indent (ess-calculate-indent nil))54;; beg shift-amt55;; (case-fold-search nil)56;; (pos (- (point-max) (point))))57;; (beginning-of-line)58;; (setq beg (point))59;; (cond ((eq indent nil)60;; (setq indent (current-indentation)))61;; (t62;; (skip-chars-forward " \t")63;; (if (and ess-fancy-comments (looking-at "////"))64;; (setq indent 0))65;; (if (and ess-fancy-comments66;; (looking-at "//")67;; (not (looking-at "///")))68;; (setq indent comment-column)69;; (if (eq indent t) (setq indent 0))70;; (if (listp indent) (setq indent (car indent)))71;; (cond ((and (looking-at "else\\b")72;; (not (looking-at "else\\s_")))73;; (setq indent (save-excursion74;; (ess-backward-to-start-of-if)75;; (+ ess-else-offset76;; (current-indentation)))))77;; ((= (following-char) ?})78;; (setq indent79;; (+ indent80;; (- ess-close-brace-offset ess-indent-level))))81;; ((= (following-char) ?{)82;; (setq indent (+ indent ess-brace-offset)))))))83;; (skip-chars-forward " \t")84;; (setq shift-amt (- indent (current-column)))85;; (if (zerop shift-amt)86;; (if (> (- (point-max) pos) (point))87;; (goto-char (- (point-max) pos)))88;; (delete-region beg (point))89;; (indent-to indent)90;; ;; If initial point was within line's indentation,91;; ;; position after the indentation.92;; ;; Else stay at same point in text.93;; (if (> (- (point-max) pos) (point))94;; (goto-char (- (point-max) pos))))95;; shift-amt))969798;; (defun OMG-calculate-indent (&optional parse-start)99;; "Return appropriate indentation for current line as Omega code.100;; In usual case returns an integer: the column to indent to.101;; Returns nil if line starts inside a string, t if in a comment."102;; (save-excursion103;; (beginning-of-line)104;; (let ((indent-point (point))105;; (case-fold-search nil)106;; state107;; containing-sexp)108;; (if parse-start109;; (goto-char parse-start)110;; (beginning-of-defun))111;; (while (< (point) indent-point)112;; (setq parse-start (point))113;; (setq state (parse-partial-sexp (point) indent-point 0))114;; (setq containing-sexp (car (cdr state))))115;; (cond ((or (nth 3 state) (nth 4 state))116;; ;; return nil or t if should not change this line117;; (nth 4 state))118;; ((null containing-sexp)119;; ;; Line is at top level. May be data or function definition,120;; (beginning-of-line)121;; (if (and (/= (following-char) ?\{)122;; (save-excursion123;; (ess-backward-to-noncomment (point-min))124;; (ess-continued-statement-p)))125;; ess-continued-statement-offset126;; 0)) ; Unless it starts a function body127;; ((/= (char-after containing-sexp) ?{)128;; ;; line is expression, not statement:129;; ;; indent to just after the surrounding open.130;; (goto-char containing-sexp)131;; (let ((bol (save-excursion (beginning-of-line) (point))))132133;; ;; modified by shiba@isac 7.3.1992134;; (cond ((and (numberp ess-expression-offset)135;; (re-search-backward "[ \t]*expression[ \t]*" bol t))136;; ;; This regexp match every "expression".137;; ;; modified by shiba138;; ;;(forward-sexp -1)139;; (beginning-of-line)140;; (skip-chars-forward " \t")141;; ;; End142;; (+ (current-column) ess-expression-offset))143;; ((and (numberp ess-arg-function-offset)144;; (re-search-backward145;; "=[ \t]*\\s\"*\\(\\w\\|\\s_\\)+\\s\"*[ \t]*"146;; bol147;; t))148;; (forward-sexp -1)149;; (+ (current-column) ess-arg-function-offset))150;; ;; "expression" is searched before "=".151;; ;; End152153;; (t154;; (progn (goto-char (1+ containing-sexp))155;; (current-column))))))156;; (t157;; ;; Statement level. Is it a continuation or a new statement?158;; ;; Find previous non-comment character.159;; (goto-char indent-point)160;; (ess-backward-to-noncomment containing-sexp)161;; ;; Back up over label lines, since they don't162;; ;; affect whether our line is a continuation.163;; (while (eq (preceding-char) ?\,)164;; (ess-backward-to-start-of-continued-exp containing-sexp)165;; (beginning-of-line)166;; (ess-backward-to-noncomment containing-sexp))167;; ;; Now we get the answer.168;; (if (ess-continued-statement-p)169;; ;; This line is continuation of preceding line's statement;170;; ;; indent ess-continued-statement-offset more than the171;; ;; previous line of the statement.172;; (progn173;; (ess-backward-to-start-of-continued-exp containing-sexp)174;; (+ ess-continued-statement-offset (current-column)175;; (if (save-excursion (goto-char indent-point)176;; (skip-chars-forward " \t")177;; (eq (following-char) ?{))178;; ess-continued-brace-offset 0)))179;; ;; This line starts a new statement.180;; ;; Position following last unclosed open.181;; (goto-char containing-sexp)182;; ;; Is line first statement after an open-brace?183;; (or184;; ;; If no, find that first statement and indent like it.185;; (save-excursion186;; (forward-char 1)187;; (while (progn (skip-chars-forward " \t\n")188;; (looking-at "//"))189;; ;; Skip over comments following openbrace.190;; (forward-line 1))191;; ;; The first following code counts192;; ;; if it is before the line we want to indent.193;; (and (< (point) indent-point)194;; (current-column)))195;; ;; If no previous statement,196;; ;; indent it relative to line brace is on.197;; ;; For open brace in column zero, don't let statement198;; ;; start there too. If ess-indent-level is zero,199;; ;; use ess-brace-offset + ess-continued-statement-offset instead.200;; ;; For open-braces not the first thing in a line,201;; ;; add in ess-brace-imaginary-offset.202;; (+ (if (and (bolp) (zerop ess-indent-level))203;; (+ ess-brace-offset ess-continued-statement-offset)204;; ess-indent-level)205;; ;; Move back over whitespace before the openbrace.206;; ;; If openbrace is not first nonwhite thing on the line,207;; ;; add the ess-brace-imaginary-offset.208;; (progn (skip-chars-backward " \t")209;; (if (bolp) 0 ess-brace-imaginary-offset))210;; ;; If the openbrace is preceded by a parenthesized exp,211;; ;; move to the beginning of that;212;; ;; possibly a different line213;; (progn214;; (if (eq (preceding-char) ?\))215;; (forward-sexp -1))216;; ;; Get initial indentation of the line we are on.217;; (current-indentation))))))))))218219220221222(defvar OMG-syntax-table nil "Syntax table for Omegahat code.")223(if S-syntax-table224nil225(setq S-syntax-table (make-syntax-table))226(modify-syntax-entry ?\\ "\\" S-syntax-table)227(modify-syntax-entry ?+ "." S-syntax-table)228(modify-syntax-entry ?- "." S-syntax-table)229(modify-syntax-entry ?= "." S-syntax-table)230(modify-syntax-entry ?% "." S-syntax-table)231(modify-syntax-entry ?< "." S-syntax-table)232(modify-syntax-entry ?> "." S-syntax-table)233(modify-syntax-entry ?& "." S-syntax-table)234(modify-syntax-entry ?| "." S-syntax-table)235(modify-syntax-entry ?\' "\"" S-syntax-table)236;;FIXME: This fails (warning in compilation):237;;F "//" are 2 characters; ?// is invalid238;;F NEXT LINE IS BOGUS IN XEMACS, AJR239;;F (modify-syntax-entry ?// "<" S-syntax-table) ; open comment240;;F (modify-syntax-entry ?\n ">" S-syntax-table) ; close comment241;;(modify-syntax-entry ?. "w" S-syntax-table) ; "." used in S obj names242(modify-syntax-entry ?. "_" S-syntax-table) ; see above/below,243; plus consider separation.244(modify-syntax-entry ?$ "_" S-syntax-table) ; foo.bar$hack is 1 symbol245(modify-syntax-entry ?_ "." S-syntax-table)246(modify-syntax-entry ?* "." S-syntax-table)247(modify-syntax-entry ?< "." S-syntax-table)248(modify-syntax-entry ?> "." S-syntax-table)249(modify-syntax-entry ?/ "." S-syntax-table))250251252(defvar OMG-editing-alist253'((paragraph-start . (concat "^$\\|" page-delimiter))254(paragraph-separate . (concat "^$\\|" page-delimiter))255(paragraph-ignore-fill-prefix . t)256(require-final-newline . mode-require-final-newline)257(comment-start . "//")258(comment-start-skip . "//+ *")259(comment-column . 40)260;;(comment-indent-function . 'S-comment-indent)261;;(ess-comment-indent . 'S-comment-indent)262;;(ess-indent-line . 'S-indent-line)263;;(ess-calculate-indent . 'ess-calculate-indent)264(indent-line-function . 'ess-indent-line)265(parse-sexp-ignore-comments . t)266(ess-style . ess-default-style)267(ess-local-process-name . nil)268;;(ess-keep-dump-files . 'ask)269(ess-mode-syntax-table . S-syntax-table)270(font-lock-defaults . '(ess-OMG-font-lock-defaults271nil nil ((?\. . "w")))))272"General options for Omegahat source files.")273274(defvar ess-OMG-font-lock-defaults275(append (list276(cons "\\b[0-9]+\\b" 'font-lock-type-face) ; numbers277(cons (concat "\\<" (regexp-opt ess-S-keywords 'enc-paren) "\\>")278'font-lock-keyword-face))279(list280(cons (regexp-opt ess-S-assign-ops)281'font-lock-constant-face) ; assign282(cons (concat "\\<" (regexp-opt ess-S-constants 'enc-paren) "\\>")283'font-lock-type-face) ; constants284(cons (concat "\\<" (regexp-opt ess-S-modifyiers 'enc-paren) "\\>")285'font-lock-constant-face) ; modify search list or source286287(cons ess-S-function-name-regexp288'(1 font-lock-function-name-face keep))289; function name290(cons "\\s.\\|\\s(\\|\\s)" 'font-lock-function-name-face)291;punctuation and parents (same as function not to cause vidual disturbance)292)) ; keywords293"Font-lock patterns used in `OMG' buffers.")294295296;;; Changes from S to S-PLUS 3.x. (standard S3 should be in ess-s-l.el !).297298(defconst OMG-help-sec-keys-alist299'((?a . "ARGUMENTS:")300(?b . "BACKGROUND:")301(?B . "BUGS:")302(?d . "DESCRIPTION:")303(?D . "DETAILS:")304(?e . "EXAMPLES:")305(?n . "NOTE:")306(?O . "OPTIONAL ARGUMENTS:")307(?R . "REQUIRED ARGUMENTS:")308(?r . "REFERENCES:")309(?s . "SEE ALSO:")310(?S . "SIDE EFFECTS:")311(?u . "USAGE:")312(?v . "VALUE:"))313"Alist of (key . string) pairs for use in section searching.")314;;; `key' indicates the keystroke to use to search for the section heading315;;; `string' in an S help file. `string' is used as part of a316;;; regexp-search, and so specials should be quoted.317318(defconst ess-help-OMG-sec-regex "^[A-Z. ---]+:$"319"Reg(ular) Ex(pression) of section headers in help file")320321;;; S-mode extras of Martin Maechler, Statistik, ETH Zurich.322323;;>> Moved things into --> ./ess-utils.el324325(provide 'ess-omg-l)326327; Local variables section328329;;; This file is automatically placed in Outline minor mode.330;;; The file is structured as follows:331;;; Chapters: ^L ;332;;; Sections: ;;*;;333;;; Subsections: ;;;*;;;334;;; Components: defuns, defvars, defconsts335;;; Random code beginning with a ;;;;* comment336337;;; Local variables:338;;; mode: emacs-lisp339;;; outline-minor-mode: nil340;;; mode: outline-minor341;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"342;;; End:343344;;; ess-omg-l.el ends here345346347