~ubuntu-branches/ubuntu/edgy/ess/edgy

« back to all changes in this revision

Viewing changes to lisp/essl-s.el

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-11-11 00:51:43 UTC
  • mfrom: (1.1.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041111005143-wv1cih1h04xyrxrb
Tags: 5.2.3-3
* repair broken replace-regexp-in-string -> ess-replace-regexp-in-string
  patch
* expand autoload functionality in emacsen-startup

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
;;; essl-s.el --- Support for editing S source code
2
2
 
3
 
;; Copyright (C) 1989-2001 D. Bates, Kademan, Ritter, D.M. Smith, K. Hornik,
4
 
;; R.M. Heiberger, M. Maechler, and A.J. Rossini.
 
3
;; Copyright (C) 1989-1997 D. Bates, Kademan, Ritter, D.M. Smith, K. Hornik,
 
4
;;      R.M. Heiberger, M. Maechler, and A.J. Rossini.
 
5
;; Copyright (C) 1998-2004 A.J. Rossini, Rich M. Heiberger, Martin
 
6
;;      Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
5
7
 
6
 
;; Author: A.J. Rossini <rossini@biostat.washington.edu>
7
 
;; Maintainer: A.J. Rossini <rossini@biostat.washington.edu>
 
8
;; Original Author: A.J. Rossini <rossini@biostat.washington.edu>
8
9
;; Created: 26 Aug 1997
9
 
;; Modified: $Date: 2002/05/10 19:33:24 $
10
 
;; Version: $Revision: 5.29 $
11
 
;; RCS: $Id: essl-s.el,v 5.29 2002/05/10 19:33:24 rmh Exp $
 
10
;; Maintainers: ESS-core <ESS-core@stat.math.ethz.ch>
12
11
 
13
12
;; This file is part of ESS (Emacs Speaks Statistics).
14
13
 
19
18
 
20
19
;; This file is distributed in the hope that it will be useful,
21
20
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
22
;; GNU General Public License for more details.
24
23
 
25
24
;; You should have received a copy of the GNU General Public License
26
 
;; along with GNU Emacs; see the file COPYING.  If not, write to
 
25
;; along with GNU Emacs; see the file COPYING.  If not, write to
27
26
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28
27
 
29
28
;;; Commentary:
43
42
    nil
44
43
  (setq S-syntax-table (make-syntax-table))
45
44
  (modify-syntax-entry ?\\ "\\" S-syntax-table)
46
 
  (modify-syntax-entry ?+  "."  S-syntax-table)
47
 
  (modify-syntax-entry ?-  "."  S-syntax-table)
48
 
  (modify-syntax-entry ?=  "."  S-syntax-table)
49
 
  (modify-syntax-entry ?%  "."  S-syntax-table)
50
 
  (modify-syntax-entry ?<  "."  S-syntax-table)
51
 
  (modify-syntax-entry ?>  "."  S-syntax-table)
52
 
  (modify-syntax-entry ?&  "."  S-syntax-table)
53
 
  (modify-syntax-entry ?|  "."  S-syntax-table)
 
45
  (modify-syntax-entry ?+  "."  S-syntax-table)
 
46
  (modify-syntax-entry ?-  "."  S-syntax-table)
 
47
  (modify-syntax-entry ?=  "."  S-syntax-table)
 
48
  (modify-syntax-entry ?%  "."  S-syntax-table)
 
49
  (modify-syntax-entry ?<  "."  S-syntax-table)
 
50
  (modify-syntax-entry ?>  "."  S-syntax-table)
 
51
  (modify-syntax-entry ?&  "."  S-syntax-table)
 
52
  (modify-syntax-entry ?|  "."  S-syntax-table)
54
53
  (modify-syntax-entry ?\' "\"" S-syntax-table)
55
 
  (modify-syntax-entry ?#  "<"  S-syntax-table) ; open comment
56
 
  (modify-syntax-entry ?\n ">"  S-syntax-table) ; close comment
 
54
  (modify-syntax-entry ?\" "\"" S-syntax-table)
 
55
  (modify-syntax-entry ?#  "<"  S-syntax-table) ; open comment
 
56
  (modify-syntax-entry ?\n ">"  S-syntax-table) ; close comment
57
57
  ;;(modify-syntax-entry ?.  "w"  S-syntax-table) ; "." used in S obj names
58
 
  (modify-syntax-entry ?.  "_"  S-syntax-table) ; see above/below,
 
58
  (modify-syntax-entry ?.  "_"  S-syntax-table) ; see above/below,
59
59
                                        ; plus consider separation.
60
 
  (modify-syntax-entry ?$  "_"  S-syntax-table) ; foo.bar$hack is 1 symbol
61
 
  (modify-syntax-entry ?_  "."  S-syntax-table)
62
 
  (modify-syntax-entry ?*  "."  S-syntax-table)
63
 
  (modify-syntax-entry ?<  "."  S-syntax-table)
64
 
  (modify-syntax-entry ?>  "."  S-syntax-table)
65
 
  (modify-syntax-entry ?/  "."  S-syntax-table))
 
60
  (modify-syntax-entry ?$  "_"  S-syntax-table) ; foo.bar$hack is 1 symbol
 
61
  (modify-syntax-entry ?_  "."  S-syntax-table)
 
62
  (modify-syntax-entry ?*  "."  S-syntax-table)
 
63
  (modify-syntax-entry ?<  "."  S-syntax-table)
 
64
  (modify-syntax-entry ?>  "."  S-syntax-table)
 
65
  (modify-syntax-entry ?/  "."  S-syntax-table))
66
66
 
67
67
(defvar S-editing-alist
68
 
  '((paragraph-start              . (concat "^$\\|" page-delimiter))
69
 
    (paragraph-separate           . (concat "^$\\|" page-delimiter))
 
68
  '((paragraph-start              . (concat "\\s-*$\\|" page-delimiter))
 
69
    (paragraph-separate           . (concat "\\s-*$\\|" page-delimiter))
70
70
    (paragraph-ignore-fill-prefix . t)
71
 
    (require-final-newline        . t)
72
 
    (comment-start                . "#")
73
 
    (comment-start-skip           . "#+ *")
74
 
    (comment-column               . 40)
75
 
    ;;(comment-indent-function  . 'S-comment-indent)
76
 
    ;;(ess-comment-indent           . 'S-comment-indent)
77
 
    ;;(ess-indent-line                      . 'S-indent-line)
78
 
    ;;(ess-calculate-indent           . 'S-calculate-indent)
79
 
    (indent-line-function            . 'S-indent-line)
80
 
    (parse-sexp-ignore-comments   . t)
81
 
    (ess-set-style                . ess-default-style)
82
 
    (ess-local-process-name       . nil)
83
 
    ;;(ess-keep-dump-files          . 'ask)
84
 
    (ess-mode-syntax-table        . S-syntax-table)
 
71
    (require-final-newline        . t)
 
72
    (comment-start                . "#")
 
73
    (comment-start-skip           . "#+ *")
 
74
    (comment-column               . 40)
 
75
    ;;(comment-indent-function  . 'S-comment-indent)
 
76
    ;;(ess-comment-indent           . 'S-comment-indent)
 
77
    ;;(ess-indent-line                      . 'S-indent-line)
 
78
    ;;(ess-calculate-indent           . 'S-calculate-indent)
 
79
    (indent-line-function            . 'S-indent-line)
 
80
    (parse-sexp-ignore-comments   . t)
 
81
    (ess-set-style                . ess-default-style)
 
82
    (ess-local-process-name       . nil)
 
83
    ;;(ess-keep-dump-files          . 'ask)
 
84
    (ess-mode-syntax-table        . S-syntax-table)
85
85
    ;; For Changelog add, require ' ' before <- : "attr<-" is a function name :
86
86
    (add-log-current-defun-header-regexp . "^\\(.+\\)\\s-+<-[ \t\n]*function")
87
 
    (font-lock-defaults           . '(ess-mode-font-lock-keywords
 
87
    (font-lock-defaults           . '(ess-mode-font-lock-keywords
88
88
                                      nil nil ((?\. . "w"))))
89
89
    )
90
90
  "General options for editing S, S+, and R source files.")
91
91
 
92
92
(defvar inferior-S-language-start
93
93
  '(concat "options("
94
 
             "STERM='"  ess-STERM  "'"
 
94
             "STERM='"  ess-STERM  "'"
95
95
             (if ess-editor (concat ", editor='" ess-editor "'"))
96
 
             (if ess-pager  (concat ", pager='"  ess-pager  "', help.pager='"  ess-pager  "'"))
 
96
             (if ess-pager  (concat ", pager='"  ess-pager  "', help.pager='"  ess-pager  "'"))
97
97
             ")")
98
98
  "S language expression for startup -- default for all S dialects.")
99
99
 
169
169
(defconst ess-help-S+-sec-regex "^[A-Z. ---]+:$"
170
170
  "Reg(ular) Ex(pression) of section headers in help file.")
171
171
 
172
 
(defconst ess-help-R-sec-regex "^\\s *[A-Z[a-z. ---]+:$"
 
172
(defconst ess-help-R-sec-regex "^[A-Z][a-z].+:$"
173
173
  "Reg(ular) Ex(pression) of section headers in help file.")
174
174
 
175
175
;;; S-mode extras of Martin Maechler, Statistik, ETH Zurich.
176
176
;;; See also ./ess-utils.el
177
177
 
178
178
(defvar ess-function-outline-file
179
 
  (concat ess-lisp-directory "/../etc/" "function-outline.S")
 
179
  (concat ess-etc-directory  "/function-outline.S")
180
180
  "The file name of the ess-function outline that is to be inserted at point,
181
181
when \\<ess-mode-map>\\[ess-insert-function-outline] is used.
182
182
Placeholders (substituted `at runtime'): $A$ for `Author', $D$ for `Date'.")
387
387
(defun ess-fix-comments (&optional dont-query verbose)
388
388
  "Fix ess-mode buffer so that single-line comments start with at least `##'."
389
389
  (interactive "P")
390
 
  (save-excursion
391
 
    (goto-char (point-min))
392
 
    (let ((rgxp "^\\([ \t]*#\\)\\([^#]\\)")
393
 
          (to   "\\1#\\2"))
394
 
      (if dont-query
395
 
          (ess-rep-regexp     rgxp to nil nil verbose)
396
 
        (query-replace-regexp rgxp to nil)))))
 
390
  (ess-replace-regexp-dump-to-src "^\\([ \t]*#\\)\\([^#]\\)"
 
391
                                  "\\1#\\2" dont-query verbose))
397
392
 
398
393
(defun ess-dump-to-src (&optional dont-query verbose)
399
394
  "Make the changes in an S - dump() file to improve human readability."
400
395
  (interactive "P")
401
 
  (save-excursion
402
 
    (if (not (equal major-mode 'ess-mode))
403
 
        (ess-mode))
404
 
    (goto-char (point-min))
405
 
    (let ((rgxp "^\"\\([a-z.][a-z.0-9]*\\)\"<-\n")
406
 
          (to   "\n\\1 <- "))
407
 
      (if dont-query
408
 
          (ess-rep-regexp     rgxp to nil nil verbose)
409
 
        (query-replace-regexp rgxp to nil)))))
 
396
  (ess-replace-regexp-dump-to-src  "^\"\\([a-z.][a-z.0-9]*\\)\"<-\n"
 
397
                                   "\n\\1 <- "
 
398
                                   dont-query verbose 'ensure-ess))
410
399
 
411
400
(defun ess-num-var-round (&optional dont-query verbose)
412
401
  "Is VERY useful for dump(.)'ed numeric variables; ROUND some of them by
413
 
  replacing  endings of 000000*.. and 999999*.  Martin Maechler"
 
402
  replacing  endings of 000000*.. and 999999*.  Martin Maechler"
414
403
  (interactive "P")
415
404
  (save-excursion
416
405
    (goto-char (point-min))
418
407
    (let ((num 0)
419
408
          (str "")
420
409
          (rgxp "000000+[1-9]?[1-9]?\\>")
421
 
          (to   ""))
 
410
          (to   ""))
422
411
      (if dont-query
423
412
          (ess-rep-regexp     rgxp to nil nil verbose)
424
413
        (query-replace-regexp rgxp to nil))
432
421
                        'fixedcase 'literal verbose)
433
422
        (setq num (1+ num))))))
434
423
 
 
424
(defun ess-fix-dot (before-chars &optional dont-query verbose)
 
425
  "Remove trailing decimal '.' (\"dot\"), before BEFORE; typically from S-plus"
 
426
  ;; typically, before-chars =  "]:" or more
 
427
  (ess-replace-regexp-dump-to-src
 
428
   (concat "\\([0-9]\\)\\.\\( *[" before-chars "]\\)")
 
429
   ;;           111      ^
 
430
   "\\1\\2" dont-query verbose))
 
431
 
 
432
(defun ess-fix-dot-1 (&optional do-query verbose)
 
433
  "Remove trailing decimal '.' (\"dot\"), before ':' or ']', i.e.,
 
434
in cases where it's ugly and nonsense.  DO-QUERY(prefix) asks before replacing."
 
435
  (interactive "P")
 
436
  (ess-fix-dot "]:" (not do-query) verbose))
 
437
 
 
438
(defun ess-fix-dot-more (&optional dont-query verbose)
 
439
  "Remove trailing decimal '.' (\"dot\", typically from S+) in more cases
 
440
 than `ess-fix-dot-1'."
 
441
  (interactive "P")
 
442
  (ess-fix-dot-1 nil verbose)
 
443
  (ess-fix-dot ",)" dont-query verbose))
 
444
 
 
445
(defun ess-fix-EQ-assign (&optional dont-query verbose)
 
446
  "Replace \"=\" by \"<-\" at least for function assignments.
 
447
CAREFUL if have list()s of functions!"
 
448
  ;;TODO: "in the few places we can be very sure.."
 
449
  ;;---- is hard in general: local functions: ok; but functions in
 
450
  ;;  list(a = function(x) abs(x), b= function(y) bound(y))  *NOT* ok!
 
451
  (interactive "P")
 
452
  (ess-replace-regexp-dump-to-src
 
453
   "^\\( *[a-z.][_a-z.0-9]*\\) *= *\\(function *(\\)"
 
454
   "\\1 <- \\2" dont-query verbose))
 
455
 
435
456
;;; All of the above three :
436
457
(defun ess-MM-fix-src (&optional dont-query verbose)
437
 
  "Clean up ess-source code which has been produced by  dump(..).
438
 
 Produces more readable code, and one that is well formatted in emacs ess-mode."
 
458
  "Clean up ess-source code which has been produced by dump(..), and other
 
459
code not typically produced by other tools.  Produces more readable code,
 
460
and one that is well formatted in emacs ess-mode."
439
461
  (interactive "P")
440
462
  ;; each of the following does a save-excursion:
441
463
  (ess-dump-to-src dont-query)
442
464
  (ess-fix-comments dont-query)
443
 
  (ess-num-var-round dont-query verbose))
 
465
  (ess-num-var-round dont-query verbose)
 
466
  (ess-fix-dot-more dont-query verbose)
 
467
  (ess-fix-EQ-assign dont-query verbose)
 
468
  )
444
469
 
445
470
(defun ess-fix-miscellaneous (&optional from verbose)
446
471
  "Fix Miscellaneous S/R `ill-formation's from current \\[point].
453
478
         (require 'essd-r)
454
479
         (R-fix-T-F from (not verbose))))
455
480
 
456
 
    (goto-char from) (ess-rep-regexp " *_ *" " <- " nil 'literal verbose)
 
481
    ;;from R 1.9.x "_" is valid in names; here assume no initial / trailing '_'
 
482
    (goto-char from) (ess-rep-regexp " +_ *" " <- " nil 'literal verbose)
 
483
    (goto-char from) (ess-rep-regexp   "_ +" " <- " nil 'literal verbose)
457
484
 
458
485
    ;; ensure space around  "<-"  ---- but only replace if necessary:
459
486
    (goto-char from)
489
516
    ))
490
517
 
491
518
(defun ess-smart-underscore ()
492
 
  "Electrical \"_\" key: insert `ess-S-assign' after removing spaces, unless
493
 
 in string/comment.  `ess-S-assign', typically \" <- \", can be customized."
 
519
  "Smart \"_\" key: insert `ess-S-assign', unless in string/comment.
 
520
If the underscore key is pressed a second time, the assignment
 
521
operator is removed and replaced by the underscore.  `ess-S-assign',
 
522
typically \" <- \", can be customized.  In ESS modes other than R/S,
 
523
an underscore is always inserted. "
494
524
  (interactive)
495
525
  ;;(insert (if (inside-string/comment-p (point)) "_" ess-S-assign))
496
 
  (if (inside-string/comment-p (point))
 
526
  (if (or
 
527
       (inside-string/comment-p (point))
 
528
       (not (equal ess-language "S")))
497
529
      (insert "_")
498
 
    ;; else
499
 
    (delete-horizontal-space)
500
 
    (insert ess-S-assign)))
 
530
    ;; Else one keypress produces ess-S-assign; a second keypress will delete
 
531
    ;; ess-S-assign and instead insert _
 
532
    ;; Rather than trying to count a second _ keypress, just check whether
 
533
    ;; the current point is preceded by ess-S-assign.
 
534
    (let ((assign-len (length ess-S-assign)))
 
535
      (if (and
 
536
           (>= (point) (+ assign-len (point-min))) ;check that we can move back
 
537
           (save-excursion
 
538
             (backward-char assign-len)
 
539
             (looking-at ess-S-assign)))
 
540
          ;; If we are currently looking at ess-S-assign, replace it with _
 
541
          (progn
 
542
            (delete-backward-char assign-len)
 
543
            (insert "_"))
 
544
        (delete-horizontal-space)
 
545
        (insert ess-S-assign)))))
501
546
 
502
547
(defun ess-toggle-underscore (force)
503
548
  "Set the \"_\" (underscore) key to \\[ess-smart-underscore] or back to \"_\".
513
558
             ;; (stringp uscore) (string= uscore ess-S-assign)
514
559
             (not force))
515
560
        (progn
516
 
         (define-key ess-mode-map          "_" nil); 'self-insert-command
 
561
         (define-key ess-mode-map          "_" nil); 'self-insert-command
517
562
         (define-key inferior-ess-mode-map "_" nil))
518
563
      ;; else : "force" or uscore is "nil", i.e. default
519
 
      (define-key ess-mode-map          "_" 'ess-smart-underscore)
 
564
      (define-key ess-mode-map          "_" 'ess-smart-underscore)
520
565
      (define-key inferior-ess-mode-map "_" 'ess-smart-underscore))))
521
566
 
522
567
;; NOTA BENE: "_" is smart *by default* :
540
585
 
541
586
  (interactive "sFunction ? ")
542
587
  (let* ((buffname "ess-complete.R")
543
 
         (buf (ess-execute (format "args(%s)" Sfunc)
544
 
                                          t
545
 
                                          buffname)))
 
588
         (buf (ess-execute (format "args(%s)" Sfunc) t buffname)))
546
589
    (pop-to-buffer buf)
547
590
    (message "here yet?")
548
591
    (replace-string "function" Sfunc)
549
 
    (ess-setq-vars-local ess-customize-alist (current-buffer))
 
592
    (ess-setq-vars-local ess-customize-alist); (current-buffer))
550
593
    (setq major-mode 'ess-mode)
551
594
    (use-local-map ess-mode-map)
552
595
    (set-syntax-table ess-mode-syntax-table)
559
602
 
560
603
;;; This file is automatically placed in Outline minor mode.
561
604
;;; The file is structured as follows:
562
 
;;; Chapters:     ^L ;
563
 
;;; Sections:    ;;*;;
 
605
;;; Chapters:     ^L ;
 
606
;;; Sections:    ;;*;;
564
607
;;; Subsections: ;;;*;;;
565
 
;;; Components:  defuns, defvars, defconsts
566
 
;;;              Random code beginning with a ;;;;* comment
 
608
;;; Components:  defuns, defvars, defconsts
 
609
;;;              Random code beginning with a ;;;;* comment
567
610
 
568
611
;;; Local variables:
569
612
;;; mode: emacs-lisp