add lisp packages
This commit is contained in:
11
lisp/ess/.dir-locals.el
Normal file
11
lisp/ess/.dir-locals.el
Normal file
@@ -0,0 +1,11 @@
|
||||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((nil
|
||||
(bug-reference-bug-regexp . "#\\(?2:[0-9]+\\)")
|
||||
(bug-reference-url-format . "https://github.com/emacs-ess/ess/issues/%s")
|
||||
(sentence-end-double-space))
|
||||
(emacs-lisp-mode
|
||||
(outline-regexp . "\f\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*")
|
||||
(indent-tabs-mode))
|
||||
(ess-r-mode . ((ess-style . RRR))))
|
||||
1966
lisp/ess/allnews.info
Normal file
1966
lisp/ess/allnews.info
Normal file
File diff suppressed because it is too large
Load Diff
768
lisp/ess/announc.info
Normal file
768
lisp/ess/announc.info
Normal file
@@ -0,0 +1,768 @@
|
||||
This is announc.info, produced by makeinfo version 6.5 from
|
||||
announc.texi.
|
||||
|
||||
|
||||
File: announc.info, Node: Announce
|
||||
|
||||
1 ANNOUNCING ESS
|
||||
****************
|
||||
|
||||
The ESS Developers proudly announce the release of ESS 18.10.3snapshot
|
||||
|
||||
Emacs Speaks Statistics (ESS) provides an intelligent, consistent
|
||||
interface between the user and the software. ESS interfaces with
|
||||
R/S-PLUS, SAS, BUGS/JAGS, Stata and other statistical analysis packages
|
||||
under the UNIX, GNU Linux, Microsoft Windows, macOS and other operating
|
||||
systems. ESS is a package for the GNU Emacs text editor whose features
|
||||
ESS uses to streamline the creation and use of statistical software.
|
||||
ESS knows the syntax and grammar of statistical analysis packages and
|
||||
provides consistent display and editing features based on that
|
||||
knowledge. ESS assists in interactive and batch execution of statements
|
||||
written in these statistical analysis languages.
|
||||
|
||||
ESS is freely available under the GNU General Public License (GPL).
|
||||
Please read the file COPYING which comes with the distribution, for more
|
||||
information about the license. For more detailed information, please
|
||||
read the README files that come with ESS.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Latest Version::
|
||||
* Current Features::
|
||||
* Requirements::
|
||||
* Mailing List::
|
||||
* Reporting Bugs::
|
||||
* Authors::
|
||||
* License::
|
||||
* New Features::
|
||||
|
||||
|
||||
File: announc.info, Node: Latest Version, Next: Current Features, Prev: Announce, Up: Announce
|
||||
|
||||
1.1 Getting the Latest Version
|
||||
==============================
|
||||
|
||||
ESS supports GNU Emacs versions 25.1 and newer.
|
||||
|
||||
ESS is most likely to work with current/recent versions of the
|
||||
following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
|
||||
|
||||
To build the PDF documentation, you will need a version of TeX Live
|
||||
or texinfo that includes texi2dvi.
|
||||
|
||||
There are two main methods used for installing ESS. You may install
|
||||
from a third-party repository or from source code. Once you install it,
|
||||
you must also activate or load ESS in each Emacs session, though
|
||||
installation from a third-party repository likely takes care of that for
|
||||
you. See *note Activating and Loading ESS:: for more details.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Installing from a third-party repository::
|
||||
* Installing from source::
|
||||
* Activating and Loading ESS::
|
||||
* Check Installation::
|
||||
|
||||
|
||||
File: announc.info, Node: Installing from a third-party repository, Next: Installing from source
|
||||
|
||||
1.2 Installing from a third-party repository
|
||||
============================================
|
||||
|
||||
ESS is packaged by many third party repositories. Many GNU/Linux
|
||||
distributions package it, usually with the name "emacs-ess" or similar.
|
||||
|
||||
ESS is also available through Milkypostman’s Emacs Lisp Package
|
||||
Archive (MELPA), a popular repository for Emacs packages. Instructions
|
||||
on how to do so are found on MELPA's website (https://melpa.org/).
|
||||
MELPA also hosts MELPA-stable with stable ESS builds. You may choose
|
||||
between MELPA with the latest and greatest features (and bugs) or
|
||||
MELPA-stable, which may lag a bit behind but should be more stable.
|
||||
|
||||
After installing, users should make sure ESS is activated or loaded
|
||||
in each Emacs session. See *note Activating and Loading ESS::.
|
||||
Depending on install method, this may be taken care of automatically.
|
||||
|
||||
|
||||
File: announc.info, Node: Installing from source, Next: Activating and Loading ESS, Prev: Installing from a third-party repository
|
||||
|
||||
1.3 Installing from source
|
||||
==========================
|
||||
|
||||
Stable versions of ESS are available at the ESS web page
|
||||
(https://ess.r-project.org) as a .tgz file or .zip file. ESS releases
|
||||
are GPG-signed, you should check the signature by downloading the
|
||||
accompanying '.sig' file and doing:
|
||||
|
||||
gpg --verify ess-18.10.tgz.sig
|
||||
|
||||
Alternatively, you may download the git repository. ESS is currently
|
||||
hosted on GitHub: <https://github.com/emacs-ess/ESS>. 'git clone
|
||||
https://github.com/emacs-ess/ESS.git' will download it to a new
|
||||
directory 'ESS' in the current working directory.
|
||||
|
||||
We will refer to the location of the ESS source files as
|
||||
'/path/to/ESS/' hereafter.
|
||||
|
||||
After installing, users should make sure they activate or load ESS in
|
||||
each Emacs session, see *note Activating and Loading ESS::
|
||||
|
||||
Optionally, compile elisp files, build the documentation, and the
|
||||
autoloads:
|
||||
cd /path/to/ESS/
|
||||
make
|
||||
Without this step the documentation, reference card, and autoloads
|
||||
will not be available. Uncompiled ESS will also run slower.
|
||||
|
||||
Optionally, you may make ESS available to all users of a machine by
|
||||
installing it site-wide. To do so, run 'make install'. You might need
|
||||
administrative privileges:
|
||||
|
||||
make install
|
||||
|
||||
The files are installed into '/usr/share/emacs' directory. For this
|
||||
step to run correctly on macOS, you will need to adjust the 'PREFIX'
|
||||
path in 'Makeconf'. The necessary code and instructions are commented
|
||||
in that file.
|
||||
|
||||
|
||||
File: announc.info, Node: Activating and Loading ESS, Next: Check Installation, Prev: Installing from source
|
||||
|
||||
1.4 Activating and Loading ESS
|
||||
==============================
|
||||
|
||||
After installing ESS, you must activate or load it each Emacs session.
|
||||
ESS can be autoloaded, and if you used a third-party repository (such as
|
||||
your Linux distribution or MELPA) to install, you can likely skip this
|
||||
section and proceed directly to *note Check Installation::
|
||||
|
||||
Otherwise, you may need to add the path to ESS to 'load-path' with:
|
||||
|
||||
(add-to-list 'load-path "/path/to/ESS/lisp")
|
||||
|
||||
You then need to decide whether to take advantage of deferred loading
|
||||
(which will result in a faster Emacs startup time) or require ESS when
|
||||
Emacs is loaded. To autoload ESS when needed (note that if installed
|
||||
from source, you must have run 'make'):
|
||||
|
||||
(load "ess-autoloads")
|
||||
|
||||
To require ESS on startup, you can either put
|
||||
|
||||
(require 'ess-site)
|
||||
|
||||
or
|
||||
|
||||
(require 'ess-r-mode)
|
||||
|
||||
In your configuration file, depending on whether you want all ESS
|
||||
features or only R related features.
|
||||
|
||||
|
||||
File: announc.info, Node: Check Installation, Prev: Activating and Loading ESS
|
||||
|
||||
1.5 Check Installation
|
||||
======================
|
||||
|
||||
Restart Emacs and check that ESS was loaded from a correct location with
|
||||
'M-x ess-version'.
|
||||
|
||||
|
||||
File: announc.info, Node: Current Features, Next: Requirements, Prev: Latest Version, Up: Announce
|
||||
|
||||
1.6 Current Features
|
||||
====================
|
||||
|
||||
* Languages Supported:
|
||||
* S family (R, S, and S+ AKA S-PLUS)
|
||||
* SAS
|
||||
* BUGS/JAGS
|
||||
* Stata
|
||||
* Julia
|
||||
* Editing source code (S family, SAS, BUGS/JAGS, Stata, Julia)
|
||||
* Syntactic indentation and highlighting of source code
|
||||
* Partial evaluation of code
|
||||
* Loading and error-checking of code
|
||||
* Source code revision maintenance
|
||||
* Batch execution (SAS, BUGS/JAGS)
|
||||
* Use of imenu to provide links to appropriate functions
|
||||
* Interacting with the process (S family, SAS, Stata, Julia)
|
||||
* Command-line editing
|
||||
* Searchable Command history
|
||||
* Command-line completion of S family object names and file
|
||||
names
|
||||
* Quick access to object lists and search lists
|
||||
* Transcript recording
|
||||
* Interface to the help system
|
||||
* Transcript manipulation (S family, Stata)
|
||||
* Recording and saving transcript files
|
||||
* Manipulating and editing saved transcripts
|
||||
* Re-evaluating commands from transcript files
|
||||
* Interaction with Help Pages and other Documentation (R)
|
||||
* Fast Navigation
|
||||
* Sending Examples to running ESS process.
|
||||
* Fast Transfer to Further Help Pages
|
||||
* Help File Editing (R)
|
||||
* Syntactic indentation and highlighting of source code.
|
||||
* Sending Examples to running ESS process.
|
||||
* Previewing
|
||||
|
||||
|
||||
File: announc.info, Node: Requirements, Next: Mailing List, Prev: Current Features, Up: Announce
|
||||
|
||||
1.7 Requirements
|
||||
================
|
||||
|
||||
ESS supports GNU Emacs versions 25.1 and newer.
|
||||
|
||||
ESS is most likely to work with current/recent versions of the
|
||||
following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
|
||||
|
||||
To build the PDF documentation, you will need a version of TeX Live
|
||||
or texinfo that includes texi2dvi.
|
||||
|
||||
|
||||
File: announc.info, Node: Mailing List, Next: Reporting Bugs, Prev: Requirements, Up: Announce
|
||||
|
||||
1.8 Mailing List
|
||||
================
|
||||
|
||||
There is a mailing list for discussions and announcements relating to
|
||||
ESS. Join the list by sending an e-mail with "subscribe ess-help" (or
|
||||
"help") in the body to <ess-help-request@r-project.org>; contributions
|
||||
to the list may be mailed to <ess-help@r-project.org>. Rest assured,
|
||||
this is a fairly low-volume mailing list.
|
||||
|
||||
The purposes of the mailing list include
|
||||
|
||||
* helping users of ESS to get along with it.
|
||||
* discussing aspects of using ESS.
|
||||
* suggestions for improvements.
|
||||
* announcements of new releases of ESS.
|
||||
* posting small patches to ESS.
|
||||
|
||||
|
||||
File: announc.info, Node: Reporting Bugs, Next: Authors, Prev: Mailing List, Up: Announce
|
||||
|
||||
1.9 Reporting Bugs
|
||||
==================
|
||||
|
||||
Please send bug reports, suggestions etc. to <ESS-bugs@r-project.org>,
|
||||
or post them on our github issue tracker
|
||||
(https://github.com/emacs-ess/ESS/issues)
|
||||
|
||||
The easiest way to do this is within Emacs by typing
|
||||
|
||||
'M-x ess-submit-bug-report'
|
||||
|
||||
This also gives the maintainers valuable information about your
|
||||
installation which may help us to identify or even fix the bug.
|
||||
|
||||
If Emacs reports an error, backtraces can help us debug the problem.
|
||||
Type "M-x set-variable RET debug-on-error RET t RET". Then run the
|
||||
command that causes the error and you should see a *Backtrace* buffer
|
||||
containing debug information; send us that buffer.
|
||||
|
||||
Note that comments, suggestions, words of praise and large cash
|
||||
donations are also more than welcome.
|
||||
|
||||
|
||||
File: announc.info, Node: Authors, Next: License, Prev: Reporting Bugs, Up: Announce
|
||||
|
||||
1.10 Authors
|
||||
============
|
||||
|
||||
* A.J. Rossini (mailto:blindglobe@gmail.com)
|
||||
* Richard M. Heiberger (mailto:rmh@temple.edu)
|
||||
* Kurt Hornik (mailto:Kurt.Hornik@R-project.org)
|
||||
* Martin Maechler (mailto:maechler@stat.math.ethz.ch)
|
||||
* Rodney A. Sparapani (mailto:rsparapa@mcw.edu)
|
||||
* Stephen Eglen (mailto:stephen@gnu.org)
|
||||
* Sebastian P. Luque (mailto:spluque@gmail.com)
|
||||
* Henning Redestig (mailto:henning.red@googlemail.com)
|
||||
* Vitalie Spinu (mailto:spinuvit@gmail.com)
|
||||
* Lionel Henry (mailto:lionel.hry@gmail.com)
|
||||
* J. Alexander Branham (mailto:alex.branham@gmail.com)
|
||||
|
||||
|
||||
File: announc.info, Node: License, Next: New Features, Prev: Authors, Up: Announce
|
||||
|
||||
1.11 License
|
||||
============
|
||||
|
||||
The source and documentation of ESS is free software. You can
|
||||
redistribute it and/or modify it under the terms of the GNU General
|
||||
Public License as published by the Free Software Foundation; either
|
||||
version 2, or (at your option) any later version.
|
||||
|
||||
ESS is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License in
|
||||
the file COPYING in the same directory as this file for more details.
|
||||
|
||||
|
||||
File: announc.info, Node: New Features, Prev: License, Up: Announce
|
||||
|
||||
1.12 New Features
|
||||
=================
|
||||
|
||||
Changes and New Features in 19.04 (unreleased):
|
||||
|
||||
* ESS[R]: Automatic offsetting of R process output is now disabled by
|
||||
default because it produces undesirable output in some situations.
|
||||
To re-enable, set 'inferior-ess-fix-misaligned-output' to t.
|
||||
|
||||
* ESS[R]: Improved 'xref' lookup ('M-.'). Function locations are now
|
||||
always detected for package libraries listed in
|
||||
'ess-r-package-library-paths'.
|
||||
|
||||
* ESS[R]: Evaluated lines starting with the Roxygen prefix are now
|
||||
always stripped from the prefix, so they can be sent to the process
|
||||
easily. Previously, this was only the case inside the 'examples'
|
||||
field. Since roxygen is switching to R markdown, it becomes useful
|
||||
to evaluate chunks of R outside examples.
|
||||
|
||||
* stata support is now obsolete since we were unable to elicit FSF
|
||||
paperwork from some of the original authors: see the lisp/obsolete
|
||||
sub-directory on the ESS github repo
|
||||
|
||||
* 'ess-set-working-directory' no longer changes the active directory
|
||||
(as defined by the buffer-local variable 'default-directory') of
|
||||
the buffer where the command is called. Instead, the active
|
||||
directory of the inferior buffer is updated to the new working
|
||||
directory.
|
||||
|
||||
* The default of ess-eval-visibly is now ''nowait'. With this change
|
||||
you should no longer experience freezes while evaluating code.
|
||||
|
||||
* ESS[R]: There is a new menu entry for reloading the R process. It
|
||||
is otherwise bound to 'C-c C-e C-r'. Reloading now reuses the same
|
||||
process name and start arguments that were used to start the
|
||||
process.
|
||||
|
||||
* iESS: Process runners now return the inferior buffer. Note that
|
||||
callers of inferior runners should not assume that the current
|
||||
buffer has been set to the inferior buffer. Instead, use
|
||||
'with-current-buffer' with the return value of the inferior.
|
||||
|
||||
* iESS[SAS]: The SAS keymap was only set in iESS buffers called
|
||||
'*SAS*'. This is now fixed.
|
||||
|
||||
* ESS[R]: Fixed longstanding indentation issues involving '::' and
|
||||
':::' operators.
|
||||
|
||||
* Implement a more reliable check for the process busy state.
|
||||
Background actions such as completion and directory synchronization
|
||||
should not block the process and should not cause printing of the
|
||||
extraneous output to the interpreter.
|
||||
|
||||
* Activate 'goto-address-mode' for url and email highlighting in
|
||||
inferior buffers.
|
||||
|
||||
* 'smart-underscore' and 'ess-smart-S-assign-key' have been removed.
|
||||
Users who liked the previous behavior (i.e. underscore inserting
|
||||
"<-") should bind 'ess-insert-assign' to the underscore in their
|
||||
Emacs initialization file. For example, '(define-key
|
||||
ess-r-mode-map "_" #'ess-insert-assign)' and '(define-key
|
||||
inferior-ess-r-mode-map "_" #'ess-insert-assign)' will activate it
|
||||
in all ESS R buffers.
|
||||
|
||||
* ESS major modes are now defined using 'define-derived-mode'. This
|
||||
makes ESS major modes respect modern conventions such as having
|
||||
<language>-mode-hook and <language>-mode-map. Users are encouraged
|
||||
to place customizations under the appropriate mode.
|
||||
|
||||
* New option ess-auto-width controls setting the width option on
|
||||
window changes. Users can change it to 'frame, 'window, or an
|
||||
integer. See the documentation for details.
|
||||
'ess-auto-width-visible' controls visibility.
|
||||
|
||||
* ESS now respects 'display-buffer-alist'. Users can now use
|
||||
'display-buffer-alist' to manage how and where windows appear. For
|
||||
more information and examples, see *Note (ess)Controlling buffer
|
||||
display::.
|
||||
|
||||
* 'ess-roxy-mode' can now be enabled in non-R buffers. This is
|
||||
primarily intended to support roxygen documentation for cpp
|
||||
buffers. Preview functionality is not supported outside R buffers.
|
||||
|
||||
* ESS[R]: DESCRIPTION files now open in 'conf-colon-mode'.
|
||||
|
||||
* 'ess-style' now has effects when set as a file or directory local
|
||||
variable.
|
||||
|
||||
* 'ess-default-style' is now obsolete, use 'ess-style' instead.
|
||||
|
||||
* Options for 'ess-gen-proc-buffer-name-function' have been renamed.
|
||||
ess-gen-proc-buffer-name:projectile-or-simple was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-simple and
|
||||
ess-gen-proc-buffer-name:projectile-or-directory was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-directory. As the name
|
||||
suggests, these now rely on project.el (included with Emacs) rather
|
||||
than projectile.el, which is a third-party package.
|
||||
|
||||
* Eldoc fully honors 'eldoc-echo-area-use-multiline-p'
|
||||
|
||||
* ESS[R]: 'ess-r-rhub-check-package' gained new 'RECOMMENDED'.
|
||||
|
||||
* ESS[R]: devtools commands ask about saving modified buffers before
|
||||
running. Users can disable the questioning with
|
||||
'ess-save-silently'.
|
||||
|
||||
* ESS[R] help pages now provide links to other help topics. This is
|
||||
similar with what you would see with, for example
|
||||
'options(help_type = ``html'')' but works with the plain-text
|
||||
version as well. This only works with 'options(useFancyQuotes =
|
||||
TRUE)' (the default).
|
||||
|
||||
* 'ess-rdired' buffers now derive from tabulated-list-mode. They
|
||||
should look better and be a bit faster overall. The size column
|
||||
now displays object sizes in bytes.
|
||||
|
||||
* 'ess-rdired' buffers now auto-update. The frequency is governed by
|
||||
the new option 'ess-rdired-auto-update-interval'.
|
||||
|
||||
* ESS[R]: 'electric-layout-mode' is now supported. This
|
||||
automatically inserts a newline after an opening curly brace in R
|
||||
buffers. To enable it, customize 'ess-r-mode-hook'.
|
||||
|
||||
* ESS[R]: imenu now supports assignment with the equals sign.
|
||||
|
||||
* ESS[Rd]: Rd no longer writes abbrevs to user's abbrev file.
|
||||
|
||||
* ESS removed support for many unused languages. This includes old
|
||||
versions of S+, ARC, OMG, VST, and XLS.
|
||||
|
||||
* ess-r-runner-prefixes was modified to find R-4 and later.
|
||||
|
||||
The following have been made obsolete or removed, see their
|
||||
documentation for more detail:
|
||||
|
||||
* Libraries for literate data analysis are obsolete and not loaded by
|
||||
default. This includes 'ess-noweb', 'ess-swv', and related
|
||||
functionality like 'Rnw-mode'. Users are encouraged to switch to
|
||||
one of several other packages that deal with these modes. For
|
||||
example, polymode <https://github.com/polymode/poly-R/>,
|
||||
<https://polymode.github.io/>, or markdown-mode with edit-indirect
|
||||
<https://jblevins.org/projects/markdown-mode>.
|
||||
|
||||
* Support for 'auto-complete' is obsolete. The 'auto-complete'
|
||||
package is unmaintained and so ESS support is now obsolete. Users
|
||||
are encouraged to switch to 'company-mode' instead.
|
||||
|
||||
* User options for controlling display of buffers. This includes
|
||||
'ess-show-buffer-action', 'inferior-ess-same-window',
|
||||
'inferior-ess-own-frame', and 'inferior-ess-frame-alist'. See
|
||||
above about ESS respecting 'display-buffer-alist'.
|
||||
|
||||
* Variables 'ess-tab-always-indent' and 'ess-tab-complete-in-script'.
|
||||
Use the Emacs-wide setting of 'tab-always-indent' instead.
|
||||
|
||||
* 'inferior-ess-*-start-file' variables. All modes except Stata did
|
||||
not respect customization of this variable. In order to load a
|
||||
file on startup, you should put a function on
|
||||
'ess-*-post-run-hook'.
|
||||
|
||||
Bug Fixes in 18.10.3:
|
||||
* More 'Makefile' fixes, notably installing '*.el's.
|
||||
|
||||
Bug Fixes in 18.10.2:
|
||||
* ESS[R] Fix namespace evaluation in non-installed packages.
|
||||
Evaluation is directed into GlobalEnv as originally intended.
|
||||
* 'Makefile' fixes, notably for 'make install' and including full
|
||||
docs in the tarballs.
|
||||
|
||||
Bug Fixes in 18.10-1:
|
||||
* New functions 'ess-eval-line-visibly-and-step' ('C-c C-n' and
|
||||
'ess-eval-region-or-line-visibly-and-step' ('C-RET') which behave
|
||||
as the old versions of 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step'.
|
||||
|
||||
Changes and New Features in 18.10:
|
||||
|
||||
* This is the last release to support Emacs older than 25.1. Going
|
||||
forward, only GNU Emacs 25.1 and newer will be supported. Soon
|
||||
after this release, support for older Emacs versions will be
|
||||
dropped from the git master branch. Note that MELPA uses the git
|
||||
master branch to produce ESS snapshots, so if you are using Emacs <
|
||||
25.1 from MELPA and are unable to upgrade, you should switch to
|
||||
MELPA-stable.
|
||||
|
||||
* ESS now displays the language dialect in the mode-line. So, for
|
||||
example, R buffers will now show ESS[R] rather than ESS[S].
|
||||
|
||||
* The ESS manual has been updated and revised.
|
||||
|
||||
* The ESS initialization process has been further streamlined. If
|
||||
you update the autoloads (which installation from 'package-install'
|
||||
does), you should not need to '(require 'ess-site)' at all, as
|
||||
autoloads should automatically load ESS when it is needed (e.g.
|
||||
the first time an R buffer is opened). In order to defer loading
|
||||
your ESS config, you may want to do something like
|
||||
'(with-require-after-load "ess" <ess-config-here>)' in your Emacs
|
||||
init file. Users of the popular 'use-package' Emacs package can
|
||||
now do '(use-package ess :defer t)' to take advantage of this
|
||||
behavior. For more information on this feature, see *Note
|
||||
(ess)Activating and Loading ESS::.
|
||||
|
||||
* ESS now respects Emacs conventions for keybindings. This means
|
||||
that The 'C-c [letter]' bindings have been removed. This affects
|
||||
'C-c h', which was bound to 'ess-eval-line-and-step-invisibly' in
|
||||
'sas-mode-local-map'; 'C-c f', which was bound to
|
||||
'ess-insert-function-outline' in 'ess-add-MM-keys'; and 'C-c h',
|
||||
which was bound to 'ess-handy-commands' in 'Rd-mode-map',
|
||||
'ess-noweb-minor-mode-map', and 'ess-help-mode-map'
|
||||
|
||||
* Functions 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step' now behave consistently with
|
||||
other evaluation function inside a package.
|
||||
|
||||
* ESS[R]: 'ess-r-package-use-dir' now works with any mode. This sets
|
||||
the working directory to the root of the current package including
|
||||
for example C or C++ files within '/src').
|
||||
|
||||
* ESS[R]: Long + + prompts in the inferior no longer offset output.
|
||||
|
||||
* ESS[R]: New option 'strip' for 'inferior-ess-replace-long+'. This
|
||||
strips the entire + + sequence.
|
||||
|
||||
* ESS modes now inherit from 'prog-mode'. In the next release, ESS
|
||||
modes will use 'define-derived-mode' so that each mode will have
|
||||
(for example) its own hooks and keymaps.
|
||||
|
||||
* ESS[R]: Supports flymake in R buffers for Emacs 26 and newer.
|
||||
Users need to install the 'lintr' package to use it. Customizable
|
||||
options include 'ess-use-flymake', 'ess-r-flymake-linters', and
|
||||
'ess-r-flymake-lintr-cache'.
|
||||
|
||||
* ESS[R]: Gained support for xref in Emacs 25+ *Note (emacs)Xref::.
|
||||
|
||||
* ESS[R]: The startup screen is cleaner. It also displays the
|
||||
startup directory with an explicit 'setwd()'.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[R]: 'Makevars' files open with 'makefile-mode'.
|
||||
|
||||
* New variable 'ess-write-to-dribble'. This allows users to disable
|
||||
the dribble ('*ESS*') buffer if they wish.
|
||||
|
||||
* All of the '*-program-name' variables have been renamed to
|
||||
'*-program'. Users who previously customized e.g.
|
||||
'inferior-ess-R-program-name' will need to update their
|
||||
customization to 'inferior-ess-R-program'. These variables are
|
||||
treated as risky variables.
|
||||
|
||||
* 'ess-smart-S-assign' was renamed to 'ess-insert-assign'. It
|
||||
provides similar functionality but for any keybinding, not just
|
||||
'_'. For instance if you bind it to ';', repeated invocations
|
||||
cycle through between assignment and inserting ';'.
|
||||
|
||||
* 'C-c C-=' is now bound to 'ess-cycle-assign' by default. See the
|
||||
documentation for details. New user customization option
|
||||
'ess-assign-list' controls which assignment operators are cycled.
|
||||
|
||||
* ESS[R] In remote sessions, the ESSR package is now fetched from
|
||||
GitHub.
|
||||
|
||||
* Commands that send the region to the inferior process now deal with
|
||||
rectangular regions. See the documentation of 'ess-eval-region'
|
||||
for details. This only works on Emacs 25.1 and newer.
|
||||
|
||||
* ESS[R]: Improvements to interacting with iESS in non-R files.
|
||||
Interaction with inferior process in non-R files within packages
|
||||
(for instance C or C++ files) has been improved. This is a work in
|
||||
progress.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[JAGS]: *.jog and *.jmd files no longer automatically open in
|
||||
JAGS mode.
|
||||
|
||||
Many improvements to fontification:
|
||||
|
||||
* Improved customization for faces. ESS now provides custom faces
|
||||
for (nearly) all faces used and places face customization options
|
||||
into their own group. Users can customize these options using 'M-x
|
||||
customize-group RET ess-faces'.
|
||||
|
||||
* Many new keywords were added to 'ess-R-keywords' and
|
||||
'ess-R-modifiers'. See the documentation for details.
|
||||
|
||||
* ESS[R]: 'in' is now only fontified when inside a 'for' construct.
|
||||
This avoids spurious fontification, especially in the output buffer
|
||||
where 'in' is a common English word.
|
||||
|
||||
* ESS: Font-lock keywords are now generated lazily. That means you
|
||||
can now add or remove keywords from variables like 'ess-R-keywords'
|
||||
in your Emacs configuration file after loading ESS (i.e. in the
|
||||
':config' section for 'use-package' users).
|
||||
|
||||
* ESS[R]: Fontification of roxygen '@param' keywords now supports
|
||||
comma-separated parameters.
|
||||
|
||||
* ESS[R]: Certain keywords are only fontified if followed by a
|
||||
parenthesis. Function-like keywords such as 'if ()' or 'stop()'
|
||||
are no longer fontified as keyword if not followed by an opening
|
||||
parenthesis. The same holds for search path modifiers like
|
||||
'library()' or 'require()'.
|
||||
|
||||
* ESS[R]: Fixed fontification toggling. Especially certain syntactic
|
||||
elements such as '%op%' operators and backquoted function
|
||||
definitions.
|
||||
|
||||
* ESS[R]: 'ess-font-lock-toggle-keyword' can be called interactively.
|
||||
This command asks with completion for a font-lock group to toggle.
|
||||
This functionality is equivalent to the font-lock menu.
|
||||
|
||||
Notable bug fixes:
|
||||
|
||||
* 'prettify-symbols-mode' no longer breaks indentation. This is
|
||||
accomplished by having the pretty symbols occupy the same number of
|
||||
characters as their non-pretty cousins. You may customize the new
|
||||
variable 'ess-r-prettify-symbols' to control this behavior.
|
||||
|
||||
* ESS: Inferior process buffers are now always displayed on startup.
|
||||
Additionally, they don't hang Emacs on failures.
|
||||
|
||||
Obsolete libraries, functions, and variables:
|
||||
|
||||
* The 'ess-r-args.el' library has been obsoleted and will be removed
|
||||
in the next release. Use 'eldoc-mode' instead, which is on by
|
||||
default.
|
||||
|
||||
* Functions and options dealing with the smart assign key are
|
||||
obsolete. The following functions have been made obsolete and will
|
||||
be removed in the next release of ESS: 'ess-smart-S-assign',
|
||||
'ess-toggle-S-assign', 'ess-toggle-S-assign-key',
|
||||
'ess-disable-smart-S-assign'.
|
||||
|
||||
The variable 'ess-smart-S-assign-key' is now deprecated and will be
|
||||
removed in the next release. If you would like to continue using
|
||||
'_' for inserting assign in future releases, please bind
|
||||
'ess-insert-assign' in 'ess-mode-map' the normal way.
|
||||
|
||||
* ESS[S]: Variable 'ess-s-versions-list' is obsolete and ignored.
|
||||
Use 'ess-s-versions' instead. You may pass arguments by starting
|
||||
the inferior process with the universal argument.
|
||||
|
||||
Changes and New Features in 17.11:
|
||||
|
||||
* The ESS initialization process has been streamlined. You can now
|
||||
load the R and Stata modes independently from the rest of ESS. Just
|
||||
put '(require 'ess-r-mode)' or '(require 'ess-stata-mode)' in your
|
||||
init file. This is for experienced Emacs users as this requires
|
||||
setting up autoloads for '.R' files manually. We will keep
|
||||
maintaining 'ess-site' for easy loading of all ESS features.
|
||||
|
||||
* Reloading and quitting the process is now more robust. If no
|
||||
process is attached, ESS now switches automatically to one
|
||||
(prompting you for selection if there are several running).
|
||||
Reloading and quitting will now work during a debug session or when
|
||||
R is prompting for input (for instance after a crash). Finally,
|
||||
the window configuration is saved and restored after reloading to
|
||||
prevent the buffer of the new process from capturing the cursor.
|
||||
|
||||
* ESS[R]: New command 'ess-r-package-use-dir'. It sets the working
|
||||
directory of the current process to the current package directory.
|
||||
|
||||
* ESS[R] Lookup for references in inferior buffers has been improved.
|
||||
New variable 'ess-r-package-source-roots' contains package
|
||||
sub-directories which are searched recursively during the file
|
||||
lookup point. Directories in 'ess-tracebug-search-path' are now
|
||||
also searched recursively.
|
||||
|
||||
* ESS[R] Namespaced evaluation is now automatically enabled only in
|
||||
the 'R/' directory. This way ESS will not attempt to update
|
||||
function definitions from a package if you are working from e.g. a
|
||||
test file.
|
||||
|
||||
Changes and New Features in 16.10:
|
||||
|
||||
* ESS[R]: Syntax highlighting is now more consistent. Backquoted
|
||||
names are not fontified as strings (since they really are
|
||||
identifiers). Furthermore they are now correctly recognized when
|
||||
they are function definitions or function calls.
|
||||
* ESS[R]: Backquoted names and '%op%' operators are recognized as
|
||||
sexp. This is useful for code navigation, e.g. with 'C-M-f' and
|
||||
'C-M-b'.
|
||||
* ESS[R]: Integration of outline mode with roxygen examples fields.
|
||||
You can use outline mode's code folding commands to fold the
|
||||
examples field. This is especially nice to use with well
|
||||
documented packages with long examples set. Set
|
||||
'ess-roxy-fold-examples' to non-nil to automatically fold the
|
||||
examples field when you open a buffer.
|
||||
* ESS[R]: New experimental feature: syntax highlighting in roxygen
|
||||
examples fields. This is turned off by default. Set
|
||||
'ess-roxy-fontify-examples' to non-nil to try it out.
|
||||
* ESS[R]: New package development command 'ess-r-devtools-ask' bound
|
||||
to 'C-c C-w C-a'. It asks with completion for any devtools command
|
||||
that takes 'pkg' as argument.
|
||||
* ESS[R]: New command 'C-c C-e C-r' to reload the inferior process.
|
||||
Currently only implemented for R. The R method runs
|
||||
'inferior-ess-r-reload-hook' on reloading.
|
||||
* ESS[R]: 'ess-r-package-mode' is now activated in non-file buffers
|
||||
as well.
|
||||
|
||||
Bug fixes in 16.10:
|
||||
* ESS[R]: Fix broken (un)flagging for debugging inside packages
|
||||
* ESS[R]: Fixes (and improvements) in Package development
|
||||
* ESS[R]: Completion no longer produces '...=' inside 'list( )'.
|
||||
* ESS[R]: Better debugging and tracing in packages.
|
||||
* ESS[R]: Better detection of symbols at point.
|
||||
* ESS[R]: No more spurious warnings on deletion of temporary files.
|
||||
* ESS[julia]: help and completion work (better)
|
||||
* ESS[julia]: available via 'ess-remote'
|
||||
|
||||
Changes and New Features in 16.04:
|
||||
|
||||
* ESS[R]: 'developer' functionality has been refactored. The new
|
||||
user interface consists of a single command
|
||||
'ess-r-set-evaluation-env' bound by default to 'C-c C-t C-s'. Once
|
||||
an evaluation environment has been set with, all subsequent ESS
|
||||
evaluation will source the code into that environment. By default,
|
||||
for file within R packages the evaluation environment is set to the
|
||||
package environment. Set 'ess-r-package-auto-set-evaluation-env'
|
||||
to 'nil' to disable this.
|
||||
* ESS[R]: New 'ess-r-package-mode' This development mode provides
|
||||
features to make package development easier. Currently, most of
|
||||
the commands are based on the 'devtools' packages and are
|
||||
accessible with 'C-c C-w' prefix. See the documentation of
|
||||
'ess-r-package-mode' function for all available commands. With
|
||||
'C-u' prefix each command asks for extra arguments to the
|
||||
underlying devtools function. This mode is automatically enabled
|
||||
in all files within R packages and is indicated with '[pkg:NAME]'
|
||||
in the mode-line.
|
||||
* ESS[R]: Help lookup has been improved. It is now possible to get
|
||||
help for namespaced objects such as pkg::foobar. Furthermore, ESS
|
||||
recognizes more reliably when you change 'options('html_type')'.
|
||||
* ESS[R]: New specialized breakpoints for debugging magrittr pipes
|
||||
* ESS: ESS now implements a simple message passing interface to
|
||||
communicate between ESS and inferior process.
|
||||
|
||||
Bug fixes in 16.04:
|
||||
* ESS[R]: Roxygen blocks with backtics are now correctly filled
|
||||
* ESS[R]: Don't skip breakpoints in magrittr's 'debug_pipe'
|
||||
* ESS[R]: Error highlighting now understands 'testthat' type errors
|
||||
* ESS[Julia]: Added getwd and setwd generic commands
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Announce75
|
||||
Node: Latest Version1298
|
||||
Node: Installing from a third-party repository2241
|
||||
Node: Installing from source3192
|
||||
Node: Activating and Loading ESS4788
|
||||
Node: Check Installation5866
|
||||
Node: Current Features6090
|
||||
Node: Requirements7633
|
||||
Node: Mailing List8068
|
||||
Node: Reporting Bugs8774
|
||||
Node: Authors9654
|
||||
Node: License10338
|
||||
Node: New Features10988
|
||||
|
||||
End Tag Table
|
||||
19
lisp/ess/authors.info
Normal file
19
lisp/ess/authors.info
Normal file
@@ -0,0 +1,19 @@
|
||||
This is authors.info, produced by makeinfo version 6.5 from
|
||||
authors.texi.
|
||||
|
||||
* A.J. Rossini (mailto:blindglobe@gmail.com)
|
||||
* Richard M. Heiberger (mailto:rmh@temple.edu)
|
||||
* Kurt Hornik (mailto:Kurt.Hornik@R-project.org)
|
||||
* Martin Maechler (mailto:maechler@stat.math.ethz.ch)
|
||||
* Rodney A. Sparapani (mailto:rsparapa@mcw.edu)
|
||||
* Stephen Eglen (mailto:stephen@gnu.org)
|
||||
* Sebastian P. Luque (mailto:spluque@gmail.com)
|
||||
* Henning Redestig (mailto:henning.red@googlemail.com)
|
||||
* Vitalie Spinu (mailto:spinuvit@gmail.com)
|
||||
* Lionel Henry (mailto:lionel.hry@gmail.com)
|
||||
* J. Alexander Branham (mailto:alex.branham@gmail.com)
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
26
lisp/ess/bugrept.info
Normal file
26
lisp/ess/bugrept.info
Normal file
@@ -0,0 +1,26 @@
|
||||
This is bugrept.info, produced by makeinfo version 6.5 from
|
||||
bugrept.texi.
|
||||
|
||||
Please send bug reports, suggestions etc. to <ESS-bugs@r-project.org>,
|
||||
or post them on our github issue tracker
|
||||
(https://github.com/emacs-ess/ESS/issues)
|
||||
|
||||
The easiest way to do this is within Emacs by typing
|
||||
|
||||
'M-x ess-submit-bug-report'
|
||||
|
||||
This also gives the maintainers valuable information about your
|
||||
installation which may help us to identify or even fix the bug.
|
||||
|
||||
If Emacs reports an error, backtraces can help us debug the problem.
|
||||
Type "M-x set-variable RET debug-on-error RET t RET". Then run the
|
||||
command that causes the error and you should see a *Backtrace* buffer
|
||||
containing debug information; send us that buffer.
|
||||
|
||||
Note that comments, suggestions, words of praise and large cash
|
||||
donations are also more than welcome.
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
81
lisp/ess/credits.info
Normal file
81
lisp/ess/credits.info
Normal file
@@ -0,0 +1,81 @@
|
||||
This is credits.info, produced by makeinfo version 6.5 from
|
||||
credits.texi.
|
||||
|
||||
The ESS environment is built on the open-source projects of many
|
||||
contributors, dating back to 1989 where Doug Bates and Ed Kademan wrote
|
||||
S-mode to edit S and Splus files in GNU Emacs. Frank Ritter and Mike
|
||||
Meyer added features, creating version 2. Meyer and David Smith made
|
||||
further contributions, creating version 3. For version 4, David Smith
|
||||
provided significant enhancements to allow for powerful process
|
||||
interaction.
|
||||
|
||||
John Sall wrote GNU Emacs macros for SAS source code around 1990.
|
||||
Tom Cook added functions to submit jobs, review listing and log files,
|
||||
and produce basic views of a dataset, thus creating a SAS-mode which was
|
||||
distributed in 1994.
|
||||
|
||||
In 1994, A.J. Rossini extended S-mode to support XEmacs. Together
|
||||
with extensions written by Martin Maechler, this became version 4.7 and
|
||||
supported S, Splus, and R. In 1995, Rossini extended SAS-mode to work
|
||||
with XEmacs.
|
||||
|
||||
In 1997, Rossini merged S-mode and SAS-mode into a single Emacs
|
||||
package for statistical programming; the product of this marriage was
|
||||
called ESS version 5. Richard M. Heiberger designed the inferior mode
|
||||
for interactive SAS and SAS-mode was further integrated into ESS. Thomas
|
||||
Lumley's Stata mode, written around 1996, was also folded into ESS. More
|
||||
changes were made to support additional statistical languages,
|
||||
particularly XLispStat.
|
||||
|
||||
ESS initially worked only with Unix statistics packages that used
|
||||
standard-input and standard-output for both the command-line interface
|
||||
and batch processing. ESS could not communicate with statistical
|
||||
packages that did not use this protocol. This changed in 1998 when
|
||||
Brian Ripley demonstrated use of the Windows Dynamic Data Exchange (DDE)
|
||||
protocol with ESS. Heiberger then used DDE to provide interactive
|
||||
interfaces for Windows versions of Splus. In 1999, Rodney A. Sparapani
|
||||
and Heiberger implemented SAS batch for ESS relying on files, rather
|
||||
than standard-input/standard-output, for Unix, Windows and Mac. In
|
||||
2001, Sparapani added BUGS batch file processing to ESS for Unix and
|
||||
Windows.
|
||||
|
||||
* The multiple process code, and the idea for
|
||||
'ess-eval-line-and-next-line' are by Rod Ball.
|
||||
|
||||
* Thanks to Doug Bates for many useful suggestions.
|
||||
|
||||
* Thanks to Martin Maechler for reporting and fixing bugs, providing
|
||||
many useful comments and suggestions, and for maintaining the ESS
|
||||
mailing lists.
|
||||
|
||||
* Thanks to Frank Ritter for updates, particularly the menu code, and
|
||||
invaluable comments on the manual.
|
||||
|
||||
* Thanks to Ken'ichi Shibayama for his excellent indenting code, and
|
||||
many comments and suggestions.
|
||||
|
||||
* Thanks to Aki Vehtari for adding interactive BUGS support.
|
||||
|
||||
* Thanks to Brendan Halpin for bug-fixes and updates to Stata-mode.
|
||||
|
||||
* Last, but definitely not least, thanks to the many ESS users and
|
||||
contributors to the ESS mailing lists.
|
||||
|
||||
_ESS_ is being developed and currently maintained by
|
||||
|
||||
* A.J. Rossini (mailto:blindglobe@gmail.com)
|
||||
* Richard M. Heiberger (mailto:rmh@temple.edu)
|
||||
* Kurt Hornik (mailto:Kurt.Hornik@R-project.org)
|
||||
* Martin Maechler (mailto:maechler@stat.math.ethz.ch)
|
||||
* Rodney A. Sparapani (mailto:rsparapa@mcw.edu)
|
||||
* Stephen Eglen (mailto:stephen@gnu.org)
|
||||
* Sebastian P. Luque (mailto:spluque@gmail.com)
|
||||
* Henning Redestig (mailto:henning.red@googlemail.com)
|
||||
* Vitalie Spinu (mailto:spinuvit@gmail.com)
|
||||
* Lionel Henry (mailto:lionel.hry@gmail.com)
|
||||
* J. Alexander Branham (mailto:alex.branham@gmail.com)
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
42
lisp/ess/currfeat.info
Normal file
42
lisp/ess/currfeat.info
Normal file
@@ -0,0 +1,42 @@
|
||||
This is currfeat.info, produced by makeinfo version 6.5 from
|
||||
currfeat.texi.
|
||||
|
||||
* Languages Supported:
|
||||
* S family (R, S, and S+ AKA S-PLUS)
|
||||
* SAS
|
||||
* BUGS/JAGS
|
||||
* Stata
|
||||
* Julia
|
||||
* Editing source code (S family, SAS, BUGS/JAGS, Stata, Julia)
|
||||
* Syntactic indentation and highlighting of source code
|
||||
* Partial evaluation of code
|
||||
* Loading and error-checking of code
|
||||
* Source code revision maintenance
|
||||
* Batch execution (SAS, BUGS/JAGS)
|
||||
* Use of imenu to provide links to appropriate functions
|
||||
* Interacting with the process (S family, SAS, Stata, Julia)
|
||||
* Command-line editing
|
||||
* Searchable Command history
|
||||
* Command-line completion of S family object names and file
|
||||
names
|
||||
* Quick access to object lists and search lists
|
||||
* Transcript recording
|
||||
* Interface to the help system
|
||||
* Transcript manipulation (S family, Stata)
|
||||
* Recording and saving transcript files
|
||||
* Manipulating and editing saved transcripts
|
||||
* Re-evaluating commands from transcript files
|
||||
* Interaction with Help Pages and other Documentation (R)
|
||||
* Fast Navigation
|
||||
* Sending Examples to running ESS process.
|
||||
* Fast Transfer to Further Help Pages
|
||||
* Help File Editing (R)
|
||||
* Syntactic indentation and highlighting of source code.
|
||||
* Sending Examples to running ESS process.
|
||||
* Previewing
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
19
lisp/ess/dir
Normal file
19
lisp/ess/dir
Normal file
@@ -0,0 +1,19 @@
|
||||
This is the file .../info/dir, which contains the
|
||||
topmost node of the Info hierarchy, called (dir)Top.
|
||||
The first time you invoke Info you start off looking at this node.
|
||||
|
||||
File: dir, Node: Top, This is the top of the INFO tree
|
||||
|
||||
This (the Directory node) gives a menu of major topics.
|
||||
Typing "q" exits, "?" lists all Info commands, "d" returns here,
|
||||
"h" gives a primer for first-timers,
|
||||
"mEmacs<Return>" visits the Emacs manual, etc.
|
||||
|
||||
In Emacs, you can click mouse button 2 on a menu item or cross reference
|
||||
to select it.
|
||||
|
||||
* Menu:
|
||||
|
||||
Emacs
|
||||
* ESS: (ess). Emacs Speaks Statistics (R/S/S+, SAS,
|
||||
BUGS/JAGS and Stata).
|
||||
298
lisp/ess/ess-bugs-d.el
Normal file
298
lisp/ess/ess-bugs-d.el
Normal file
@@ -0,0 +1,298 @@
|
||||
;;; ess-bugs-d.el --- ESS[BUGS] dialect -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2008-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Rodney Sparapani
|
||||
;; Maintainer: ESS-help <ess-help@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-bugs-l)
|
||||
(require 'ess-utils)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-mode)
|
||||
|
||||
(defvar ess-bugs-command "OpenBUGS" "Default BUGS program in PATH.")
|
||||
(make-local-variable 'ess-bugs-command)
|
||||
|
||||
(defvar ess-bugs-monitor '("") "Default list of variables to monitor.")
|
||||
(make-local-variable 'ess-bugs-monitor)
|
||||
|
||||
(defvar ess-bugs-thin 1 "Default thinning parameter.")
|
||||
(make-local-variable 'ess-bugs-thin)
|
||||
|
||||
(defvar ess-bugs-chains 1 "Default number of chains.")
|
||||
(make-local-variable 'ess-bugs-chains)
|
||||
|
||||
(defvar ess-bugs-burnin 10000 "Default burn-in.")
|
||||
(make-local-variable 'ess-bugs-burnin)
|
||||
|
||||
(defvar ess-bugs-update 10000 "Default number of updates after burnin.")
|
||||
(make-local-variable 'ess-bugs-update)
|
||||
|
||||
(defvar ess-bugs-system nil "Default whether BUGS recognizes the system command.")
|
||||
|
||||
(defvar ess-bugs-font-lock-keywords
|
||||
(list
|
||||
;; .bug files
|
||||
(cons "#.*\n" font-lock-comment-face)
|
||||
|
||||
(cons "^[ \t]*\\(model\\|var\\)\\>"
|
||||
font-lock-keyword-face)
|
||||
|
||||
(cons (concat "\\<d\\(bern\\|beta\\|bin\\|cat\\|chisq\\|"
|
||||
"dexp\\|dirch\\|exp\\|\\(gen[.]\\)?gamma\\|hyper\\|"
|
||||
"interval\\|lnorm\\|logis\\|mnorm\\|mt\\|multi\\|"
|
||||
"negbin\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
|
||||
"unif\\|weib\\|wish\\)[ \t\n]*(")
|
||||
font-lock-constant-face)
|
||||
|
||||
(cons (concat "\\<\\(abs\\|cos\\|C\\|dim\\|\\(i\\)?cloglog\\|equals\\|"
|
||||
"exp\\|for\\|inprod\\|interp[.]line\\|inverse\\|length\\|"
|
||||
"\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|max\\|mean\\|"
|
||||
"mexp\\|min\\|phi\\|pow\\|probit\\|prod\\|rank\\|round\\|"
|
||||
"sd\\|sin\\|sort\\|sqrt\\|step\\|sum\\|t\\|trunc\\|T\\)[ \t\n]*(")
|
||||
font-lock-function-name-face)
|
||||
|
||||
;; .bmd files
|
||||
(cons (concat (regexp-opt '(
|
||||
"dicClear" "dicSet" "dicStats"
|
||||
"infoMemory" "infoModules" "infoNodeMethods"
|
||||
"infoNodeTypes" "infoNodeValues"
|
||||
"infoUpdatersbyDepth" "infoUpdatersbyName"
|
||||
"modelCheck" "modelCompile" "modelData"
|
||||
"modelDisable" "modelEnable" "modelGenInits"
|
||||
"modelInits" "modelPrecision" "modelQuit"
|
||||
"modelSaveState" "modelSetAP" "modelSetIts"
|
||||
"modelSetOR" "modelSetRN" "modelUpdate"
|
||||
"ranksClear" "ranksSet" "ranksStats"
|
||||
"samplesAutoC" "samplesBgr" "samplesCoda"
|
||||
"samplesDensity" "samplesHistory" "samplesSet"
|
||||
"sampleStats" "samplesThin"
|
||||
"summaryClear" "summarySet" "summaryStats"
|
||||
) 'words) "(")
|
||||
font-lock-function-name-face)
|
||||
|
||||
(cons (concat (regexp-opt '("Local Variables" "End") 'words) ":")
|
||||
font-lock-keyword-face)
|
||||
)
|
||||
"ESS[BUGS]: Font lock keywords."
|
||||
)
|
||||
|
||||
(defun ess-bugs-switch-to-suffix (suffix &optional bugs-chains bugs-monitor bugs-thin
|
||||
bugs-burnin bugs-update)
|
||||
"ESS[BUGS]: Switch to file with suffix."
|
||||
(find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
|
||||
|
||||
(if (equal 0 (buffer-size)) (progn
|
||||
(if (equal ".bug" suffix) (progn
|
||||
;(insert "var ;\n")
|
||||
(insert "model {\n")
|
||||
(insert " for (i in 1:N) {\n \n")
|
||||
(insert " }\n")
|
||||
(insert "}\n")
|
||||
(insert "#Local Variables" ":\n")
|
||||
; (insert "#enable-local-variables: :all\n")
|
||||
(insert "#ess-bugs-chains:1\n")
|
||||
(insert "#ess-bugs-monitor:(\"\")\n")
|
||||
(insert "#ess-bugs-thin:1\n")
|
||||
(insert "#ess-bugs-burnin:10000\n")
|
||||
(insert "#ess-bugs-update:10000\n")
|
||||
(insert "#End:\n")
|
||||
))
|
||||
|
||||
(if (equal ".bmd" suffix) (let
|
||||
((ess-bugs-temp-chains "") (ess-bugs-temp-monitor ""))
|
||||
|
||||
(if bugs-chains (setq ess-bugs-chains bugs-chains))
|
||||
(if bugs-monitor (setq ess-bugs-monitor bugs-monitor))
|
||||
(if bugs-thin (setq ess-bugs-thin bugs-thin))
|
||||
|
||||
(setq ess-bugs-temp-chains
|
||||
(concat "modelCompile(" (format "%d" ess-bugs-chains) ")\n"))
|
||||
|
||||
(setq bugs-chains ess-bugs-chains)
|
||||
|
||||
(while (< 0 bugs-chains)
|
||||
(setq ess-bugs-temp-chains
|
||||
(concat ess-bugs-temp-chains
|
||||
"modelInits('" ess-bugs-file-root
|
||||
".##" (format "%d" bugs-chains) "', "
|
||||
(format "%d" bugs-chains) ")\n"))
|
||||
(setq bugs-chains (- bugs-chains 1)))
|
||||
|
||||
(setq ess-bugs-temp-monitor "")
|
||||
|
||||
(while (and (listp ess-bugs-monitor) (consp ess-bugs-monitor))
|
||||
(if (not (string-equal "" (car ess-bugs-monitor)))
|
||||
(setq ess-bugs-temp-monitor
|
||||
(concat ess-bugs-temp-monitor "samplesSet('"
|
||||
(car ess-bugs-monitor)
|
||||
;", thin(" (format "%d" ess-bugs-thin)
|
||||
"')\n")))
|
||||
(setq ess-bugs-monitor (cdr ess-bugs-monitor)))
|
||||
|
||||
(insert "modelCheck('" ess-bugs-file-root ".bug')\n")
|
||||
(insert "modelData('" ess-bugs-file-root ".bdt')\n")
|
||||
(insert (ess-replace-in-string ess-bugs-temp-chains "##" "in"))
|
||||
(insert "modelGenInits()\n")
|
||||
(insert "modelUpdate(" (format "%d" bugs-burnin) ")\n")
|
||||
;(insert "modelUpdate(" (format "%d" (* bugs-thin bugs-burnin)) ")\n")
|
||||
(insert ess-bugs-temp-monitor)
|
||||
(insert "modelUpdate(" (format "%d" (* bugs-thin bugs-update)) ")\n")
|
||||
; (insert (ess-replace-in-string
|
||||
; (ess-replace-in-string ess-bugs-temp-chains
|
||||
; "modelCompile([0-9]+)" "#") "##" "to"))
|
||||
|
||||
(if (< 1 bugs-thin) (insert "samplesThin(" (format "%d" bugs-thin) ")\n"))
|
||||
|
||||
(insert "samplesCoda('*', '" ess-bugs-file-root "')\n")
|
||||
|
||||
; (if ess-bugs-system (progn
|
||||
; (insert "system rm -f " ess-bugs-file-root ".ind\n")
|
||||
; (insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
|
||||
|
||||
; (setq bugs-chains ess-bugs-chains)
|
||||
|
||||
; (while (< 0 bugs-chains)
|
||||
; (setq ess-bugs-temp-chain (format "%d" bugs-chains))
|
||||
|
||||
; ;.txt not recognized by BOA and impractical to over-ride
|
||||
; (insert "system rm -f " ess-bugs-file-root ess-bugs-temp-chain ".out\n")
|
||||
; (insert "system ln -s " ess-bugs-file-root "chain" ess-bugs-temp-chain ".txt "
|
||||
; ess-bugs-file-root ess-bugs-temp-chain ".out\n")
|
||||
; (setq bugs-chains (- bugs-chains 1)))))
|
||||
|
||||
(insert "modelQuit()\n")
|
||||
(insert "Local Variables" ":\n")
|
||||
; (insert "enable-local-variables: :all\n")
|
||||
(insert "ess-bugs-chains:" (format "%d" ess-bugs-chains) "\n")
|
||||
(insert "ess-bugs-command:\"" ess-bugs-command "\"\n")
|
||||
(insert "End:\n")
|
||||
))
|
||||
))
|
||||
)
|
||||
|
||||
(defun ess-bugs-na-bmd (bugs-command)
|
||||
"ESS[BUGS]: Perform the Next-Action for .bmd."
|
||||
;(ess-save-and-set-local-variables)
|
||||
(if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bmd")
|
||||
;else
|
||||
(shell)
|
||||
(ess-sleep)
|
||||
|
||||
(when (and (when (fboundp 'w32-shell-dos-semantics)
|
||||
(w32-shell-dos-semantics))
|
||||
(string-equal ":" (substring ess-bugs-file 1 2)))
|
||||
(insert (substring ess-bugs-file 0 2)))
|
||||
|
||||
(comint-send-input)
|
||||
(insert "cd \"" ess-bugs-file-dir "\"")
|
||||
(comint-send-input)
|
||||
|
||||
; (let ((ess-bugs-temp-chains ""))
|
||||
;
|
||||
; (while (< 0 bugs-chains)
|
||||
; (setq ess-bugs-temp-chains
|
||||
; (concat (format "%d " bugs-chains) ess-bugs-temp-chains))
|
||||
; (setq bugs-chains (- bugs-chains 1)))
|
||||
|
||||
;; (insert "echo '"
|
||||
;; ess-bugs-batch-pre-command " " bugs-command " < "
|
||||
;; ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
|
||||
;; ess-bugs-batch-post-command "' > " ess-bugs-file-root ".bsh")
|
||||
;; (comint-send-input)
|
||||
|
||||
;; (insert "at -f " ess-bugs-file-root ".bsh now")
|
||||
|
||||
;; (comint-send-input)
|
||||
|
||||
(insert "echo '"
|
||||
ess-bugs-batch-pre-command " " bugs-command " < "
|
||||
ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
|
||||
ess-bugs-batch-post-command "' | at now")
|
||||
|
||||
(comint-send-input)
|
||||
))
|
||||
|
||||
(defun ess-bugs-na-bug ()
|
||||
"ESS[BUGS]: Perform Next-Action for .bug"
|
||||
|
||||
(if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bug")
|
||||
;else
|
||||
(ess-save-and-set-local-variables)
|
||||
(ess-bugs-switch-to-suffix ".bmd"
|
||||
ess-bugs-chains ess-bugs-monitor ess-bugs-thin ess-bugs-burnin ess-bugs-update))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-bugs-mode ess-mode "ESS[BUGS]"
|
||||
"Major mode for BUGS."
|
||||
(setq-local comment-start "#")
|
||||
(setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
|
||||
(setq ess-language "S") ; mimic S for ess-smart-underscore
|
||||
(unless (when (fboundp 'w32-shell-dos-semantics)
|
||||
(w32-shell-dos-semantics))
|
||||
(add-hook 'comint-output-filter-functions 'ess-bugs-exit-notify-sh)))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode))
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode))
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode))
|
||||
|
||||
(defun ess-sci-to-dec ()
|
||||
"For BUGS/S family: Express +/-0.000E+/-0 or +/-0.0e+/-00 as a decimal."
|
||||
(interactive)
|
||||
(setq buffer-read-only nil)
|
||||
(save-excursion (goto-char 0)
|
||||
(save-match-data (let ((ess-temp-replacement-string nil)
|
||||
(ess-temp-replacement-9 0)
|
||||
(ess-temp-replacement-diff 0))
|
||||
(while (search-forward-regexp "-?[0-9][.][0-9][0-9]?[0-9]?[Ee][+-][0-9][0-9]?" nil t)
|
||||
(setq ess-temp-replacement-string
|
||||
(int-to-string (string-to-number (match-string 0))))
|
||||
(setq ess-temp-replacement-diff (- (match-end 0) (match-beginning 0)))
|
||||
(save-match-data
|
||||
(setq ess-temp-replacement-9
|
||||
(string-match "99999999999$" ess-temp-replacement-string))
|
||||
|
||||
(if (not ess-temp-replacement-9)
|
||||
(setq ess-temp-replacement-9
|
||||
(string-match "000000000001$" ess-temp-replacement-string))))
|
||||
|
||||
(if ess-temp-replacement-9
|
||||
(setq ess-temp-replacement-string
|
||||
(substring ess-temp-replacement-string 0 ess-temp-replacement-9)))
|
||||
|
||||
(setq ess-temp-replacement-diff
|
||||
(- ess-temp-replacement-diff (string-width ess-temp-replacement-string)))
|
||||
|
||||
(while (> ess-temp-replacement-diff 0)
|
||||
(setq ess-temp-replacement-string (concat ess-temp-replacement-string " "))
|
||||
(setq ess-temp-replacement-diff (- ess-temp-replacement-diff 1)))
|
||||
|
||||
(replace-match ess-temp-replacement-string))))))
|
||||
|
||||
(provide 'ess-bugs-d)
|
||||
|
||||
;;; ess-bugs-d.el ends here
|
||||
290
lisp/ess/ess-bugs-l.el
Normal file
290
lisp/ess/ess-bugs-l.el
Normal file
@@ -0,0 +1,290 @@
|
||||
;;; ess-bugs-l.el --- ESS[BUGS] languages -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Rodney Sparapani
|
||||
;; Maintainer: ESS-help <ess-help@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'shell)
|
||||
(require 'ess-utils)
|
||||
(defvar ess-bugs-command)
|
||||
(defvar ess-bugs-chains)
|
||||
(defvar ess-jags-command)
|
||||
(defvar ess-jags-chains)
|
||||
(defvar ess-bugs-default-bins)
|
||||
|
||||
(declare-function ess-bugs-na-bug "ess-bugs-d")
|
||||
(declare-function ess-jags-na-bug "ess-jags-d")
|
||||
(declare-function ess-bugs-na-bmd "ess-bugs-d")
|
||||
(declare-function ess-jags-na-jmd "ess-jags-d")
|
||||
|
||||
(defgroup ess-bugs nil
|
||||
"ESS: BUGS."
|
||||
:group 'ess
|
||||
:prefix "ess-")
|
||||
|
||||
(defcustom ess-bugs-batch-method
|
||||
(if (and ess-microsoft-p
|
||||
(fboundp 'w32-shell-dos-semantics)
|
||||
(w32-shell-dos-semantics))
|
||||
'dos
|
||||
'sh)
|
||||
"Method used by `ess-bugs-batch'.
|
||||
The default is based on the value of the Emacs variable `system-type'
|
||||
and, on Windows machines, the function `w32-shell-dos-semantics'.
|
||||
'sh if *shell* runs a Bourne-like or a C-like Unix shell
|
||||
'dos if *shell* runs a DOS-like Windows shell
|
||||
|
||||
Unix users will get 'sh by default.
|
||||
|
||||
Windows users running a DOS-like *shell* will get 'dos by default,
|
||||
while those running a Unix-like *shell* will get 'sh by default.
|
||||
|
||||
Users whose default is not 'sh, but are accessing a remote machine with
|
||||
`telnet' or `ssh', should have the following in their init file:
|
||||
(setq-default ess-bugs-batch-method 'sh)"
|
||||
:group 'ess-bugs
|
||||
:type '(choice (const 'sh :tag "Bourne/C-like Unix Shell")
|
||||
(const 'dos :tag "DOS-like Windows shell")))
|
||||
|
||||
(defcustom ess-bugs-batch-post-command
|
||||
(if (equal ess-bugs-batch-method 'sh) "&" " ")
|
||||
"ESS[BUGS]: Modifiers at the end of the batch BUGS command line."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
(defcustom ess-bugs-batch-pre-command
|
||||
(if (equal ess-bugs-batch-method 'sh) "nohup nice time"
|
||||
(if ess-microsoft-p "start"))
|
||||
"ESS[BUGS]: Modifiers at the beginning of the batch BUGS command line."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
|
||||
(defcustom ess-bugs-default-burn-in "500"
|
||||
"ESS[BUGS]: Burn-in iterations to discard."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
(defcustom ess-bugs-default-update "1000"
|
||||
"ESS[BUGS]: Iterations to store."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
(defvar ess-bugs-batch-command ";"
|
||||
"ESS[BUGS]: The name of the command to run BUGS in batch mode."
|
||||
)
|
||||
|
||||
(defvar ess-bugs-file "."
|
||||
"ESS[BUGS]: BUGS file with PATH.")
|
||||
|
||||
(defvar ess-bugs-file-root "."
|
||||
"ESS[BUGS]: Root of BUGS file.")
|
||||
|
||||
(defvar ess-bugs-file-suffix "."
|
||||
"ESS[BUGS]: Suffix of BUGS file.")
|
||||
|
||||
(defvar ess-bugs-file-dir "."
|
||||
"ESS[BUGS]: Directory of BUGS file.")
|
||||
|
||||
(defvar ess-bugs-file-data "..."
|
||||
"ESS[BUGS]: BUGS data file.")
|
||||
|
||||
(defcustom ess-bugs-inits-suffix ".in"
|
||||
"ESS[BUGS]: BUGS init file suffix."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
(defcustom ess-bugs-data-suffix ".dat"
|
||||
"ESS[BUGS]: BUGS data file suffix."
|
||||
:group 'ess-bugs
|
||||
:type 'string
|
||||
)
|
||||
|
||||
(defcustom ess-bugs-mode-hook nil
|
||||
"ESS[BUGS]: List of functions to call upon entering mode."
|
||||
:group 'ess-bugs
|
||||
:type 'hook)
|
||||
|
||||
(defvar ess-bugs-monitor-vars " "
|
||||
"ESS[BUGS]: List of BUGS variables to be written out to a file.")
|
||||
|
||||
(defvar ess-bugs-stats-vars " "
|
||||
"ESS[BUGS]: List of BUGS variables to be summarized with statistics.")
|
||||
|
||||
(defvar ess-bugs-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (quote [f2]) #'ess-revert-wisely)
|
||||
(define-key map "\C-c\C-c" #'ess-bugs-next-action)
|
||||
(define-key map "=" #'ess-bugs-hot-arrow)
|
||||
(define-key map "_" #'ess-bugs-hot-arrow)
|
||||
map)
|
||||
"ESS[BUGS]: Keymap for mode.")
|
||||
|
||||
(defvar ess-bugs-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?\\ "." table)
|
||||
(modify-syntax-entry ?# "<" table)
|
||||
(modify-syntax-entry ?\n ">" table)
|
||||
(modify-syntax-entry ?\( "()" table)
|
||||
(modify-syntax-entry ?\) ")(" table)
|
||||
(modify-syntax-entry ?. "w" table)
|
||||
table)
|
||||
"ESS[BUGS]: Syntax table for mode.")
|
||||
|
||||
(defun ess-bugs-file ()
|
||||
"ESS[BUGS]: Set internal variables dealing with BUGS files.
|
||||
Set `ess-bugs-file', `ess-bugs-file-root', `ess-bugs-file-suffix'
|
||||
and `ess-bugs-file-dir'."
|
||||
(let ((ess-bugs-temp-string (buffer-name)))
|
||||
(setq ess-bugs-file (expand-file-name ess-bugs-temp-string))
|
||||
(setq ess-bugs-file-dir
|
||||
(convert-standard-filename (file-name-directory ess-bugs-file)))
|
||||
(setq ess-bugs-file-root
|
||||
(file-name-nondirectory (file-name-sans-extension ess-bugs-file)))
|
||||
|
||||
(if (fboundp 'file-name-extension)
|
||||
(setq ess-bugs-file-suffix (file-name-extension ess-bugs-temp-string))
|
||||
;;else
|
||||
(setq ess-bugs-file-suffix (car (last (split-string ess-bugs-temp-string "[.]")))))
|
||||
|
||||
(setq ess-bugs-file-suffix
|
||||
(downcase (car (split-string (concat "." ess-bugs-file-suffix) "[<]"))))
|
||||
|
||||
(setq ess-bugs-file (concat ess-bugs-file-dir ess-bugs-file-root ess-bugs-file-suffix))
|
||||
)
|
||||
)
|
||||
|
||||
(defun ess-bugs-exit-notify-sh (string)
|
||||
"ESS[BUGS]: Detect completion or failure of submitted job and notify the user."
|
||||
(let* ((exit-done "\\[[0-9]+\\] *\\+* *\\(Exit\\|Done\\)[^\r\n]*")
|
||||
(beg (string-match exit-done string)))
|
||||
(if beg (message "%s" (substring string beg (match-end 0))))))
|
||||
|
||||
(defun ess-bugs-hot-arrow ()
|
||||
"ESS[BUGS]: Substitute <- for = key press"
|
||||
(interactive)
|
||||
(insert " <- "))
|
||||
|
||||
(defun ess-bugs-next-action ()
|
||||
"ESS[BUGS/JAGS]: Perform the appropriate next action."
|
||||
(interactive)
|
||||
(ess-bugs-file)
|
||||
|
||||
(cond ((equal ".bug" ess-bugs-file-suffix) (ess-bugs-na-bug))
|
||||
((equal ".jag" ess-bugs-file-suffix) (ess-jags-na-bug))
|
||||
((equal ".bmd" ess-bugs-file-suffix)
|
||||
(ess-save-and-set-local-variables)
|
||||
(ess-bugs-na-bmd ess-bugs-command ess-bugs-chains))
|
||||
((equal ".jmd" ess-bugs-file-suffix)
|
||||
(ess-save-and-set-local-variables)
|
||||
(ess-jags-na-jmd ess-jags-command ess-jags-chains)))
|
||||
)
|
||||
|
||||
(defun ess-bugs-sci-to-round-4-dp ()
|
||||
"ESS[BUGS]: round output from +/-0.000E+/-0 to 4 decimal places."
|
||||
(interactive)
|
||||
(setq buffer-read-only nil)
|
||||
(save-excursion (goto-char 0)
|
||||
(save-match-data (let ((ess-bugs-replacement-string nil)
|
||||
(ess-bugs-replacement-9 0)
|
||||
(ess-bugs-replacement-diff 0))
|
||||
(while (search-forward-regexp "-?[0-9][.][0-9][0-9][0-9]E[+-][0-9]" nil t)
|
||||
(setq ess-bugs-replacement-string
|
||||
(int-to-string (string-to-number (match-string 0))))
|
||||
(setq ess-bugs-replacement-diff (- (match-end 0) (match-beginning 0)))
|
||||
(save-match-data
|
||||
(setq ess-bugs-replacement-9
|
||||
(string-match "99999999999$" ess-bugs-replacement-string))
|
||||
|
||||
(if (not ess-bugs-replacement-9)
|
||||
(setq ess-bugs-replacement-9
|
||||
(string-match "000000000001$" ess-bugs-replacement-string))))
|
||||
|
||||
(if ess-bugs-replacement-9
|
||||
(setq ess-bugs-replacement-string
|
||||
(substring ess-bugs-replacement-string 0 ess-bugs-replacement-9)))
|
||||
|
||||
(setq ess-bugs-replacement-diff
|
||||
(- ess-bugs-replacement-diff (string-width ess-bugs-replacement-string)))
|
||||
|
||||
(while (> ess-bugs-replacement-diff 0)
|
||||
(setq ess-bugs-replacement-string (concat ess-bugs-replacement-string " "))
|
||||
(setq ess-bugs-replacement-diff (- ess-bugs-replacement-diff 1)))
|
||||
|
||||
(replace-match ess-bugs-replacement-string))))))
|
||||
|
||||
;;; ESS[BUGS-Shell] for running BUGS interactively
|
||||
(defgroup ess-bugs-shell nil
|
||||
"ESS: BUGS-Shell."
|
||||
:group 'ess-bugs
|
||||
:prefix "ess-")
|
||||
|
||||
(defcustom ess-bugs-shell-buffer-name "BUGS"
|
||||
"ESS[BUGS-Shell]: The name of the BUGS-Shell buffer."
|
||||
:group 'ess-bugs-shell
|
||||
:type 'string)
|
||||
|
||||
(defcustom ess-bugs-shell-command "OpenBUGS"
|
||||
"ESS[BUGS-Shell]: The name of the command to run BUGS interactively.
|
||||
|
||||
Set to the name of the batch BUGS script that comes with ESS or
|
||||
to the name of BUGS command. Make sure it is in your PATH or
|
||||
add path to the command name."
|
||||
:group 'ess-bugs-shell
|
||||
:type 'string)
|
||||
|
||||
(defcustom ess-bugs-shell-default-output-file-root "bugs"
|
||||
"ESS[BUGS-Shell]: Default value for the root of output files."
|
||||
:group 'ess-bugs-shell
|
||||
:type 'string)
|
||||
|
||||
(defcustom ess-bugs-shell-mode-hook nil
|
||||
"ESS[BUGS-Shell]: List of functions to call upon entering mode."
|
||||
:group 'ess-bugs-shell
|
||||
:type 'hook)
|
||||
|
||||
(defun ess-bugs-shell ()
|
||||
"Create a buffer with BUGS running as a subprocess."
|
||||
(interactive)
|
||||
(pop-to-buffer-same-window (concat "*" ess-bugs-shell-buffer-name "*"))
|
||||
(make-comint ess-bugs-shell-buffer-name ess-bugs-shell-command nil
|
||||
ess-bugs-default-bins ess-bugs-shell-default-output-file-root)
|
||||
(comint-mode)
|
||||
(setq shell-dirtrackp t
|
||||
major-mode 'bugs-shell-mode
|
||||
mode-name "ESS[BUGS-Shell]"
|
||||
comint-prompt-regexp "^Bugs> *")
|
||||
(make-local-variable 'font-lock-defaults)
|
||||
(setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
|
||||
(run-mode-hooks 'ess-bugs-shell-mode-hook)
|
||||
)
|
||||
|
||||
(provide 'ess-bugs-l)
|
||||
|
||||
;;; ess-bugs-l.el ends here
|
||||
2474
lisp/ess/ess-custom.el
Normal file
2474
lisp/ess/ess-custom.el
Normal file
File diff suppressed because it is too large
Load Diff
8
lisp/ess/ess-defs.info
Normal file
8
lisp/ess/ess-defs.info
Normal file
@@ -0,0 +1,8 @@
|
||||
This is ess-defs.info, produced by makeinfo version 6.5 from
|
||||
ess-defs.texi.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
595
lisp/ess/ess-gretl.el
Normal file
595
lisp/ess/ess-gretl.el
Normal file
@@ -0,0 +1,595 @@
|
||||
;; ess-gretl.el --- ESS gretl mode and inferior interaction -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2012-2020 Free Software Foundation, Inc.
|
||||
;; Author: Ahmadou Dicko, Spinu Vitalie and Allin Cottrell
|
||||
;; Maintainer: ESS Core Team <ESS-core@r-project.org>
|
||||
;; Created: 01-10-2012 (ESS 12.09)
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
;; start the inferior with M-x gretl.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'compile); for compilation-* below
|
||||
(require 'ess-r-mode)
|
||||
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.inp\\'" . ess-gretl-mode))
|
||||
|
||||
|
||||
(defvar gretl-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?_ "w" table) ; underscores in words
|
||||
(modify-syntax-entry ?@ "w" table)
|
||||
(modify-syntax-entry ?# "<" table) ; # single-line comment start
|
||||
(modify-syntax-entry ?\n ">" table) ; \n single-line comment end
|
||||
(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 `ess-gretl-mode'.")
|
||||
|
||||
;; syntax table that holds within strings
|
||||
(defvar ess-gretl-mode-string-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
table)
|
||||
"Syntax table for `ess-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-string-regex
|
||||
;; "\"[^\"]*?\\(\\(\\\\\\\\\\)*\\\\\"[^\"]*?\\)*\"")
|
||||
|
||||
(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.")
|
||||
|
||||
;; (defconst ess-function-call-regexp
|
||||
;; "\\s\"?\\(\\(\\sw\\|\\s_\\)+\\(<-\\)?\\)\\s\"?*\\s-*("
|
||||
;; "Regexp for function names")
|
||||
|
||||
(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"
|
||||
"while" "const" "3sls" "liml" "fiml"
|
||||
"sur" "params" "deriv" "orthog" "weights" "series" "scalar")
|
||||
"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" "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)
|
||||
; not a keyword if used as a field name, X.word, or quoted, :word
|
||||
(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-keywords
|
||||
(list
|
||||
;; Fontify all builtin keywords.
|
||||
(cons (concat "\\<\\("
|
||||
(mapconcat 'identity gretl-keywords "\\|")
|
||||
"\\)\\>")
|
||||
'font-lock-keyword-face)
|
||||
;; Fontify all option flags.
|
||||
(cons (concat "[ \t]--\\("
|
||||
(mapconcat 'identity gretl-option-flags "\\|")
|
||||
"\\)")
|
||||
'font-lock-constant-face)
|
||||
;; Fontify all command words.
|
||||
(cons (concat "\\<\\("
|
||||
(mapconcat 'identity gretl-command-words "\\|")
|
||||
"\\)\\>")
|
||||
'font-lock-builtin-face)
|
||||
;; Fontify all builtin operators.
|
||||
(cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
|
||||
(if (boundp 'font-lock-builtin-face)
|
||||
'font-lock-builtin-face
|
||||
'font-lock-preprocessor-face))
|
||||
;; Fontify all internal variables.
|
||||
(cons (concat "\\$\\("
|
||||
(mapconcat 'identity gretl-internal-vars "\\|")
|
||||
"\\)\\>")
|
||||
'font-lock-variable-name-face)
|
||||
|
||||
;; Fontify all genr functions.
|
||||
(cons (concat "\\<\\("
|
||||
(mapconcat 'identity gretl-genr-functions "\\|")
|
||||
"\\)\\>")
|
||||
'font-lock-variable-name-face)
|
||||
;; Fontify all function declarations.
|
||||
(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-basic-offset 4)
|
||||
|
||||
(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.")
|
||||
|
||||
|
||||
|
||||
; get the position of the last open block
|
||||
(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))))))
|
||||
|
||||
|
||||
; return indent implied by a special form opening on the previous line, if any
|
||||
(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)))))
|
||||
;; previous line ends in =
|
||||
(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))
|
||||
;; take same indentation as previous line
|
||||
(save-excursion (forward-line -1)
|
||||
(current-indentation))
|
||||
0))
|
||||
(when (gretl-at-keyword gretl-block-end-keywords)
|
||||
(forward-word 1)))
|
||||
|
||||
;; (defun gretl-send-string-function (process string visibly)
|
||||
;; (let ((gretl-process (get-process "gretlcli")))
|
||||
;; (process-send-string process (format ess-load-command file)))
|
||||
|
||||
|
||||
;; (defun gretl-send-string-function (process string visibly)
|
||||
;; (let ((file (concat temporary-file-directory "gretl_eval_region.inp")))
|
||||
;; (with-temp-file file
|
||||
;; (insert string))
|
||||
;; (process-send-string process (format ess-load-command file))))
|
||||
|
||||
(defun gretl--get-words-from-command (command start-reg end-reg proc)
|
||||
(with-current-buffer (ess-command command nil nil nil nil proc)
|
||||
(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)))
|
||||
|
||||
(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "gretl"))
|
||||
(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" proc)
|
||||
(gretl--get-words-from-command "help functions\n" "Accessors:" "^Functions" proc)
|
||||
(gretl--get-words-from-command "help functions\n" "^Functions" "^For" proc)
|
||||
)))
|
||||
|
||||
;; (defvar ess-gretl-error-regexp-alist '(gretl-in gretl-at)
|
||||
;; "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
|
||||
|
||||
;; (add-to-list 'compilation-error-regexp-alist-alist
|
||||
;; '(gretl-in "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
|
||||
;; (add-to-list 'compilation-error-regexp-alist-alist
|
||||
;; '(gretl-at "^\\s-*\\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
|
||||
|
||||
|
||||
(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")
|
||||
(ess-load-command . "open \"%s\"\n")
|
||||
;; (ess-dump-error-re . "in \\w* at \\(.*\\):[0-9]+")
|
||||
;; (ess-error-regexp . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
|
||||
;; (ess-error-regexp-alist . ess-gretl-error-regexp-alist)
|
||||
;; (inferior-ess-objects-command . inferior-gretl-objects-command)
|
||||
;; (inferior-ess-search-list-command . "search()\n")
|
||||
;; inferior-ess-help-command . gretl-help-command)
|
||||
(inferior-ess-help-command . "help %s\n")
|
||||
(ess-language . "gretl")
|
||||
(ess-dialect . "gretl")
|
||||
(ess-suffix . "inp")
|
||||
(ess-dump-filename-template . (replace-regexp-in-string
|
||||
"S$" ess-suffix ; in the one from custom:
|
||||
ess-dump-filename-template-proto))
|
||||
(ess-change-sp-regexp . nil );ess-r-change-sp-regexp)
|
||||
(ess-help-sec-regex . ess-help-r-sec-regex)
|
||||
(ess-help-sec-keys-alist . ess-help-r-sec-keys-alist)
|
||||
(ess-function-pattern . ess-r-function-pattern)
|
||||
(ess-object-name-db-file . "ess-r-namedb.el" )
|
||||
;; (ess-imenu-mode-function . nil)
|
||||
(ess-smart-operators . ess-r-smart-operators)
|
||||
(inferior-ess-exit-command . "exit\n")
|
||||
;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
|
||||
(inferior-ess-language-start . nil)
|
||||
(ess-STERM . "iESS")
|
||||
)
|
||||
"Variables to customize for Gretl -- set up later than Emacs initialization.")
|
||||
|
||||
;; (defcustom inferior-gretl-program "gretlcli"
|
||||
;; "*The program to use for running gretl scripts."
|
||||
;; :type 'string
|
||||
;; :group 'ess-gretl)
|
||||
|
||||
;; (defvar ess-gretl-versions '("gretcli")
|
||||
;; "List of partial strings for versions of Julia to access within ESS.
|
||||
;; Each string specifies the start of a filename. If a filename
|
||||
;; beginning with one of these strings is found on `exec-path', a M-x
|
||||
;; command for that version of Julia is made available. ")
|
||||
|
||||
(defcustom inferior-gretl-args ""
|
||||
"String of arguments used when starting gretl."
|
||||
:group 'ess-gretl
|
||||
:type 'string)
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-gretl-mode ess-mode "ESS[gretl]"
|
||||
"Major mode for editing gretl source. See `ess-mode' for more help."
|
||||
;;(setq imenu-generic-expression R-imenu-generic-expression)
|
||||
(ess-setq-vars-local gretl-customize-alist)
|
||||
(setq font-lock-defaults `(,gretl-font-lock-keywords))
|
||||
(setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
|
||||
(setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
|
||||
(setq-local paragraph-ignore-fill-prefix t)
|
||||
(setq-local comment-start "# ")
|
||||
(setq-local comment-add 1)
|
||||
(setq-local comment-start-skip "\\s<+\\s-*")
|
||||
(setq-local comment-column 40)
|
||||
(setq-local indent-line-function #'gretl-indent-line)
|
||||
(setq-local ess-local-customize-alist gretl-customize-alist)
|
||||
(when (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
|
||||
|
||||
|
||||
(defvar ess-gretl-post-run-hook nil
|
||||
"Functions run in process buffer after Gretl starts.")
|
||||
|
||||
;;;###autoload
|
||||
(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")
|
||||
;; get settings, notably inferior-ess-r-program :
|
||||
;; (if (null inferior-gretl-program)
|
||||
;; (error "'inferior-gretl-program' does not point to 'gretl-release-basic' executable")
|
||||
(ess-write-to-dribble-buffer ;; for debugging only
|
||||
(format
|
||||
"\n(Gretl): ess-dialect=%s, buf=%s"
|
||||
ess-dialect (current-buffer)))
|
||||
(let* ((r-start-args
|
||||
(concat inferior-gretl-args " " ; add space just in case
|
||||
(if start-args
|
||||
(read-string
|
||||
(concat "Starting Args [other than `"
|
||||
inferior-gretl-args
|
||||
"'] ? "))
|
||||
nil)))
|
||||
(inf-buf (inferior-ess r-start-args gretl-customize-alist)))
|
||||
(setq-local indent-line-function 'gretl-indent-line)
|
||||
(setq-local gretl-basic-offset 4)
|
||||
(setq indent-tabs-mode nil)
|
||||
(goto-char (point-max))
|
||||
;; (if inferior-ess-language-start
|
||||
;; (ess-eval-linewise inferior-ess-language-start
|
||||
;; nil nil nil 'wait-prompt)))
|
||||
(with-current-buffer inf-buf
|
||||
(run-mode-hooks 'ess-gretl-post-run-hook))
|
||||
inf-buf))
|
||||
|
||||
|
||||
;;;; IMENU
|
||||
|
||||
;; (defvar gretl-imenu-generic-expression
|
||||
;; '(("Function (_)" "^\\s-*function\\s-+\\(_[^ \t\n]*\\)" 1)
|
||||
;; ("Function" "^\\s-*function\\s-+\\([^_][^ \t\n]*\\)" 1)
|
||||
;; ("Const" "^\\s-*const \\([^ \t\n]*\\)" 1)
|
||||
;; ("Type" "^\\s-*\\w*type\\w* \\([^ \t\n]*\\)" 1)
|
||||
;; ("Load" " *\\(load\\)(\\([^ \t\n)]*\\)" 2)
|
||||
;; ;; ("Classes" "^.*setClass(\\(.*\\)," 1)
|
||||
;; ;; ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
|
||||
;; ;; ("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
|
||||
;; ;; ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\"\\(.+\\)\"," 2)
|
||||
;; ;; ;;[ ]*\\(signature=\\)?(\\(.*,?\\)*\\)," 1)
|
||||
;; ;; ;;
|
||||
;; ;; ;;("Other" "^\\(.+\\)\\s-*<-[ \t\n]*[^\\(function\\|read\\|.*data\.frame\\)]" 1)
|
||||
;; ;; ("Package" "^.*\\(library\\|require\\)(\\(.*\\)," 2)
|
||||
;; ;; ("Data" "^\\(.+\\)\\s-*<-[ \t\n]*\\(read\\|.*data\.frame\\).*(" 1)))
|
||||
;; ))
|
||||
|
||||
|
||||
;; (defun ess-imenu-gretl (&optional arg)
|
||||
;; "Gretl Language Imenu support for ESS."
|
||||
;; (interactive)
|
||||
;; (setq imenu-generic-expression gretl-imenu-generic-expression)
|
||||
;; (imenu-add-to-menubar "Imenu-gretl"))
|
||||
|
||||
|
||||
;; (defun ess-imenu-gretl (&optional arg)
|
||||
;; "Gretl Language Imenu support for ESS."
|
||||
;; (interactive)
|
||||
;; (setq imenu-generic-expression gretl-imenu-generic-expression)
|
||||
;; (imenu-add-to-menubar "Imenu-jl"))
|
||||
|
||||
|
||||
(provide 'ess-gretl)
|
||||
|
||||
;;; ess-gretl.el ends here
|
||||
870
lisp/ess/ess-help.el
Normal file
870
lisp/ess/ess-help.el
Normal file
@@ -0,0 +1,870 @@
|
||||
;;; ess-help.el --- Support for viewing ESS help files -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1989-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: David Smith <dsmith@stats.adelaide.edu.au>
|
||||
;; Created: 7 Jan 1994
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Code for dealing with ESS help files. See README.<LANGUAGE> where
|
||||
;; <LANGUAGE> is one of `S', `SAS', `Stata' or `XLispStat'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
; Requires and autoloads
|
||||
(require 'cl-lib)
|
||||
(eval-when-compile
|
||||
(require 'tramp))
|
||||
(require 'info)
|
||||
(require 'ess-mode)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-utils)
|
||||
(require 'ansi-color)
|
||||
|
||||
(declare-function ess-r-help-mode "ess-r-mode")
|
||||
(declare-function ess-stata-help-mode "ess-stata-lang")
|
||||
|
||||
|
||||
(defcustom ess-help-mode-hook nil
|
||||
"Functions to call when entering `ess-help-mode'."
|
||||
:group 'ess-hooks
|
||||
:type 'hook)
|
||||
|
||||
(defvar ess--help-frame nil
|
||||
"Stores the frame used for displaying R help buffers.")
|
||||
|
||||
; ess-help-mode
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; In this section:
|
||||
;;;;
|
||||
;;;; * The function ess-display-help-on-object
|
||||
;;;; * The major mode ess-help-mode
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(cl-defgeneric ess--help-major-mode ()
|
||||
"Determine which help major mode to call, and call it.
|
||||
Uses `ess-dialect' to determine the appropriate help mode."
|
||||
(ess-help-mode))
|
||||
|
||||
(defun ess--help-get-bogus-buffer-substring (buffer &optional nr-first)
|
||||
"Return non-nil if BUFFER looks like a bogus ESS help buffer.
|
||||
Return the pair (match-beg. match-end) which can be used in error
|
||||
message. NR-FIRST is the number of characters at the start of the
|
||||
buffer to examine when deciding if the buffer if bogus. If nil,
|
||||
the first 150 characters of the buffer are searched."
|
||||
(if (not nr-first) (setq nr-first 150))
|
||||
(with-current-buffer buffer
|
||||
(let ((PM (point-min))
|
||||
(case-fold-search t)
|
||||
searching res)
|
||||
(setq res
|
||||
(or ;; evaluate up to first non-nil (or end):
|
||||
(< (- (point-max) PM) 80); buffer less than 80 chars
|
||||
(not (setq searching t))
|
||||
;; todo: move to customize-alist
|
||||
(progn (goto-char PM) ;; R:
|
||||
(re-search-forward "Error in help" nr-first t))
|
||||
(progn (goto-char PM) ;; S-plus 5.1 :
|
||||
(re-search-forward "^cat: .*--" nr-first t))
|
||||
(progn (goto-char PM) ;; S version 3 ; R :
|
||||
(re-search-forward "no documentation .+" nr-first t))
|
||||
(progn (goto-char PM) ;; stata
|
||||
(re-search-forward "^help .*not found" nr-first t))))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format " |--> %s [searching %s]\n" res searching))
|
||||
(when res
|
||||
(if searching
|
||||
(buffer-substring (match-beginning 0) (match-end 0))
|
||||
(buffer-string))))))
|
||||
|
||||
(defun ess-help-get-local-help-buffers ()
|
||||
(ess-force-buffer-current)
|
||||
(cl-remove-if-not
|
||||
(lambda (buffer)
|
||||
(let* ((pattern (concat "*help[" ess-current-process-name "]("))
|
||||
(name (buffer-name buffer))
|
||||
(candidate (when (> (length name) (length pattern))
|
||||
(substring name 0 (length pattern))) ))
|
||||
(when (string= pattern candidate)
|
||||
buffer)))
|
||||
(buffer-list)))
|
||||
|
||||
(defvar-local ess-help-type nil
|
||||
"Type of help file, help, index, vignettes etc.
|
||||
Local in `ess-help' buffers.")
|
||||
|
||||
(defvar-local ess-help-object nil
|
||||
"Name of the object the help is displayed for.
|
||||
Is name of the package for package index.
|
||||
Local in `ess-help' buffers.")
|
||||
(put 'ess-help-object 'permanent-local t)
|
||||
|
||||
(defun ess-display-help-on-object (object &optional command)
|
||||
"Display documentation for OBJECT.
|
||||
If prefix ARG is given, force an update of the cached help topics
|
||||
and query the ESS process for the help file instead of reusing an
|
||||
existing buffer if it exists. Uses the variable
|
||||
`inferior-ess-help-command' for the actual help command. Prompts
|
||||
for the object name based on the cursor location for all cases
|
||||
except the S-Plus GUI. With S-Plus on Windows (both GUI and in an
|
||||
inferior Emacs buffer) the GUI help window is used. If COMMAND is
|
||||
supplied, it is used instead of `inferior-ess-help-command'."
|
||||
(interactive
|
||||
(progn
|
||||
(ess-force-buffer-current)
|
||||
(when current-prefix-arg ;update cache if prefix
|
||||
(ess-process-put 'sp-for-help-changed? t))
|
||||
(list (ess-find-help-file "Help on"))))
|
||||
(let* ((hb-name (concat "*help[" ess-current-process-name "]("
|
||||
(replace-regexp-in-string "^\\?\\|`" "" object) ")*"))
|
||||
(old-hb-p (get-buffer hb-name))
|
||||
(tbuffer (get-buffer-create hb-name)))
|
||||
(when (or (not old-hb-p)
|
||||
(ess-process-get 'sp-for-help-changed?)
|
||||
(ess--help-get-bogus-buffer-substring old-hb-p))
|
||||
(ess-with-current-buffer tbuffer
|
||||
(ess--flush-help-into-current-buffer object command)
|
||||
(setq ess-help-object object)
|
||||
(ess--help-major-mode)
|
||||
(setq truncate-lines nil
|
||||
ess-help-type 'help)))
|
||||
(unless (ess--help-kill-bogus-buffer-maybe tbuffer)
|
||||
(ess-display-help tbuffer))))
|
||||
|
||||
(defun ess-help-revert-buffer (_ignore-auto _noconfirm)
|
||||
"Revert the current help buffer.
|
||||
This reloads the documentation. IGNORE-AUTO and NOCONFIRM are
|
||||
ignored."
|
||||
(ess-process-put 'sp-for-help-changed? t)
|
||||
(ess-display-help-on-object ess-help-object))
|
||||
|
||||
(defalias 'ess-help 'ess-display-help-on-object)
|
||||
|
||||
(cl-defgeneric ess-build-help-command (object)
|
||||
"Build a string command for retrieving help on OBJECT."
|
||||
(format inferior-ess-help-command object))
|
||||
|
||||
(defun ess--flush-help-into-current-buffer (object &optional command)
|
||||
(let ((inhibit-modification-hooks t)
|
||||
(inhibit-read-only t))
|
||||
(delete-region (point-min) (point-max))
|
||||
(let ((command (if (and command (string-match-p "%s" command))
|
||||
(format command object)
|
||||
command)))
|
||||
(ess-command (or command (ess-build-help-command object)) (current-buffer)))
|
||||
(ess-help-underline)
|
||||
(unless (string= ess-language "STA")
|
||||
(ess-nuke-help-bs))
|
||||
(goto-char (point-min))
|
||||
(set-buffer-modified-p 'nil)))
|
||||
|
||||
(defun ess--help-kill-bogus-buffer-maybe (buffer)
|
||||
"Internal, try to kill bogus BUFFER with message. Return t if killed."
|
||||
(when ess-help-kill-bogus-buffers
|
||||
(let ((bog-mes (ess--help-get-bogus-buffer-substring buffer)))
|
||||
(when bog-mes
|
||||
;; The following is giving erroneous messages when help is displayed in the browser
|
||||
;; (when (< (length bog-mes) 10) ;;no message at all, how to treat this properly?
|
||||
;; (setq bog-mes (format "No documentation found; %s" bog-mes)))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "(ess-help: kill bogus buffer %s ..\n" (buffer-name buffer)))
|
||||
(message "%s" (replace-regexp-in-string "\n" "" bog-mes))
|
||||
;; (ding) ;; don't ding, in julia a lot of doc strings are very short
|
||||
(kill-buffer buffer)))))
|
||||
|
||||
(defun ess-display-help-in-browser ()
|
||||
"Displaying HTML help where available, using \\[browse-url]."
|
||||
(interactive)
|
||||
;; Three ways to find HTML help, 1) ask sub-process 2) get URL/file from subprocess
|
||||
;; 3) call elisp function to get the file path
|
||||
;; For 2 and 3 call browse-url on the output
|
||||
(let (com-html-help ;1) command for sub-process to trigger
|
||||
;help, must contain %s for help obj
|
||||
com-get-file-path ;2) command for sub-process to return a
|
||||
; location for the help page, must
|
||||
; contain %s for help obj
|
||||
fun-get-file-path ;3) elisp function to return the
|
||||
;location, gets one argument, help topic
|
||||
not-implemented
|
||||
)
|
||||
(cond
|
||||
((string-match "^R" ess-dialect)
|
||||
(setq com-html-help "help('%s', help_type='html')\n"))
|
||||
(t (setq not-implemented t))
|
||||
)
|
||||
(if not-implemented
|
||||
(message "Sorry, not implemented for %s " ess-dialect)
|
||||
(if (or (not ess-help-object)
|
||||
(not (eq ess-help-type 'help)))
|
||||
(message "No help topic found")
|
||||
(if com-html-help
|
||||
(ess-command (format com-html-help ess-help-object))
|
||||
(require 'browse-url)
|
||||
(if com-get-file-path
|
||||
(browse-url (car (ess-get-words-from-vector
|
||||
(format com-get-file-path ess-help-object))))
|
||||
(when (functionp fun-get-file-path)
|
||||
(browse-url (funcall fun-get-file-path ess-help-object)))))))))
|
||||
|
||||
(defun ess--button-action (&optional button)
|
||||
"Provide help on object at the beginning of line.
|
||||
It's intended to be used in R-index help pages. Load the package
|
||||
if necessary. It is bound to RET and C-m in R-index pages."
|
||||
(let* ((string (button-label button))
|
||||
(command (ess-build-help-command string)))
|
||||
(ess-display-help-on-object string command)))
|
||||
|
||||
(cl-defgeneric ess-help-commands ()
|
||||
"Return an alist of dialect specific retriever commands.
|
||||
Currently understood commands:
|
||||
- package-for-object - command to get the package of current help object
|
||||
- packages - command to get a list of available packages (REQUIRED)
|
||||
- package-index - command to get the package index (REQUIRED)
|
||||
- index-keyword-reg - regexp used to find keywords for linking in index listing
|
||||
only (1st subexpression is used)
|
||||
- index-start-reg - regexp from where to start searching for keywords in index listing"
|
||||
(user-error "Not implemented for %s " ess-dialect))
|
||||
|
||||
(cl-defmethod ess-help-commands (&context (ess-dialect "R"))
|
||||
'((package-for-object . "sub('package:', '', .ess.findFUN('%s'))\n")
|
||||
(packages . ".packages(all.available=TRUE)\n")
|
||||
(package-index . ".ess.help(package='%s', help.type='text')\n")
|
||||
(index-keyword-reg . "^\\([^ \t\n:]+\\)")
|
||||
(index-start-reg . "^Index:")))
|
||||
|
||||
(defun ess-display-package-index (&optional package)
|
||||
"Prompt for package name and display its index."
|
||||
(interactive
|
||||
(list (let* ((coms (ess-help-commands))
|
||||
(all-packs (ess-get-words-from-vector (cdr (assoc 'packages coms))))
|
||||
(pack (or (when (and ess-help-object
|
||||
(cdr (assoc 'package-for-object coms))
|
||||
(eq ess-help-type 'help))
|
||||
(car (ess-get-words-from-vector
|
||||
(format (cdr (assoc 'package-for-object coms))
|
||||
ess-help-object))))
|
||||
(car (member (ess-read-object-name-default) all-packs)))))
|
||||
(ess-completing-read "Index of" all-packs nil nil nil nil pack))))
|
||||
(let ((coms (ess-help-commands)))
|
||||
(ess--display-indexed-help-page
|
||||
(format (cdr (assoc 'package-index coms)) package)
|
||||
(cdr (assoc 'index-keyword-reg coms))
|
||||
(format "*help[%s](index:%s)*" ess-dialect package)
|
||||
'index nil nil (cdr (assoc 'index-start-reg coms)) package)))
|
||||
|
||||
(defun ess--display-indexed-help-page (command item-regexp title help-type
|
||||
&optional action help-echo reg-start help-object)
|
||||
"Internal function to display help pages with linked actions.
|
||||
COMMAND to produce the indexed help page,
|
||||
ITEM-REGEXP -- first subexpression is highlighted,
|
||||
TITLE of the help page,
|
||||
HELP-TYPE to be stored in `ess-help-type' local variable,
|
||||
ACTION is a function with no argument (default is `ess--button-action'),
|
||||
HELP-ECHO if given becomes the help-echo property of the button,
|
||||
REG-START gives the start location from where to search linkifying, and HELP-OBJECT becomes `ess-help-object'."
|
||||
(let ((inhibit-modification-hooks t)
|
||||
(alist ess-local-customize-alist)
|
||||
(pname ess-local-process-name)
|
||||
(buff (get-buffer-create title)))
|
||||
(ess-with-current-buffer buff
|
||||
(setq buffer-read-only nil)
|
||||
(delete-region (point-min) (point-max))
|
||||
(setq ess-local-process-name pname)
|
||||
(ess--help-major-mode)
|
||||
(ess-setq-vars-local (eval alist))
|
||||
(setq ess-help-object help-object
|
||||
ess-help-sec-regex "\\(^\\s-.*\n\\)\\|\\(^\n\\)")
|
||||
(ess-command command buff)
|
||||
(ess-help-underline)
|
||||
(set-buffer-modified-p 'nil)
|
||||
(goto-char (point-min))
|
||||
(when reg-start ;; go to the beginning of listing
|
||||
(re-search-forward reg-start nil t))
|
||||
(when item-regexp
|
||||
;;linkify the buffer
|
||||
(save-excursion
|
||||
(while (re-search-forward item-regexp nil t)
|
||||
(make-text-button (match-beginning 1) (match-end 1)
|
||||
'mouse-face 'highlight
|
||||
'action (or action #'ess--button-action)
|
||||
'help-object (buffer-substring-no-properties (match-beginning 1) (match-end 1))
|
||||
'follow-link t
|
||||
'help-echo (or help-echo "help on object")))))
|
||||
(save-excursion ;; why R help adds all these spaces?
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "Index:\n\n" nil t)
|
||||
(let ((beg (point)))
|
||||
(forward-paragraph 1)
|
||||
(align-regexp beg (point) "\\(\\s-+\\)"))))
|
||||
(setq buffer-read-only t)
|
||||
(setq ess-help-type help-type)
|
||||
(setq truncate-lines nil))
|
||||
(unless (ess--help-kill-bogus-buffer-maybe buff)
|
||||
(ess-display-help buff))))
|
||||
|
||||
(defun ess-display-help-apropos (&optional pattern)
|
||||
"Create an ess-apropos buffer with a *linked* list of apropos topics."
|
||||
(interactive "sPattern: ")
|
||||
(let (com regexp)
|
||||
(cond ((equal ess-dialect "R")
|
||||
(setq com "help.search('%s')\n"
|
||||
regexp "^\\([^ \t\n:]+::[^ \t\n:]+\\)[ \t\n]+"))
|
||||
((equal ess-dialect "julia")
|
||||
(setq com "apropos(\"%s\")\n"
|
||||
regexp "^\\(\\(\\w\\|\\s_\\)+\\)("))
|
||||
((equal ess-dialect "stata")
|
||||
(setq com "hsearch %s\n"
|
||||
regexp "^[\t ]*[0-9]+\\.[\t ]+\\(.+\\)$"))
|
||||
(t (error "Not implemented for dialect %s" ess-dialect)))
|
||||
(ess--display-indexed-help-page
|
||||
(format com pattern) regexp
|
||||
(format "*ess-apropos[%s](%s)*" ess-current-process-name pattern)
|
||||
'appropos)))
|
||||
|
||||
(defun ess-display-demos ()
|
||||
"Create an ess-demos buffer with a *linked* list of available demos."
|
||||
(interactive)
|
||||
(let (com regexp)
|
||||
(cond ((equal ess-dialect "R")
|
||||
(setq com "demo()\n"
|
||||
regexp "^\\([^ \n:]+\\) +"))
|
||||
(t (error "Not implemented for dialect %s" ess-dialect)))
|
||||
(ess--display-indexed-help-page
|
||||
com regexp
|
||||
(format "*ess-demos[%s]*" ess-current-process-name)
|
||||
'demos #'ess--action-demo)))
|
||||
|
||||
(defun ess--action-demo (&optional button)
|
||||
"Provide help on object at the beginning of line.
|
||||
It's intended to be used in R-index help pages. Load the package
|
||||
if necessary. It is bound to RET and C-m in R-index pages."
|
||||
(let* ((string (button-label button))
|
||||
(command
|
||||
(cond ((equal ess-dialect "R")
|
||||
(format "demo('%s')\n" string))
|
||||
(t (error "Not implemented for dialect %s" ess-dialect)))))
|
||||
(ess-eval-linewise command)
|
||||
(ess-switch-to-end-of-ESS)))
|
||||
|
||||
(defun ess-display-vignettes (&optional all)
|
||||
"Display vignettes if available for the current dialect.
|
||||
With (prefix) ALL non-nil, use `vignette(*, all=TRUE)`, i.e., from all installed
|
||||
packages, which can be *very* slow."
|
||||
(interactive "P")
|
||||
(ess--display-vignettes-override all))
|
||||
|
||||
(cl-defgeneric ess--display-vignettes-override (_all)
|
||||
"Display vignettes for the current dialect.
|
||||
See `ess-display-vignettes' for ALL."
|
||||
(user-error "Sorry, not implemented for %s" ess-dialect))
|
||||
|
||||
(defun ess--action-open-in-emacs (pos)
|
||||
(display-buffer (find-file-noselect (get-text-property pos 'help-echo))))
|
||||
(defun ess--action-R-open-vignette (pos)
|
||||
(ess-eval-linewise (format "vignette('%s', package='%s')\n"
|
||||
(get-text-property pos 'vignette)
|
||||
(get-text-property pos 'package))))
|
||||
|
||||
(defalias 'ess-help-quit 'quit-window)
|
||||
(make-obsolete 'ess-help-quit 'quit-window "16.04")
|
||||
|
||||
(defun ess-display-help (buff)
|
||||
"Display buffer BUFF.
|
||||
If `ess-help-pop-to-buffer' is non-nil, call `pop-to-buffer',
|
||||
otherwise call `display-buffer' to display the buffer.
|
||||
|
||||
You may control how help buffers are displayed by EITHER setting
|
||||
an entry in `display-buffer-alist' (see examples in info
|
||||
node `(ess) Controlling buffer display') OR setting the
|
||||
ESS-specific variables `ess-help-own-frame',
|
||||
`ess-help-reuse-window', `ess-help-frame-alist', and
|
||||
`ess-display-buffer-reuse-frames'."
|
||||
(let* ((action (cond (ess-help-own-frame
|
||||
'(display-buffer-reuse-window
|
||||
display-buffer-use-some-frame
|
||||
display-buffer-pop-up-frame))
|
||||
(ess-help-reuse-window
|
||||
'(display-buffer-reuse-window
|
||||
ess-display-buffer-reuse-mode-window
|
||||
display-buffer-pop-up-window
|
||||
display-buffer-use-some-window))
|
||||
(t '(display-buffer-pop-up-window
|
||||
display-buffer-use-some-window))))
|
||||
(alist `((mode . (ess-help-mode ess-r-help-mode ess-stata-help-mode ess-julia-help-mode))
|
||||
(reusable-frames . ,ess-display-buffer-reuse-frames)
|
||||
;; `display-buffer-use-some-frame' uses this to
|
||||
;; determine whether to use the frame or not.
|
||||
(frame-predicate . (lambda (f)
|
||||
(when (equal ess-help-own-frame 'one)
|
||||
;; Note we're always returning
|
||||
;; nil for `ess-help-own-frame' t.
|
||||
(frame-parameter f 'ess-help-frame))))
|
||||
;; If `display-buffer' makes a new frame, these are
|
||||
;; given as frame parameters.
|
||||
(pop-up-frame-parameters . ,(append ess-help-frame-alist
|
||||
`((auto-hide-function . delete-frame)
|
||||
(ess-help-frame . ,(equal ess-help-own-frame 'one)))))))
|
||||
(display-alist `(,action . ,alist)))
|
||||
(if ess-help-pop-to-buffer
|
||||
(pop-to-buffer buff display-alist)
|
||||
(display-buffer buff display-alist))))
|
||||
|
||||
(defun ess-help-web-search (cmd)
|
||||
"Search the web for documentation on CMD."
|
||||
(interactive "sSearch for: ")
|
||||
(ess--help-web-search-override cmd))
|
||||
|
||||
(cl-defgeneric ess--help-web-search-override (_cmd)
|
||||
"Dialect-specific override for `ess-help-web-search', which see for CMD."
|
||||
(error "Not implemented for %s" ess-dialect))
|
||||
|
||||
(defun ess-manual-lookup ()
|
||||
"Search manual for documentation."
|
||||
(interactive)
|
||||
(ess--manual-lookup-override))
|
||||
|
||||
(cl-defgeneric ess--manual-lookup-override ()
|
||||
"Dialect-specific override for `ess-manual-lookup'."
|
||||
(error "Not implemented for %s" ess-dialect))
|
||||
|
||||
(defvar ess-doc-map
|
||||
(let (ess-doc-map)
|
||||
(define-prefix-command 'ess-doc-map)
|
||||
(define-key ess-doc-map "\C-e" #'ess-describe-object-at-point)
|
||||
(define-key ess-doc-map "e" #'ess-describe-object-at-point)
|
||||
(define-key ess-doc-map "\C-d" #'ess-display-help-on-object)
|
||||
(define-key ess-doc-map "d" #'ess-display-help-on-object)
|
||||
(define-key ess-doc-map "\C-i" #'ess-display-package-index)
|
||||
(define-key ess-doc-map "i" #'ess-display-package-index)
|
||||
(define-key ess-doc-map "\C-a" #'ess-display-help-apropos)
|
||||
(define-key ess-doc-map "a" #'ess-display-help-apropos)
|
||||
(define-key ess-doc-map "\C-v" #'ess-display-vignettes)
|
||||
(define-key ess-doc-map "v" #'ess-display-vignettes)
|
||||
(define-key ess-doc-map "\C-o" #'ess-display-demos)
|
||||
(define-key ess-doc-map "o" #'ess-display-demos)
|
||||
(define-key ess-doc-map "\C-w" #'ess-help-web-search)
|
||||
(define-key ess-doc-map "w" #'ess-help-web-search)
|
||||
(define-key ess-doc-map "\C-m" #'ess-manual-lookup)
|
||||
(define-key ess-doc-map "m" #'ess-manual-lookup)
|
||||
ess-doc-map)
|
||||
"ESS documentation map.")
|
||||
|
||||
|
||||
(defvar ess-help-mode-map
|
||||
(let ((map (make-keymap)))
|
||||
(define-key map "\C-m" #'next-line)
|
||||
(define-key map "h" #'ess-display-help-on-object)
|
||||
(define-key map "w" #'ess-display-help-in-browser)
|
||||
(define-key map "i" #'ess-display-package-index)
|
||||
(define-key map "a" #'ess-display-help-apropos)
|
||||
(define-key map "v" #'ess-display-vignettes)
|
||||
(define-key map "l" #'ess-eval-line-visibly-and-step)
|
||||
(define-key map "r" #'ess-eval-region-and-go)
|
||||
(define-key map "f" #'ess-eval-function-or-paragraph-and-step)
|
||||
(define-key map "n" #'ess-skip-to-next-section)
|
||||
(define-key map "p" #'ess-skip-to-previous-section)
|
||||
(define-key map "/" #'isearch-forward)
|
||||
(define-key map "x" #'ess-kill-buffer-and-go)
|
||||
(define-key map "k" #'kill-this-buffer)
|
||||
(define-key map "\C-c\C-s" #'ess-switch-process)
|
||||
(define-key map "\C-c\C-r" #'ess-eval-region)
|
||||
(define-key map "\C-c\M-r" #'ess-eval-region-and-go)
|
||||
(define-key map "\C-c\C-f" #'ess-eval-function)
|
||||
(define-key map "\M-\C-x" #'ess-eval-function)
|
||||
(define-key map "\C-c\M-f" #'ess-eval-function-and-go)
|
||||
(define-key map "\C-c\C-j" #'ess-eval-line)
|
||||
(define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
|
||||
(define-key map "\C-c\C-c" #'ess-eval-region-or-function-or-paragraph-and-step)
|
||||
(define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
|
||||
(define-key map "\C-c\M-j" #'ess-eval-line-and-go)
|
||||
(define-key map "\M-\C-a" #'ess-goto-beginning-of-function-or-para)
|
||||
(define-key map "\M-\C-e" #'ess-goto-end-of-function-or-para)
|
||||
(define-key map "\C-c\C-y" #'ess-switch-to-ESS)
|
||||
(define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
|
||||
(define-key map "\C-c\C-l" #'ess-load-file)
|
||||
(define-key map "\C-c\M-l" #'ess-load-file); alias, as in #'iESS#' where C-c C-l is comint-list-*
|
||||
(define-key map "\C-c\C-v" #'ess-display-help-on-object)
|
||||
(define-key map "\C-c\C-k" #'ess-request-a-process)
|
||||
(define-key map "\C-c\C-d" 'ess-doc-map)
|
||||
(define-key map "\C-c\C-e" 'ess-extra-map)
|
||||
(define-key map "\C-c\C-t" 'ess-dev-map)
|
||||
map)
|
||||
"Keymap for ESS help mode.")
|
||||
|
||||
;; One reason for the following menu is to <TEACH> the user about key strokes
|
||||
(defvar ess-help-mode-menu
|
||||
'("ESS-help"
|
||||
["Search forward" isearch-forward t]
|
||||
["Next section" ess-skip-to-next-section t]
|
||||
["Previous section" ess-skip-to-previous-section t]
|
||||
["Help on section skipping" ess-describe-sec-map t]
|
||||
["Beginning of buffer" beginning-of-buffer t]
|
||||
["End of buffer" end-of-buffer t]
|
||||
"-"
|
||||
["Help on ..." ess-display-help-on-object t]
|
||||
["Apropos of ..." ess-display-help-apropos t]
|
||||
["Index of ..." ess-display-package-index t]
|
||||
["Vignettes" ess-display-vignettes t]
|
||||
["Open in browser" ess-display-help-in-browser t]
|
||||
"-"
|
||||
["Eval line" ess-eval-line-and-step t]
|
||||
["Eval paragraph & step" ess-eval-paragraph-and-step t]
|
||||
["Eval region & go" ess-eval-region-and-go t]
|
||||
["Switch to ESS process" ess-switch-to-ESS t]
|
||||
["Switch to end of ESS proc." ess-switch-to-end-of-ESS t]
|
||||
["Switch _the_ process" ess-switch-process t]
|
||||
"-"
|
||||
["Kill buffer" kill-this-buffer t]
|
||||
["Kill buffer & go" ess-kill-buffer-and-go t]
|
||||
"-"
|
||||
["Handy commands" ess-handy-commands t])
|
||||
"Menu used in ess-help mode.")
|
||||
|
||||
(easy-menu-define ess-help-mode-menu-map ess-help-mode-map
|
||||
"Menu keymap for ess-help mode." ess-help-mode-menu)
|
||||
|
||||
(define-derived-mode ess-help-mode special-mode "ESS Help"
|
||||
"Mode for viewing ESS help files."
|
||||
:group 'ess-help
|
||||
;; FIXME
|
||||
;; (if ess-mode-syntax-table ;;set in advance by ess-setq-local
|
||||
;; (set-syntax-table ess-mode-syntax-table))
|
||||
(setq-local revert-buffer-function #'ess-help-revert-buffer)
|
||||
(setq show-trailing-whitespace nil))
|
||||
|
||||
|
||||
;;*;; User commands defined in ESS help mode
|
||||
|
||||
(defun ess-skip-to-help-section ()
|
||||
"Jump to a section heading of a help buffer.
|
||||
The section selected is determined by the command letter used to
|
||||
invoke the command, as indicated by `ess-help-sec-keys-alist'.
|
||||
Use \\[ess-describe-sec-map] to see which keystrokes find which
|
||||
sections."
|
||||
(interactive)
|
||||
(let ((old-point (point))
|
||||
(case-fold-search nil)
|
||||
(the-sec (cdr (assoc last-command-event ess-help-sec-keys-alist))))
|
||||
(cl-assert the-sec nil (format "Invalid section key: %c" last-command-event))
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward (concat "^" the-sec) nil t)
|
||||
(progn (recenter)
|
||||
(beginning-of-line))
|
||||
(message "No %s section in this help. Sorry." the-sec)
|
||||
(goto-char old-point))))
|
||||
|
||||
(defun ess-skip-to-next-section ()
|
||||
"Jump to next section in ESS help buffer."
|
||||
(interactive)
|
||||
(let ((case-fold-search nil))
|
||||
(when (looking-at-p ess-help-sec-regex)
|
||||
(forward-line))
|
||||
(if (re-search-forward ess-help-sec-regex nil 'no-error)
|
||||
(beginning-of-line)
|
||||
(message "No more sections."))))
|
||||
|
||||
(defun ess-skip-to-previous-section ()
|
||||
"Jump to previous section in ESS help buffer."
|
||||
(interactive)
|
||||
(let ((case-fold-search nil))
|
||||
(if (re-search-backward ess-help-sec-regex nil 'no-error)
|
||||
(beginning-of-line)
|
||||
(message "No previous section."))))
|
||||
|
||||
(defun ess-kill-buffer-and-go nil
|
||||
"Kill the current buffer and switch back to the ESS process."
|
||||
(interactive)
|
||||
(kill-buffer (current-buffer))
|
||||
(when (and ess-current-process-name (get-process ess-current-process-name))
|
||||
(ess-switch-to-ESS nil)))
|
||||
|
||||
(defun ess-describe-sec-map nil
|
||||
"Display help for the `s' key."
|
||||
(interactive)
|
||||
(let ((keys-alist ess-help-sec-keys-alist))
|
||||
(describe-function 'ess-skip-to-help-section)
|
||||
|
||||
(with-current-buffer "*Help*"
|
||||
(setq buffer-read-only nil)
|
||||
(goto-char (point-max))
|
||||
(insert "\n\nCurrently defined keys are:
|
||||
|
||||
Keystroke Section
|
||||
--------- -------\n")
|
||||
(dolist (cs keys-alist)
|
||||
(insert " "
|
||||
(car cs)
|
||||
" "
|
||||
(cdr cs) "\n")))))
|
||||
|
||||
(defun ess-helpobjs-at-point--read-obj ()
|
||||
(let* ((obj (ess-read-object-name-default)))
|
||||
;; Exclude numbers
|
||||
(unless (and obj (not (string-match "[[:alpha:]]" obj)))
|
||||
obj)))
|
||||
|
||||
(defun ess-unqualify-symbol (object)
|
||||
(if (string-match "^[[:alnum:].]+::?" object)
|
||||
(substring object (match-end 0))
|
||||
object))
|
||||
|
||||
(defun ess-helpobjs-at-point (slist)
|
||||
"Return a list (def obj fun).
|
||||
Obj is a name at point, fun is the name of the function call
|
||||
point is in, and def is either obj or fun (in that order) which
|
||||
has a a help file, i.e. it is a member of SLIST (string-list).
|
||||
nil otherwise."
|
||||
(let* ((obj (ess-helpobjs-at-point--read-obj))
|
||||
(unqualified-obj (and obj (ess-unqualify-symbol obj)))
|
||||
;; FIXME: probably should use syntactic logic here
|
||||
(fun (ignore-errors
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region (max (point-min) (- (point) 1000))
|
||||
(point-max))
|
||||
(backward-up-list 1)
|
||||
(backward-char 1)
|
||||
(ess-read-object-name-default))))))
|
||||
(list (or (car (member obj slist))
|
||||
(when (member unqualified-obj slist)
|
||||
obj)
|
||||
(car (member fun slist)))
|
||||
obj fun)))
|
||||
|
||||
(cl-defgeneric ess-help-get-topics (proc)
|
||||
"Return a list of help topics from PROC."
|
||||
(user-error "Not supported for %s (process: %s)" ess-dialect proc))
|
||||
|
||||
(defun ess-find-help-file (p-string)
|
||||
"Find help, prompting for P-STRING."
|
||||
(ess-make-buffer-current)
|
||||
(let* ((help-files-list (ess-help-get-topics ess-current-process-name))
|
||||
(hlpobjs (delq nil (ess-helpobjs-at-point help-files-list))))
|
||||
(ess-completing-read p-string (append hlpobjs help-files-list)
|
||||
nil nil nil nil (car hlpobjs))))
|
||||
|
||||
|
||||
;;*;; Utility functions
|
||||
|
||||
(defun ess-get-help-files-list ()
|
||||
"Return a list of files which have help available."
|
||||
(apply 'nconc
|
||||
(mapcar (lambda (str)
|
||||
(let ((dirname (concat str "/.Help")))
|
||||
(and (file-directory-p dirname)
|
||||
(directory-files dirname))))
|
||||
(ess-search-list))))
|
||||
|
||||
(defun ess-get-help-aliases-list ()
|
||||
"Return a list of aliases which have help available."
|
||||
(message "Retrieving RDS aliases...")
|
||||
;; ess-command locks display, make sure the above message is visible
|
||||
(redisplay t)
|
||||
(ess-write-to-dribble-buffer "Processing RDS files ...\n")
|
||||
(prog1 (ess-get-words-from-vector ".ess.getHelpAliases()\n")
|
||||
(message "Retrieving RDS aliases...done")))
|
||||
|
||||
(defun ess-nuke-help-bs ()
|
||||
"Remove ASCII underlining and overstriking performed by ^H codes."
|
||||
;; This function is a modification of nuke-nroff-bs in man.el from the
|
||||
;; standard Emacs 18 lisp library.
|
||||
;; Nuke underlining and overstriking (only by the same letter)
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "\b" nil t)
|
||||
(let* ((preceding (char-after (- (point) 2)))
|
||||
(following (following-char)))
|
||||
(cond ((= preceding following)
|
||||
;; x\bx
|
||||
(delete-char -2))
|
||||
((= preceding ?\_)
|
||||
;; _\b
|
||||
(delete-char -2))
|
||||
((= following ?\_)
|
||||
;; \b_
|
||||
(delete-region (1- (point)) (1+ (point)))))))
|
||||
(goto-char (point-min))
|
||||
(let ((case-fold-search nil)); 'URL' != 'url' ('libcurl: ' on ?capabilities)
|
||||
(while (re-search-forward "\\bURL: " nil t); test with ?rtags
|
||||
;; quick fix for C-x f confusion (getting into tramp)
|
||||
(delete-region (match-beginning 0) (match-end 0))))
|
||||
;; Crunch blank lines
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "\n\n\n\n*" nil t)
|
||||
(replace-match "\n\n"))
|
||||
;; Nuke blanks lines at start.
|
||||
(goto-char (point-min))
|
||||
(skip-chars-forward "\n")
|
||||
(delete-region (point-min) (point)))
|
||||
|
||||
(defun ess-help-underline ()
|
||||
"Replace _^H codes with underline face."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "_" nil t)
|
||||
(backward-delete-char 2)
|
||||
(put-text-property (point) (1+ (point)) 'face 'underline))))
|
||||
|
||||
;;*;; Link to Info
|
||||
(defun ess-goto-info (node)
|
||||
"Display node NODE from `ess-mode' info."
|
||||
(require 'info)
|
||||
(split-window)
|
||||
(Info-goto-node (concat "(ess)" node)))
|
||||
|
||||
|
||||
;; describe object at point
|
||||
|
||||
(defvar-local ess-describe-object-at-point-commands nil
|
||||
"Commands cycled by `ess-describe-object-at-point'.
|
||||
Dialect specific.")
|
||||
|
||||
(defvar ess--descr-o-a-p-commands nil)
|
||||
|
||||
(defun ess-describe-object-at-point ()
|
||||
"Get info for object at point, & display it in an electric buffer or tooltip.
|
||||
If region is active use it instead of the object at point.
|
||||
|
||||
This is an electric command (`ess--execute-electric-command'),
|
||||
which means that you can use the last key to cycle through the
|
||||
action set (in this case `C-e'). After invocation of this command
|
||||
all standard Emacs commands, except those containing 'window' in
|
||||
their names, remove the electric *ess-describe* buffer. Use
|
||||
`other-window' to switch to *ess-describe* window.
|
||||
|
||||
Customize `ess-describe-at-point-method' if you wan to display
|
||||
the description in a tooltip. See also
|
||||
`ess-r-describe-object-at-point-commands' (and similar option for
|
||||
other dialects)."
|
||||
(interactive)
|
||||
(if (not ess-describe-object-at-point-commands)
|
||||
(message "Not implemented for dialect %s" ess-dialect)
|
||||
(ess-force-buffer-current)
|
||||
(let ((map (make-sparse-keymap))
|
||||
(objname (or (and (use-region-p)
|
||||
(buffer-substring-no-properties (point) (mark)))
|
||||
(ess-symbol-at-point)))
|
||||
ess--descr-o-a-p-commands) ;; used in ess--describe-object-at-point
|
||||
(unless objname (error "No object at point "))
|
||||
(define-key map (vector last-command-event) 'ess--describe-object-at-point)
|
||||
;; todo: put digits into the map
|
||||
(let* ((inhibit-quit t) ;; C-g removes the buffer
|
||||
(buf (ess--execute-electric-command
|
||||
map (format "Press %s to cycle"
|
||||
(single-key-description last-command-event))
|
||||
nil nil objname))
|
||||
;; read full command
|
||||
(keys (read-key-sequence-vector ""))
|
||||
(command (and keys (key-binding keys))))
|
||||
(when (and (commandp command)
|
||||
(bufferp buf)
|
||||
(or (not (symbolp command)) ;; kill on lambdas
|
||||
(not (string-match "window" (symbol-name command)))))
|
||||
(kill-buffer buf)) ;; bury does not work here :( (Emacs bug?)
|
||||
(setq unread-command-events
|
||||
(append keys unread-command-events))))))
|
||||
|
||||
(defun ess--describe-object-at-point (_ev objname)
|
||||
(setq ess--descr-o-a-p-commands (or ess--descr-o-a-p-commands
|
||||
(symbol-value ess-describe-object-at-point-commands)))
|
||||
(let* ((com (format (car (pop ess--descr-o-a-p-commands)) objname))
|
||||
(buf (get-buffer-create "*ess-describe*"))
|
||||
pos)
|
||||
(unless (eq ess-describe-at-point-method 'tooltip)
|
||||
;; can take some time for the command to execute
|
||||
(display-buffer buf))
|
||||
(sit-for .01)
|
||||
(ess-command (concat com "\n") buf) ;; erases buf
|
||||
(with-current-buffer buf
|
||||
(goto-char (point-min))
|
||||
(insert (propertize (format "%s:\n\n" com) 'face 'font-lock-string-face))
|
||||
(forward-line -1)
|
||||
(setq pos (point))
|
||||
;; set the keys that we are used to in help mode
|
||||
(special-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(ansi-color-apply-on-region (point-min) (point-max))))
|
||||
(if (eq ess-describe-at-point-method 'tooltip)
|
||||
(ess-tooltip-show-at-point
|
||||
(with-current-buffer buf (buffer-string)) 0 30)
|
||||
(display-buffer buf)
|
||||
(set-window-point (get-buffer-window buf) pos) ;; don't move window point
|
||||
buf)))
|
||||
|
||||
(with-no-warnings
|
||||
;; We're just backporting here, don't care about compiler warnings
|
||||
(defalias 'ess-display-buffer-reuse-mode-window
|
||||
;; TODO: Remove once we drop support for Emacs 25
|
||||
(if (fboundp 'display-buffer-reuse-mode-window)
|
||||
'display-buffer-reuse-mode-window
|
||||
(lambda (buffer alist)
|
||||
(let* ((alist-entry (assq 'reusable-frames alist))
|
||||
(alist-mode-entry (assq 'mode alist))
|
||||
(frames (cond (alist-entry (cdr alist-entry))
|
||||
((if (eq pop-up-frames 'graphic-only)
|
||||
(display-graphic-p)
|
||||
pop-up-frames)
|
||||
0)
|
||||
(display-buffer-reuse-frames 0)
|
||||
(t (last-nonminibuffer-frame))))
|
||||
(inhibit-same-window-p (cdr (assq 'inhibit-same-window alist)))
|
||||
(windows (window-list-1 nil 'nomini frames))
|
||||
(buffer-mode (with-current-buffer buffer major-mode))
|
||||
(allowed-modes (if alist-mode-entry
|
||||
(cdr alist-mode-entry)
|
||||
buffer-mode))
|
||||
(curwin (selected-window))
|
||||
(curframe (selected-frame)))
|
||||
(unless (listp allowed-modes)
|
||||
(setq allowed-modes (list allowed-modes)))
|
||||
(let (same-mode-same-frame
|
||||
same-mode-other-frame
|
||||
derived-mode-same-frame
|
||||
derived-mode-other-frame)
|
||||
(dolist (window windows)
|
||||
(let ((mode?
|
||||
(with-current-buffer (window-buffer window)
|
||||
(cond ((memq major-mode allowed-modes)
|
||||
'same)
|
||||
((derived-mode-p allowed-modes)
|
||||
'derived)))))
|
||||
(when (and mode?
|
||||
(not (and inhibit-same-window-p
|
||||
(eq window curwin))))
|
||||
(push window (if (eq curframe (window-frame window))
|
||||
(if (eq mode? 'same)
|
||||
same-mode-same-frame
|
||||
derived-mode-same-frame)
|
||||
(if (eq mode? 'same)
|
||||
same-mode-other-frame
|
||||
derived-mode-other-frame))))))
|
||||
(let ((window (car (nconc same-mode-same-frame
|
||||
same-mode-other-frame
|
||||
derived-mode-same-frame
|
||||
derived-mode-other-frame))))
|
||||
(when (window-live-p window)
|
||||
(prog1 (window--display-buffer buffer window 'reuse alist)
|
||||
(unless (cdr (assq 'inhibit-switch-frame alist))
|
||||
(window--maybe-raise-frame (window-frame window))))))))))))
|
||||
|
||||
(provide 'ess-help)
|
||||
;;; ess-help.el ends here
|
||||
2974
lisp/ess/ess-inf.el
Normal file
2974
lisp/ess/ess-inf.el
Normal file
File diff suppressed because it is too large
Load Diff
257
lisp/ess/ess-jags-d.el
Normal file
257
lisp/ess/ess-jags-d.el
Normal file
@@ -0,0 +1,257 @@
|
||||
;;; ess-jags-d.el --- ESS[JAGS] dialect -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Rodney Sparapani
|
||||
;; Created: 13 March 2008
|
||||
;; Maintainer: ESS Core Team <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-bugs-d)
|
||||
(require 'ess-utils)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-mode)
|
||||
|
||||
(defvar ess-jags-command "jags" "Default JAGS program in PATH.")
|
||||
(make-local-variable 'ess-jags-command)
|
||||
|
||||
(defvar ess-jags-monitor '("") "Default list of variables to monitor.")
|
||||
(make-local-variable 'ess-jags-monitor)
|
||||
|
||||
(defvar ess-jags-thin 1 "Default thinning parameter.")
|
||||
(make-local-variable 'ess-jags-thin)
|
||||
|
||||
(defvar ess-jags-chains 1 "Default number of chains.")
|
||||
(make-local-variable 'ess-jags-chains)
|
||||
|
||||
(defvar ess-jags-burnin 10000 "Default burn-in.")
|
||||
(make-local-variable 'ess-jags-burnin)
|
||||
|
||||
(defvar ess-jags-update 10000 "Default number of updates after burnin.")
|
||||
(make-local-variable 'ess-jags-update)
|
||||
|
||||
(defvar ess-jags-system t "Default whether JAGS recognizes the system command.")
|
||||
|
||||
(defvar ess-jags-font-lock-keywords
|
||||
(list
|
||||
;; .jag files
|
||||
(cons "#.*\n" font-lock-comment-face)
|
||||
|
||||
(cons "^[ \t]*\\(model\\|var\\)\\>"
|
||||
font-lock-keyword-face)
|
||||
|
||||
(cons (concat "\\<d\\(bern\\|beta\\|bin\\|cat\\|chisq\\|"
|
||||
"dexp\\|dirch\\|exp\\|\\(gen[.]\\)?gamma\\|hyper\\|"
|
||||
"interval\\|lnorm\\|logis\\|mnorm\\|mt\\|multi\\|"
|
||||
"negbin\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
|
||||
"unif\\|weib\\|wish\\)[ \t\n]*(")
|
||||
font-lock-constant-face)
|
||||
|
||||
(cons (concat "\\<\\(abs\\|cos\\|dim\\|\\(i\\)?cloglog\\|equals\\|"
|
||||
"exp\\|for\\|inprod\\|interp[.]line\\|inverse\\|length\\|"
|
||||
"\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|max\\|mean\\|"
|
||||
"mexp\\|min\\|phi\\|pow\\|probit\\|prod\\|rank\\|round\\|"
|
||||
"sd\\|sin\\|sort\\|sqrt\\|step\\|sum\\|t\\|trunc\\|T\\)[ \t\n]*(")
|
||||
font-lock-function-name-face)
|
||||
|
||||
;; .jmd files
|
||||
(cons (concat "\\<\\(adapt\\|cd\\|clear\\|coda\\|data\\|dir\\|"
|
||||
"exit\\|in\\(itialize\\)?\\|load\\|model\\|monitors\\|parameters\\|"
|
||||
"pwd\\|run\\|s\\(amplers\\|ystem\\)\\|to\\|update\\)[ \t\n]")
|
||||
font-lock-keyword-face)
|
||||
|
||||
(cons "\\<\\(compile\\|monitor\\)[, \t\n]"
|
||||
font-lock-keyword-face)
|
||||
|
||||
(cons "[, \t\n]\\(by\\|chain\\|nchains\\|stem\\|thin\\|type\\)[ \t\n]*("
|
||||
font-lock-function-name-face)
|
||||
)
|
||||
"ESS[JAGS]: Font lock keywords."
|
||||
)
|
||||
|
||||
(defun ess-jags-switch-to-suffix (suffix &optional jags-chains jags-monitor jags-thin
|
||||
jags-burnin jags-update)
|
||||
"ESS[JAGS]: Switch to file with suffix."
|
||||
(find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
|
||||
|
||||
(if (equal 0 (buffer-size)) (progn
|
||||
(if (equal ".jag" suffix) (progn
|
||||
(insert "var ;\n")
|
||||
(insert "model {\n")
|
||||
(insert " for (i in 1:N) {\n \n")
|
||||
(insert " }\n")
|
||||
(insert "}\n")
|
||||
(insert "#Local Variables" ":\n")
|
||||
(insert "#ess-jags-chains:1\n")
|
||||
(insert "#ess-jags-monitor:(\"\")\n")
|
||||
(insert "#ess-jags-thin:1\n")
|
||||
(insert "#ess-jags-burnin:10000\n")
|
||||
(insert "#ess-jags-update:10000\n")
|
||||
(insert "#End:\n")
|
||||
))
|
||||
|
||||
(if (equal ".jmd" suffix) (let
|
||||
((ess-jags-temp-chains "") (ess-jags-temp-monitor "") (ess-jags-temp-chain ""))
|
||||
|
||||
(if jags-chains (setq ess-jags-chains jags-chains))
|
||||
(if jags-monitor (setq ess-jags-monitor jags-monitor))
|
||||
(if jags-thin (setq ess-jags-thin jags-thin))
|
||||
|
||||
(setq ess-jags-temp-chains
|
||||
(concat "compile, nchains(" (format "%d" ess-jags-chains) ")\n"))
|
||||
|
||||
(setq jags-chains ess-jags-chains)
|
||||
|
||||
(while (< 0 jags-chains)
|
||||
(setq ess-jags-temp-chains
|
||||
(concat ess-jags-temp-chains
|
||||
"parameters ## \"" ess-bugs-file-root
|
||||
".##" (format "%d" jags-chains) "\", chain("
|
||||
(format "%d" jags-chains) ")\n"))
|
||||
(setq jags-chains (- jags-chains 1)))
|
||||
|
||||
(setq ess-jags-temp-monitor "")
|
||||
|
||||
(while (and (listp ess-jags-monitor) (consp ess-jags-monitor))
|
||||
(if (not (string-equal "" (car ess-jags-monitor)))
|
||||
(setq ess-jags-temp-monitor
|
||||
(concat ess-jags-temp-monitor "monitor "
|
||||
(car ess-jags-monitor) ", thin(" (format "%d" ess-jags-thin) ")\n")))
|
||||
(setq ess-jags-monitor (cdr ess-jags-monitor)))
|
||||
|
||||
(insert "model in \"" ess-bugs-file-root ".jag\"\n")
|
||||
(insert "data in \"" ess-bugs-file-root ".jdt\"\n")
|
||||
(insert (ess-replace-in-string ess-jags-temp-chains "##" "in"))
|
||||
(insert "initialize\n")
|
||||
;(insert "update " (format "%d" (* jags-thin jags-burnin)) "\n")
|
||||
(insert "update " (format "%d" jags-burnin) "\n")
|
||||
(insert ess-jags-temp-monitor)
|
||||
(insert "update " (format "%d" (* jags-thin jags-update)) "\n")
|
||||
(insert (ess-replace-in-string
|
||||
(ess-replace-in-string ess-jags-temp-chains
|
||||
"compile, nchains([0-9]+)" "#") "##" "to"))
|
||||
(insert "coda "
|
||||
;(if ess-microsoft-p (if (w32-shell-dos-semantics) "*" "\\*") "\\*")
|
||||
"*, stem(\"" ess-bugs-file-root "\")\n")
|
||||
|
||||
(if ess-jags-system (progn
|
||||
(insert "system rm -f " ess-bugs-file-root ".ind\n")
|
||||
(insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
|
||||
|
||||
(setq jags-chains ess-jags-chains)
|
||||
|
||||
(while (< 0 jags-chains)
|
||||
(setq ess-jags-temp-chain (format "%d" jags-chains))
|
||||
|
||||
;.txt not recognized by BOA and impractical to over-ride
|
||||
(insert "system rm -f " ess-bugs-file-root ess-jags-temp-chain ".out\n")
|
||||
(insert "system ln -s " ess-bugs-file-root "chain" ess-jags-temp-chain ".txt "
|
||||
ess-bugs-file-root ess-jags-temp-chain ".out\n")
|
||||
(setq jags-chains (- jags-chains 1)))))
|
||||
|
||||
(insert "exit\n")
|
||||
(insert "Local Variables" ":\n")
|
||||
(insert "ess-jags-chains:" (format "%d" ess-jags-chains) "\n")
|
||||
(insert "ess-jags-command:\"jags\"\n")
|
||||
(insert "End:\n")
|
||||
))
|
||||
))
|
||||
)
|
||||
|
||||
(defun ess-jags-na-jmd (jags-command)
|
||||
"ESS[JAGS]: Perform the Next-Action for .jmd."
|
||||
;(ess-save-and-set-local-variables)
|
||||
(if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jmd")
|
||||
;else
|
||||
(shell)
|
||||
(ess-sleep)
|
||||
|
||||
(if (when (fboundp 'w32-shell-dos-semantics)
|
||||
(w32-shell-dos-semantics))
|
||||
(if (string-equal ":" (substring ess-bugs-file 1 2))
|
||||
(progn
|
||||
(insert (substring ess-bugs-file 0 2))
|
||||
(comint-send-input)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(insert "cd \"" ess-bugs-file-dir "\"")
|
||||
(comint-send-input)
|
||||
|
||||
; (let ((ess-jags-temp-chains ""))
|
||||
;
|
||||
; (while (< 0 jags-chains)
|
||||
; (setq ess-jags-temp-chains
|
||||
; (concat (format "%d " jags-chains) ess-jags-temp-chains))
|
||||
; (setq jags-chains (- jags-chains 1)))
|
||||
|
||||
(insert ess-bugs-batch-pre-command " " jags-command " "
|
||||
ess-bugs-file-root ".jmd "
|
||||
|
||||
(if (or (equal shell-file-name "/bin/csh")
|
||||
(equal shell-file-name "/bin/tcsh")
|
||||
(equal shell-file-name "/bin/zsh")
|
||||
(equal shell-file-name "/bin/bash"))
|
||||
(concat ">& " ess-bugs-file-root ".jog ")
|
||||
;else
|
||||
"> " ess-bugs-file-root ".jog 2>&1 ")
|
||||
|
||||
; ;.txt not recognized by BOA and impractical to over-ride
|
||||
; "&& (rm -f " ess-bugs-file-root ".ind; "
|
||||
; "ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind; "
|
||||
; "for i in " ess-jags-temp-chains "; do; "
|
||||
; "rm -f " ess-bugs-file-root "$i.out; "
|
||||
; "ln -s " ess-bugs-file-root "chain$i.txt " ess-bugs-file-root "$i.out; done) "
|
||||
|
||||
ess-bugs-batch-post-command)
|
||||
|
||||
(comint-send-input)
|
||||
))
|
||||
|
||||
(defun ess-jags-na-bug ()
|
||||
"ESS[JAGS]: Perform Next-Action for .jag"
|
||||
|
||||
(if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jag")
|
||||
;else
|
||||
(ess-save-and-set-local-variables)
|
||||
(ess-jags-switch-to-suffix ".jmd"
|
||||
ess-jags-chains ess-jags-monitor ess-jags-thin ess-jags-burnin ess-jags-update))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-jags-mode ess-bugs-mode "ESS[JAGS]"
|
||||
"Major mode for JAGS."
|
||||
(setq-local comment-start "#")
|
||||
(setq font-lock-defaults '(ess-jags-font-lock-keywords nil t))
|
||||
(setq ess-language "S") ; mimic S for ess-smart-underscore
|
||||
(unless (and (fboundp 'w32-shell-dos-semantics)
|
||||
(w32-shell-dos-semantics))
|
||||
(add-hook 'comint-output-filter-functions 'ess-bugs-exit-notify-sh))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Jj][Aa][Gg]\\'" . ess-jags-mode))
|
||||
|
||||
(provide 'ess-jags-d)
|
||||
|
||||
;;; ess-jags-d.el ends here
|
||||
471
lisp/ess/ess-julia.el
Normal file
471
lisp/ess/ess-julia.el
Normal file
@@ -0,0 +1,471 @@
|
||||
;; ess-julia.el --- ESS julia mode and inferior interaction -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2012-2020 Free Software Foundation, Inc.
|
||||
;; Author: Vitalie Spinu
|
||||
;; Maintainer: Vitalie Spinu
|
||||
;; Created: 02-04-2012 (ESS 12.03)
|
||||
;; Keywords: ESS, julia
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Customize inferior-julia-program to point to your julia binary
|
||||
;; and start the inferior with M-x julia.
|
||||
|
||||
;; As of Sept 2015, this file depends heavily on julia-mode.el from the Julia
|
||||
;; sources. If you install ESS using `make', this will work fine, otherwise
|
||||
;; ensure that julia-mode.el is on your path before loading this file.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-help)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-r-mode)
|
||||
(require 'ess-utils)
|
||||
;; Don't require `julia-mode' to compile this file.
|
||||
(when t (require 'julia-mode))
|
||||
(declare-function julia-mode "julia-mode" ())
|
||||
(declare-function julia-latexsub "julia-mode" ())
|
||||
(defvar julia-mode-syntax-table)
|
||||
|
||||
(defvar ac-prefix)
|
||||
(declare-function company-in-string-or-comment "company")
|
||||
(declare-function company-doc-buffer "company")
|
||||
|
||||
(defcustom inferior-julia-args ""
|
||||
"String of arguments (see `julia --help') used when starting julia."
|
||||
:group 'ess-julia
|
||||
:type 'string)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'cl-lib))
|
||||
|
||||
(defun ess-julia-send-string-function (process string _visibly)
|
||||
"Send the Julia STRING to the PROCESS.
|
||||
VISIBLY is not currently used."
|
||||
(let ((file (concat temporary-file-directory "julia_eval_region.jl")))
|
||||
(with-temp-file file
|
||||
(insert string))
|
||||
(process-send-string process (format ess-load-command file))))
|
||||
|
||||
|
||||
;;; HELP
|
||||
(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "julia"))
|
||||
(append (with-current-buffer (ess-command "ESS.all_help_topics()\n")
|
||||
(split-string (buffer-string) "\n"))
|
||||
(ess-julia--get-objects proc)))
|
||||
|
||||
(defun ess-julia--retrive-topics (url)
|
||||
(with-current-buffer (url-retrieve-synchronously url)
|
||||
(require 'url)
|
||||
(goto-char (point-min))
|
||||
(let (out)
|
||||
(while (re-search-forward
|
||||
"toctext[ \"]+href=\"\\([^>]+\\)\">\\([^<]+\\)</a" nil t)
|
||||
(push (propertize (match-string 2)
|
||||
:manual (concat url (match-string 1)))
|
||||
out))
|
||||
(kill-buffer)
|
||||
(nreverse out))))
|
||||
|
||||
(defvar ess-julia--manual-topics nil)
|
||||
(cl-defmethod ess--manual-lookup-override (&context (ess-dialect "julia"))
|
||||
"Look up topics at https://docs.julialang.org/en/latest/manual/."
|
||||
(let* ((pages (or ess-julia--manual-topics
|
||||
(setq ess-julia--manual-topics
|
||||
(ess-julia--retrive-topics
|
||||
"https://docs.julialang.org/en/latest/"))))
|
||||
(page (ess-completing-read "Lookup:" pages nil t)))
|
||||
(browse-url (get-text-property 1 :manual page))))
|
||||
|
||||
(defun ess-julia-input-sender (proc string)
|
||||
"Function to send PROC STRING submitted by user.
|
||||
See `comint-input-sender'."
|
||||
(save-current-buffer
|
||||
(let* ((help-?-regexp "^ *\\(?:\\(?1: *?\\? *\\)\\(?2:.+\\)\\)")
|
||||
(help-?-match (string-match help-?-regexp string)))
|
||||
(cond (help-?-match
|
||||
(ess-display-help-on-object (match-string 2 string))
|
||||
(process-send-string proc "\n"))
|
||||
(t ;; normal command
|
||||
(inferior-ess-input-sender proc string))))))
|
||||
|
||||
(cl-defmethod ess-installed-packages (&context (ess-dialect "julia"))
|
||||
"Return list of installed julia packages."
|
||||
;; FIXME: This doesn't work if the user hasn't done "using Pkg" yet
|
||||
(ess-get-words-from-vector "keys(Pkg.installed())\n"))
|
||||
|
||||
(cl-defmethod ess-load-library--override (pack &context (ess-dialect "julia"))
|
||||
(ess-eval-linewise (format "using %s\n" pack)))
|
||||
|
||||
|
||||
;;; COMPLETION
|
||||
(defun ess-julia-latexsub-completion ()
|
||||
"Complete latex input, and return format required by `completion-at-point-functions'."
|
||||
(if (julia-latexsub) ; julia-latexsub returns nil if it performed a completion, the point otherwise
|
||||
nil
|
||||
(lambda () t) ;; bypass other completion methods
|
||||
))
|
||||
|
||||
(defun ess-julia-object-completion ()
|
||||
"Return completions at point in a format required by `completion-at-point-functions'."
|
||||
(let ((proc (ess-get-next-available-process ess-dialect t))
|
||||
(beg (ess-symbol-start)))
|
||||
(if proc
|
||||
(when beg
|
||||
(let* ((prefix (buffer-substring-no-properties beg (point)))
|
||||
(obj (and (string-match "\\(.*\\)\\..*$" prefix)
|
||||
(match-string 1 prefix)))
|
||||
(beg (if obj
|
||||
(+ beg 1 (length obj))
|
||||
beg)))
|
||||
(list beg (point)
|
||||
(nreverse (mapcar 'car (ess-julia--get-objects proc obj)))
|
||||
:exclusive 'no)))
|
||||
(when (string-match "complet" (symbol-name last-command))
|
||||
(message "No ESS process of dialect %s started" ess-dialect)
|
||||
nil))))
|
||||
|
||||
(defun ess-julia-objects (prefix &optional proc)
|
||||
"Given PREFIX get all cached objects from PROC."
|
||||
(when prefix
|
||||
(let ((proc (or proc (ess-get-next-available-process nil t))))
|
||||
(if (string-match "\\(.*\\)\\..*$" prefix)
|
||||
(let ((module (match-string 1 prefix)))
|
||||
(mapcar (lambda (el) (concat module "." (car el)))
|
||||
(ess-julia--get-objects proc module)))
|
||||
(ess-julia--get-objects proc)))))
|
||||
|
||||
(defun ess-julia--get-objects (&optional proc obj)
|
||||
"Return all available objects.
|
||||
Local caching might be used. If MODULE is givven, return only
|
||||
objects from that MODULE."
|
||||
(setq proc (or proc (ess-get-process)))
|
||||
(when (stringp proc)
|
||||
(setq proc (get-process proc)))
|
||||
(when (process-live-p proc)
|
||||
(let ((objects (process-get proc 'objects)))
|
||||
(if (process-get proc 'busy)
|
||||
(if obj
|
||||
(assoc obj objects)
|
||||
(process-get proc 'objects))
|
||||
(if obj
|
||||
(or (cdr (assoc obj objects))
|
||||
;; don't cache composite objects and datatypes
|
||||
(ess-julia--get-components proc obj))
|
||||
;; this segment is entered when user completon at top level is
|
||||
;; requested, either Tab or AC. Hence Main is always updated.
|
||||
(let ((modules (ess-get-words-from-vector
|
||||
"ESS.main_modules()\n" nil nil proc))
|
||||
(loc (process-get proc 'last-objects-cache))
|
||||
(lev (process-get proc 'last-eval)))
|
||||
(prog1
|
||||
(apply #'nconc
|
||||
(mapcar
|
||||
(lambda (mod)
|
||||
;; we are caching all modules, and reinit Main every
|
||||
;; time user enters commands
|
||||
(copy-sequence
|
||||
(or (and (or (not (equal mod "Main"))
|
||||
(ignore-errors (time-less-p lev loc)))
|
||||
(cdr (assoc mod objects)))
|
||||
(ess-julia--get-components proc mod t))))
|
||||
modules))
|
||||
(process-put proc 'last-objects-cache (current-time)))))))))
|
||||
|
||||
(defun ess-julia--get-components (proc obj &optional cache?)
|
||||
(with-current-buffer (ess-command (format "ESS.components(%s)\n" obj)
|
||||
nil nil nil nil proc)
|
||||
(goto-char (point-min))
|
||||
(let (list)
|
||||
(while (re-search-forward
|
||||
"^\\([^ \t\n]+\\) +\\([^ \t\n]+\\)$" nil t)
|
||||
(push (cons (match-string 1) (match-string 2)) list))
|
||||
(when cache?
|
||||
(let ((objects (process-get proc 'objects)))
|
||||
(push (cons obj list) objects)
|
||||
(process-put proc 'objects objects)))
|
||||
list)))
|
||||
|
||||
(defun ess-julia-get-object-help-string (sym)
|
||||
"Help string for ac."
|
||||
(let ((proc (ess-get-next-available-process nil t)))
|
||||
(if (null proc)
|
||||
"No free ESS process found"
|
||||
(let ((buf (get-buffer-create " *ess-command-output*")))
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(ess-with-current-buffer buf
|
||||
(ess--flush-help-into-current-buffer sym nil)))
|
||||
(with-current-buffer buf
|
||||
(ess-help-underline)
|
||||
(goto-char (point-min))
|
||||
(buffer-string))))))
|
||||
|
||||
(defvar ac-source-ess-julia-objects
|
||||
'((prefix . ess-symbol-start)
|
||||
(requires . 2)
|
||||
(candidates . ess-ac-julia-objects)
|
||||
(document . ess-julia-get-object-help-string))
|
||||
"Auto-completion source for julia objects.")
|
||||
|
||||
(defun ess-ac-julia-objects ()
|
||||
(require 'auto-complete)
|
||||
(ess-julia-objects ac-prefix))
|
||||
|
||||
(declare-function company-begin-backend "company.el")
|
||||
|
||||
(defun company-ess-julia-objects (command &optional arg &rest ignored)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-ess-julia-objects))
|
||||
(prefix (unless (company-in-string-or-comment)
|
||||
(let ((start (ess-symbol-start)))
|
||||
(when start (buffer-substring-no-properties start (point))))))
|
||||
(candidates (let ((proc (ess-get-next-available-process)))
|
||||
(when proc
|
||||
(all-completions arg (mapcar (lambda (x) (or (car-safe x) x))
|
||||
(ess-julia-objects arg proc))))))
|
||||
(doc-buffer (company-doc-buffer (ess-julia-get-object-help-string arg)))))
|
||||
|
||||
|
||||
;;; ERRORS
|
||||
(defvar ess-julia-error-regexp-alist '(ess-julia-in ess-julia-at ess-julia-while-load)
|
||||
"List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
|
||||
|
||||
(add-to-list 'compilation-error-regexp-alist-alist
|
||||
'(ess-julia-in "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
|
||||
(add-to-list 'compilation-error-regexp-alist-alist
|
||||
'(ess-julia-at "^\\S-+\\s-+\\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
|
||||
(add-to-list 'compilation-error-regexp-alist-alist
|
||||
'(ess-julia-while-load "^\\s-*\\(while loading\\s-\\(.*\\), in .* on line +\\([0-9]+\\)\\)" 2 3 nil 2 1))
|
||||
|
||||
|
||||
;;; ELDOC
|
||||
(defun ess-julia-eldoc-function ()
|
||||
"Return the doc string, or nil.
|
||||
If an ESS process is not associated with the buffer, do not try
|
||||
to look up any doc strings. Honors `eldoc-echo-area-use-multiline-p'."
|
||||
(when (and ess-can-eval-in-background
|
||||
(ess-process-live-p)
|
||||
(not (ess-process-get 'busy)))
|
||||
(let ((funname (or (and ess-eldoc-show-on-symbol ;; aggressive completion
|
||||
(symbol-name (ess-symbol-at-point)))
|
||||
(car (ess--fn-name-start))))
|
||||
(multiline (eq t eldoc-echo-area-use-multiline-p)))
|
||||
(when funname
|
||||
(let* ((args (copy-sequence (nth 2 (ess-function-arguments funname))))
|
||||
(W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
|
||||
(doc (concat (propertize funname 'face font-lock-function-name-face) ": ")))
|
||||
(when args
|
||||
(setq args (sort args (lambda (s1 s2)
|
||||
(< (length s1) (length s2)))))
|
||||
(setq doc (concat doc (pop args)))
|
||||
(while (and args (or multiline (< (+ (length doc) (length (car args))) W)))
|
||||
(setq doc (concat doc " " (pop args))))
|
||||
(when (and args (< (length doc) W))
|
||||
(setq doc (concat doc " {--}")))
|
||||
doc))))))
|
||||
|
||||
|
||||
;;; CORE
|
||||
(defvar ess-julia-customize-alist
|
||||
'((inferior-ess-primary-prompt . "\\w*> ")
|
||||
(inferior-ess-secondary-prompt . nil)
|
||||
(inferior-ess-prompt . "\\w*> ")
|
||||
(ess-local-customize-alist . 'ess-julia-customize-alist)
|
||||
(inferior-ess-program . inferior-julia-program)
|
||||
(ess-load-command . "include(expanduser(\"%s\"))\n")
|
||||
(ess-funargs-command . "ESS.fun_args(\"%s\")\n")
|
||||
(ess-dump-error-re . "in \\w* at \\(.*\\):[0-9]+")
|
||||
(ess-error-regexp . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
|
||||
(ess-error-regexp-alist . ess-julia-error-regexp-alist)
|
||||
(ess-mode-completion-syntax-table . ess-julia-completion-syntax-table)
|
||||
;; (inferior-ess-objects-command . inferior-ess-r-objects-command)
|
||||
;; (inferior-ess-search-list-command . "search()\n")
|
||||
(inferior-ess-help-command . "ESS.help(\"%s\")\n")
|
||||
;; (inferior-ess-help-command . "help(\"%s\")\n")
|
||||
(ess-language . "julia")
|
||||
(ess-dialect . "julia")
|
||||
(ess-suffix . "jl")
|
||||
(ess-dump-filename-template . (replace-regexp-in-string
|
||||
"S$" ess-suffix ; in the one from custom:
|
||||
ess-dump-filename-template-proto))
|
||||
(ess-mode-editing-alist . nil)
|
||||
(ess-change-sp-regexp . nil );ess-r-change-sp-regexp)
|
||||
(ess-help-sec-regex . ess-help-r-sec-regex)
|
||||
(ess-help-sec-keys-alist . ess-help-r-sec-keys-alist)
|
||||
(ess-function-pattern . ess-r-function-pattern)
|
||||
(ess-object-name-db-file . "ess-jl-namedb.el" )
|
||||
(ess-smart-operators . ess-r-smart-operators)
|
||||
(inferior-ess-exit-command . "exit()\n")
|
||||
;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
|
||||
(inferior-ess-language-start . nil)
|
||||
(ess-STERM . "iESS")
|
||||
(ess-editor . ess-r-editor)
|
||||
(ess-pager . ess-r-pager)
|
||||
(ess-getwd-command . "pwd()\n")
|
||||
(ess-setwd-command . "cd(expanduser(\"%s\"))\n"))
|
||||
"Variables to customize for Julia.")
|
||||
|
||||
(cl-defmethod ess--help-web-search-override (cmd &context (ess-dialect "julia"))
|
||||
"Offer to search the web for a Julia command."
|
||||
(browse-url (format "https://docs.julialang.org/en/latest/search/?q=%s" cmd)))
|
||||
|
||||
(defvar ess-julia-completion-syntax-table
|
||||
(let ((table (copy-syntax-table ess-r-mode-syntax-table)))
|
||||
(modify-syntax-entry ?. "_" table)
|
||||
;; (modify-syntax-entry ?: "_" table)
|
||||
;; (modify-syntax-entry ?$ "_" table)
|
||||
(modify-syntax-entry ?@ "_" table)
|
||||
table)
|
||||
"Syntax table used for completion and help symbol lookup.
|
||||
It makes underscores and dots word constituent chars.")
|
||||
|
||||
(cl-defmethod ess-help-commands (&context (ess-dialect "julia"))
|
||||
'((packages . "_ess_list_categories()\n")
|
||||
(package-index . "_ess_print_index(\"%s\")\n")
|
||||
(index-keyword-reg . "^\\(.*+\\):$*")
|
||||
(index-start-reg . ":")))
|
||||
|
||||
(defvar ess-julia-mode-syntax-table (copy-syntax-table julia-mode-syntax-table))
|
||||
|
||||
(defvar ess-julia-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map ess-mode-map)
|
||||
map)
|
||||
"Keymap for `ess-julia-mode'.")
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-julia-mode julia-mode "ESS[julia]"
|
||||
"Major mode for julia files."
|
||||
:group 'ess-Julia
|
||||
(setq-local ess-local-customize-alist ess-julia-customize-alist)
|
||||
(setq ess-dialect "julia")
|
||||
(ess-setq-vars-local ess-julia-customize-alist)
|
||||
;; eldoc
|
||||
(if (boundp 'eldoc-documentation-functions)
|
||||
(add-hook 'eldoc-documentation-functions #'ess-julia-eldoc-function nil t)
|
||||
(add-function :before-until (local 'eldoc-documentation-function)
|
||||
#'ess-julia-eldoc-function))
|
||||
(when ess-use-eldoc (eldoc-mode))
|
||||
;; auto-complete
|
||||
(ess--setup-auto-complete '(ac-source-ess-julia-objects))
|
||||
;; company
|
||||
(ess--setup-company '(company-ess-julia-objects))
|
||||
;; for emacs >= 24
|
||||
(remove-hook 'completion-at-point-functions 'ess-filename-completion 'local) ;; should be first
|
||||
(add-hook 'completion-at-point-functions 'ess-julia-object-completion nil 'local)
|
||||
(add-hook 'completion-at-point-functions 'ess-filename-completion nil 'local)
|
||||
(add-hook 'completion-at-point-functions 'ess-julia-latexsub-completion nil 'local)
|
||||
(if (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
|
||||
|
||||
;; Inferior mode
|
||||
(defvar inferior-ess-julia-mode-syntax-table
|
||||
(copy-syntax-table ess-julia-mode-syntax-table)
|
||||
"Syntax table for `inferior-ess-julia-mode'.")
|
||||
|
||||
(define-derived-mode inferior-ess-julia-mode inferior-ess-mode "iESS[julia]"
|
||||
"Major mode for inferior julia processes."
|
||||
:group 'ess-Julia
|
||||
(ess-setq-vars-local ess-julia-customize-alist)
|
||||
(setq-local comint-use-prompt-regexp t)
|
||||
(setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
|
||||
(setq ess-dialect "julia")
|
||||
;; eldoc
|
||||
(if (boundp 'eldoc-documentation-functions)
|
||||
(add-hook 'eldoc-documentation-functions #'ess-julia-eldoc-function nil t)
|
||||
(add-function :before-until (local 'eldoc-documentation-function)
|
||||
#'ess-julia-eldoc-function))
|
||||
(when ess-use-eldoc (eldoc-mode))
|
||||
;; auto-complete
|
||||
(ess--setup-auto-complete '(ac-source-ess-julia-objects) t)
|
||||
;; company
|
||||
(ess--setup-company '(company-ess-julia-objects) t)
|
||||
(remove-hook 'completion-at-point-functions 'ess-filename-completion 'local) ;; should be first
|
||||
(add-hook 'completion-at-point-functions 'ess-julia-object-completion nil 'local)
|
||||
(add-hook 'completion-at-point-functions 'ess-filename-completion nil 'local)
|
||||
(add-hook 'completion-at-point-functions 'ess-julia-latexsub-completion nil 'local)
|
||||
(setq comint-input-sender #'ess-julia-input-sender))
|
||||
|
||||
(defvar ess-julia-mode-hook nil)
|
||||
(defvar ess-julia-post-run-hook nil
|
||||
"Functions run in process buffer after starting julia process.")
|
||||
|
||||
;;;###autoload
|
||||
(defun run-ess-julia (&optional start-args)
|
||||
"Start an inferior julia process.
|
||||
Optional prefix START-ARGS (\\[universal-argument]) allows to set
|
||||
command line arguments, such as --load=<file>. This should be OS
|
||||
agnostic. If you have certain command line arguments that should
|
||||
always be passed to julia, put them in the variable
|
||||
`inferior-julia-args'."
|
||||
(interactive "P")
|
||||
;; get settings, notably inferior-julia-program :
|
||||
(if (null inferior-julia-program)
|
||||
(error "'inferior-julia-program' does not point to 'julia' or 'julia-basic' executable")
|
||||
(ess-write-to-dribble-buffer ;; for debugging only
|
||||
(format
|
||||
"\n(julia): ess-dialect=%s, buf=%s, start-arg=%s\n current-prefix-arg=%s\n"
|
||||
ess-dialect (current-buffer) start-args current-prefix-arg))
|
||||
(let* ((jl-start-args
|
||||
(concat inferior-julia-args " " ; add space just in case
|
||||
(if start-args
|
||||
(read-string
|
||||
(concat "Starting Args"
|
||||
(if inferior-julia-args
|
||||
(concat " [other than '" inferior-julia-args "']"))
|
||||
" ? "))
|
||||
nil))))
|
||||
(let ((inf-buf (inferior-ess jl-start-args ess-julia-customize-alist)))
|
||||
(with-current-buffer inf-buf
|
||||
(ess--tb-start)
|
||||
;; Remove ` from julia's logo
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "`" nil t)
|
||||
(replace-match "'"))
|
||||
;; Remove an offending unmatched parenthesis
|
||||
(goto-char (point-min))
|
||||
(forward-line 4)
|
||||
(when (re-search-forward "(" nil t)
|
||||
(replace-match "|"))
|
||||
(goto-char (point-max))
|
||||
;; --> julia helpers from ../etc/ess-julia.jl :
|
||||
(ess--inject-code-from-file (format "%sess-julia.jl" ess-etc-directory))
|
||||
(run-mode-hooks 'ess-julia-post-run-hook))
|
||||
inf-buf))))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'julia #'run-ess-julia)
|
||||
|
||||
(cl-defmethod ess--help-major-mode (&context (ess-dialect "julia"))
|
||||
(ess-julia-help-mode))
|
||||
|
||||
(define-derived-mode ess-julia-help-mode ess-help-mode "ESS[Julia] Help"
|
||||
"Major mode for Julia documentation."
|
||||
:group 'ess-help
|
||||
(let ((inhibit-read-only t))
|
||||
;; Julia help buffers can contain color if julia starts with
|
||||
;; --color=yes
|
||||
(ansi-color-apply-on-region (point-min) (point-max))))
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode))
|
||||
|
||||
(provide 'ess-julia)
|
||||
;;; ess-julia.el ends here
|
||||
682
lisp/ess/ess-mode.el
Normal file
682
lisp/ess/ess-mode.el
Normal file
@@ -0,0 +1,682 @@
|
||||
;;; ess-mode.el -- Emacs Speaks Statistics root mode. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
;; This file defines ess-mode from which other modes (like ess-r-mode)
|
||||
;; derive.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x))
|
||||
(require 'ess-inf)
|
||||
|
||||
;; Silence the byte compiler
|
||||
(declare-function run-ess-r "ess-r-mode" (&optional start-args))
|
||||
(declare-function S+ "ess-sp6-d" (&optional proc-name))
|
||||
(declare-function SAS "ess-sas-d" ())
|
||||
|
||||
;; FIXME:This one should not be necessary
|
||||
(declare-function ess-display-help-on-object "ess-help" (object &optional command))
|
||||
|
||||
;; ESS mode
|
||||
;; Major mode definition
|
||||
|
||||
;;*;; Hooks
|
||||
|
||||
(defcustom ess-mode-hook nil
|
||||
"Hook for customizing ESS each time it is entered."
|
||||
:group 'ess-hooks
|
||||
:type 'hook)
|
||||
|
||||
(defvar ess-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap yank] #'ess-yank)
|
||||
(define-key map "\C-c\C-r" #'ess-eval-region)
|
||||
(define-key map "\C-c\M-r" #'ess-eval-region-and-go)
|
||||
(define-key map "\C-c\C-b" #'ess-eval-buffer)
|
||||
(define-key map "\C-c\M-b" #'ess-eval-buffer-and-go)
|
||||
(define-key map (kbd "C-c C-<up>") #'ess-eval-buffer-from-beg-to-here)
|
||||
(define-key map (kbd "C-c C-<down>") #'ess-eval-buffer-from-here-to-end)
|
||||
(define-key map "\C-c\C-f" #'ess-eval-function)
|
||||
(define-key map "\C-c\M-f" #'ess-eval-function-and-go)
|
||||
(define-key map "\C-c\C-c" #'ess-eval-region-or-function-or-paragraph-and-step)
|
||||
(define-key map "\C-c\C-p" #'ess-eval-paragraph-and-step)
|
||||
(define-key map "\C-c\M-p" #'ess-eval-paragraph-and-go)
|
||||
(define-key map "\C-\M-x" #'ess-eval-region-or-function-or-paragraph)
|
||||
(define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
|
||||
(define-key map "\C-c\C-j" #'ess-eval-line)
|
||||
(define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
|
||||
(define-key map "\C-c\M-j" #'ess-eval-line-and-go)
|
||||
;; FIXME: The next three can only work in S/R - mode
|
||||
(define-key map "\C-\M-a" #'ess-goto-beginning-of-function-or-para)
|
||||
(define-key map "\C-\M-e" #'ess-goto-end-of-function-or-para)
|
||||
(define-key map "\C-xnd" #'ess-narrow-to-defun-or-para)
|
||||
(define-key map "\C-xnf" #'ess-narrow-to-defun-or-para)
|
||||
(define-key map "\C-c\C-z" #'ess-switch-to-inferior-or-script-buffer)
|
||||
(define-key map "\C-c\C-l" #'ess-load-file)
|
||||
;;; Make an alias because C-c C-l is taken up by comint in inferiors
|
||||
(define-key map "\C-c\M-l" #'ess-load-file)
|
||||
(define-key map "\C-c\C-v" #'ess-display-help-on-object)
|
||||
(define-key map "\C-c\C-s" #'ess-switch-process)
|
||||
(define-key map "\C-c\C-k" #'ess-force-buffer-current)
|
||||
(define-key map "\C-c`" #'ess-show-traceback)
|
||||
(define-key map [(control ?c) ?~] #'ess-show-call-stack)
|
||||
(define-key map "\C-\M-q" #'ess-indent-exp)
|
||||
(define-key map "{" #'skeleton-pair-insert-maybe)
|
||||
(define-key map "}" #'skeleton-pair-insert-maybe)
|
||||
(define-key map "\C-\M-h" #'ess-mark-function-or-para)
|
||||
(define-key map "\t" #'ess-indent-or-complete)
|
||||
(define-key map "\C-c\C-q" #'ess-quit)
|
||||
(define-key map "\M-\r" #'ess-use-this-dir)
|
||||
(define-key map "," #'ess-smart-comma)
|
||||
(define-key map "\C-c\C-d" 'ess-doc-map)
|
||||
(define-key map "\C-c\C-e" 'ess-extra-map)
|
||||
(define-key map "\C-c\C-t" 'ess-dev-map)
|
||||
map)
|
||||
"Keymap for `ess-mode'.")
|
||||
|
||||
;; Redefine `indent-new-comment-line' commands for Emacs < 26. Emacs
|
||||
;; 27 binds M-j to `default-indent-new-line' which calls
|
||||
;; `comment-line-break-function' if point is in a comment. We set this
|
||||
;; function in the mode init.
|
||||
(substitute-key-definition 'indent-new-comment-line
|
||||
'ess-indent-new-comment-line
|
||||
ess-mode-map global-map)
|
||||
|
||||
(defvar ess-extra-map
|
||||
(let (ess-extra-map)
|
||||
(define-prefix-command 'ess-extra-map)
|
||||
(define-key ess-extra-map "\C-d" #'ess-dump-object-into-edit-buffer)
|
||||
(define-key ess-extra-map "d" #'ess-dump-object-into-edit-buffer)
|
||||
(define-key ess-extra-map "\C-e" #'ess-execute)
|
||||
(define-key ess-extra-map "e" #'ess-execute)
|
||||
(define-key ess-extra-map "\C-i" #'ess-install-library)
|
||||
(define-key ess-extra-map "i" #'ess-install-library)
|
||||
(define-key ess-extra-map "\C-l" #'ess-load-library)
|
||||
(define-key ess-extra-map "l" #'ess-load-library)
|
||||
(define-key ess-extra-map "\C-r" #'inferior-ess-reload)
|
||||
(define-key ess-extra-map "r" #'inferior-ess-reload)
|
||||
(define-key ess-extra-map "\C-s" #'ess-set-style)
|
||||
(define-key ess-extra-map "s" #'ess-set-style)
|
||||
(define-key ess-extra-map "\C-t" #'ess-build-tags-for-directory)
|
||||
(define-key ess-extra-map "t" #'ess-build-tags-for-directory)
|
||||
(define-key ess-extra-map "\C-w" #'ess-execute-screen-options)
|
||||
(define-key ess-extra-map "w" #'ess-execute-screen-options)
|
||||
(define-key ess-extra-map "/" #'ess-set-working-directory)
|
||||
ess-extra-map)
|
||||
"ESS extra map.")
|
||||
|
||||
(easy-menu-define
|
||||
ess-mode-menu ess-mode-map
|
||||
"Menu for use in `ess-mode'."
|
||||
'("ESS" ; ESS-mode
|
||||
["Load file" ess-load-file t]
|
||||
["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
|
||||
["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
|
||||
["Eval region | line" ess-eval-region-or-line-visibly-and-step t]
|
||||
["Enter expression" ess-execute t]
|
||||
;; sub menus
|
||||
"------"
|
||||
("Process"
|
||||
["Goto end of process buffer" ess-switch-to-end-of-ESS t]
|
||||
["Switch to process buffer" ess-switch-to-inferior-or-script-buffer t]
|
||||
["Switch process" ess-switch-process t]
|
||||
;; ["Recreate R and S versions known to ESS" (ess-r-s-versions-creation+menu) t]
|
||||
("Start Process"
|
||||
["R" R :help "Start a new R process" :active t]
|
||||
["S" S :help "Start a new S process" :active t]
|
||||
["Sqpe" Sqpe ess-microsoft-p] ;; :help "Start a new Sqpe process" :active t
|
||||
["S+6-exisiting" S+6-existing ess-microsoft-p] ;; :help "Access an existing S process" :active t
|
||||
["SAS" SAS-menu t] ;; :help "Start a new SAS process" :active t
|
||||
;; The following menu item "Other" is a place-holder that will
|
||||
;; be replaced with the other versions of R and Sqpe that can be run.
|
||||
;; See `ess-r-define-runners' and ess-site.el
|
||||
("Other"
|
||||
["No other R or Sqpe versions" nil nil])
|
||||
["About"
|
||||
(ess-goto-info "Starting up") t]
|
||||
;; :help "Read about starting a new ESS process" :active t]
|
||||
)
|
||||
("Eval visibly "
|
||||
:filter ess--generate-eval-visibly-submenu)
|
||||
["Quit process" ess-quit t]
|
||||
["Reload process" inferior-ess-reload t])
|
||||
"------"
|
||||
("ESS Eval"
|
||||
["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
|
||||
["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
|
||||
["Eval region | line & step" ess-eval-region-or-line-visibly-and-step t]
|
||||
"-----"
|
||||
["Eval buffer" ess-eval-buffer t]
|
||||
["Eval buffer till here" ess-eval-buffer-from-beg-to-here t]
|
||||
["Eval buffer from here" ess-eval-buffer-from-here-to-end t]
|
||||
["Eval region" ess-eval-region t]
|
||||
["Eval function" ess-eval-function t]
|
||||
["Eval line" ess-eval-line t]
|
||||
["Eval line & step" ess-eval-line-and-step t]
|
||||
["Eval paragraph" ess-eval-paragraph t]
|
||||
["Eval paragraph & step" ess-eval-paragraph-and-step t]
|
||||
["About" (ess-goto-info "Evaluating code") t]
|
||||
)
|
||||
("Eval and Go"
|
||||
["Eval buffer" ess-eval-buffer-and-go t]
|
||||
["Eval region" ess-eval-region-and-go t]
|
||||
["Eval function" ess-eval-function-and-go t]
|
||||
["Eval line" ess-eval-line-and-go t]
|
||||
["Eval paragraph" ess-eval-paragraph-and-go t]
|
||||
["About" (ess-goto-info "Evaluating code") t]
|
||||
)
|
||||
("Motion"
|
||||
["Beginning of function or para" ess-goto-beginning-of-function-or-para t]
|
||||
["End of function or para" ess-goto-end-of-function-or-para t]
|
||||
"-----"
|
||||
["Backward list" backward-list t]
|
||||
["Forward list" forward-list t]
|
||||
["Next parenthesis" down-list t]
|
||||
["Enclosing parenthesis" backward-up-list t]
|
||||
["Backward sexp" backward-sexp t]
|
||||
["Forward sexp" forward-sexp t]
|
||||
["About" (Info-goto-node "(Emacs)Lists") t]
|
||||
)
|
||||
("ESS Edit"
|
||||
["Edit new object" ess-dump-object-into-edit-buffer t]
|
||||
["Complete Filename" comint-replace-by-expanded-filename t]
|
||||
["Complete File or Object" ess-indent-or-complete t]
|
||||
["Kill sexp" kill-sexp t]
|
||||
["Mark function" ess-mark-function-or-para t]
|
||||
["Indent expression" ess-indent-exp t]
|
||||
["Indent line" ess-indent-command t]
|
||||
["Toggle Auto-Fill Mode" auto-fill-mode t]
|
||||
["Undo" undo t]
|
||||
["About" (ess-goto-info "Edit buffer") t]
|
||||
)
|
||||
"------"
|
||||
("start-dev" :visible nil)
|
||||
("end-dev" :visible nil)
|
||||
"------"
|
||||
("Font Lock"
|
||||
:active ess-font-lock-keywords
|
||||
:filter ess--generate-font-lock-submenu)
|
||||
"------"
|
||||
["Describe" describe-mode t]
|
||||
["About editing" (ess-goto-info "Editing") t]
|
||||
["Read ESS info" (ess-goto-info "") t]
|
||||
["Send bug report" ess-submit-bug-report t]))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-mode prog-mode "ESS"
|
||||
"Major mode for editing ESS source.
|
||||
Optional arg ALIST describes how to customize the editing mode.
|
||||
Optional arg PROC-NAME is name of associated inferior process.
|
||||
|
||||
\\{ess-mode-map}
|
||||
|
||||
You can send text to the inferior ESS process from other buffers containing
|
||||
ESS source.
|
||||
`ess-eval-region' sends the current region to the ESS process.
|
||||
`ess-eval-buffer' sends the current buffer to the ESS process.
|
||||
`ess-eval-function' sends the current function to the ESS process.
|
||||
`ess-eval-line' sends the current line to the ESS process.
|
||||
`ess-switch-to-ESS' switches the current buffer to the ESS process buffer.
|
||||
`ess-switch-to-end-of-ESS' switches the current buffer to the ESS process
|
||||
buffer and puts point at the end of it.
|
||||
|
||||
`ess-eval-region-and-go', `ess-eval-buffer-and-go',
|
||||
`ess-eval-function-and-go', and `ess-eval-line-and-go' switch to the S
|
||||
process buffer after sending their text.
|
||||
|
||||
`ess-load-file' sources a file of commands to the ESS process.
|
||||
|
||||
\\[ess-indent-command] indents for ESS code.
|
||||
\\[backward-delete-char-untabify] converts tabs to spaces as it moves back.
|
||||
Comments are indented in a similar way to Emacs-lisp mode:
|
||||
`###' beginning of line
|
||||
`##' the same level of indentation as the code
|
||||
`#' the same column on the right, or to the right of such a
|
||||
column if that is not possible.(default value 40).
|
||||
\\[indent-for-comment] command automatically inserts such a
|
||||
`#' in the right place, or aligns such a comment if it is
|
||||
already inserted.
|
||||
\\[ess-indent-exp] command indents each line of the syntactic unit following point.
|
||||
|
||||
Variables controlling indentation style:
|
||||
`ess-indent-offset'
|
||||
Indentation of ESS statements within surrounding block.
|
||||
The surrounding block's indentation is the indentation of the line on
|
||||
which the open-brace appears.
|
||||
`ess-offset-block'
|
||||
Indentation of blocks opened with curly braces or anonymous parentheses.
|
||||
`ess-offset-arguments'
|
||||
Indentation of function arguments or bracket indices.
|
||||
`ess-offset-arguments-newline'
|
||||
Indentation of function arguments or bracket indices when the opening
|
||||
delimiter is immediately followed by a newline.
|
||||
`ess-offset-continued'
|
||||
Indentation style for continued statements.
|
||||
`ess-align-nested-calls'
|
||||
Functions whose nested calls should be aligned.
|
||||
`ess-align-arguments-in-calls'
|
||||
Calls in which arguments should be aligned.
|
||||
`ess-align-continuations-in-calls'
|
||||
Whether ignore indentation after an operator in calls
|
||||
`ess-align-blocks'
|
||||
Blocks that should always be aligned vertically.
|
||||
`ess-indent-from-lhs'
|
||||
Whether function calls given as argument should be indented from the
|
||||
parameter name.
|
||||
`ess-indent-from-chain-start'
|
||||
Whether to indent arguments from the first of several consecutive calls.
|
||||
`ess-indent-with-fancy-comments'
|
||||
Non-nil means distinguish between #, ##, and ### for indentation.
|
||||
|
||||
Furthermore, \\[ess-set-style] command enables you to set up predefined ess-mode
|
||||
indentation style. See `ess-style-alist' for predefined styles."
|
||||
:group 'ess
|
||||
;; TODO: get rid of these and rely on modes to set variables properly
|
||||
(when-let ((alist (buffer-local-value 'ess-local-customize-alist (current-buffer))))
|
||||
(ess-setq-vars-local alist))
|
||||
(when-let ((alist ess-mode-editing-alist))
|
||||
(ess-setq-vars-local alist))
|
||||
;; Keep <tabs> out of the code.
|
||||
(setq-local indent-tabs-mode nil)
|
||||
(setq-local comment-line-break-function #'ess-newline-and-indent)
|
||||
(setq mode-line-process
|
||||
'(" ["
|
||||
(:eval (ess--get-mode-line-indicator))
|
||||
ess--local-mode-line-process-indicator
|
||||
"]"))
|
||||
(add-hook 'ess-idle-timer-functions 'ess-synchronize-dirs nil 'local))
|
||||
|
||||
(defun ess--get-mode-line-indicator ()
|
||||
"Get `ess--mode-line-process-indicator' from process buffer.
|
||||
Internal function to be used for dynamic mode-line display in
|
||||
`ess-mode'."
|
||||
(if ess-local-process-name
|
||||
(let* ((proc (get-process ess-local-process-name))
|
||||
(buff (when proc (process-buffer proc))))
|
||||
(if (and proc (buffer-live-p buff))
|
||||
(with-current-buffer buff (mapcar 'eval ess--mode-line-process-indicator))
|
||||
"none"))
|
||||
"none"))
|
||||
|
||||
|
||||
;;; User commands in ess-mode
|
||||
|
||||
(defun ess-install-library (&optional update package)
|
||||
"Install PACKAGE for current dialect.
|
||||
With UPDATE, update cached package list."
|
||||
(interactive "P")
|
||||
(ess-install-library--override update package))
|
||||
|
||||
(cl-defgeneric ess-install-library--override (update package)
|
||||
"See `ess-install-library' for UPDATE, PACKAGE."
|
||||
(when update (message "Don't know how to update for %s" ess-dialect))
|
||||
(error "Cannot install %s, not available for %s" package ess-dialect))
|
||||
|
||||
|
||||
;; Motion / manipulation commands
|
||||
|
||||
(defun ess-goto-beginning-of-function-or-para ()
|
||||
"If inside a function go to the beginning of it.
|
||||
Otherwise go to the beginning of paragraph."
|
||||
(interactive)
|
||||
(let ((start-pos (point))
|
||||
beg end)
|
||||
(beginning-of-defun)
|
||||
(setq beg (point))
|
||||
(end-of-defun)
|
||||
(setq end (point))
|
||||
(goto-char beg)
|
||||
(unless (and (< beg start-pos)
|
||||
(> end start-pos))
|
||||
(let ((par-pos (save-excursion
|
||||
(goto-char start-pos)
|
||||
(forward-comment most-negative-fixnum)
|
||||
(backward-paragraph)
|
||||
(forward-comment most-positive-fixnum)
|
||||
(point))))
|
||||
(if (< end par-pos)
|
||||
(goto-char par-pos)
|
||||
(goto-char beg))))))
|
||||
|
||||
(defun ess-goto-end-of-function-or-para ()
|
||||
"If inside a function go to end of it.
|
||||
Otherwise go to the end of paragraph."
|
||||
(interactive)
|
||||
(let ((pos (point))
|
||||
beg end)
|
||||
(end-of-defun)
|
||||
(setq end (point))
|
||||
(beginning-of-defun)
|
||||
(setq beg (point))
|
||||
(goto-char end)
|
||||
(when (or (< beg pos)
|
||||
(> end pos))
|
||||
(let ((par-pos (save-excursion
|
||||
(goto-char pos)
|
||||
(forward-comment most-positive-fixnum)
|
||||
(forward-paragraph)
|
||||
(point))))
|
||||
(when (<= par-pos beg)
|
||||
(goto-char par-pos))))))
|
||||
|
||||
(defun ess-mark-function-or-para ()
|
||||
"Put mark at end of ESS function, point at beginning."
|
||||
(interactive)
|
||||
(ess-goto-beginning-of-function-or-para)
|
||||
(push-mark (point))
|
||||
(ess-goto-end-of-function-or-para)
|
||||
(exchange-point-and-mark))
|
||||
|
||||
(define-obsolete-function-alias 'ess-mark-function 'ess-mark-function-or-para "15.09")
|
||||
|
||||
(defun ess-narrow-to-defun-or-para ()
|
||||
"Make text outside current function invisible.
|
||||
If text is already narrowed, this is removed before narrowing to the
|
||||
current function."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(widen)
|
||||
(let* ((beg (progn (ess-goto-beginning-of-function-or-para)
|
||||
(point)))
|
||||
(end (progn (ess-goto-end-of-function-or-para)
|
||||
(point))))
|
||||
(narrow-to-region beg end))))
|
||||
|
||||
(define-obsolete-function-alias 'ess-narrow-to-defun 'ess-narrow-to-defun-or-para "15.09")
|
||||
|
||||
;; FIXME: Support soft breaks with `insert-and-inherit'. See
|
||||
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Hard-and-Soft-Newlines.html
|
||||
(defun ess-newline-and-indent (&optional _soft)
|
||||
(ess-indent-new-comment-line))
|
||||
|
||||
(defun ess-indent-new-comment-line ()
|
||||
"Like `indent-new-comment-line' but accounts for roxygen comments."
|
||||
(interactive)
|
||||
(cond ((and (fboundp 'ess-roxy-indent-new-comment-line)
|
||||
(string= ess-dialect "R"))
|
||||
(ess-roxy-indent-new-comment-line))
|
||||
(t
|
||||
(indent-new-comment-line))))
|
||||
|
||||
|
||||
;;; Formatting / indentation
|
||||
(defvar-local ess--installed-style-vars nil
|
||||
"A cons of the form (STYLE . VARS).
|
||||
VARS is a list of all style vars which were not set explicitly to
|
||||
buffer local values by the user in mode hooks.")
|
||||
|
||||
(defun ess-set-style (&optional style _quiet)
|
||||
"Set up the `ess-mode' style variables from the `ess-style' variable.
|
||||
If STYLE argument is given, use that instead. It makes the ESS
|
||||
indentation style variables buffer local. QUIET is for backward
|
||||
compatibility and is ignored.
|
||||
|
||||
In programs, when STYLE is nil, the `ess-style' is installed. In
|
||||
this case, if `ess-style' is buffer local, all settings are
|
||||
overwritten, otherwise only those settings which are not already
|
||||
buffer local. For example, `ess-style' is buffer local when it is
|
||||
set in .dir-locals and thus must have priority over the user
|
||||
settings in the mode hook."
|
||||
(interactive
|
||||
(list (let ((styles (mapcar (lambda (x) (symbol-name (car x)))
|
||||
ess-style-alist)))
|
||||
(intern (ess-completing-read
|
||||
"Set ESS mode indentation style"
|
||||
styles nil t nil nil ess-style)))))
|
||||
(let* ((keep-local (and (null style)
|
||||
(not (local-variable-p 'ess-style))))
|
||||
(style (or style ess-style))
|
||||
(style-alist (or (cdr (assq style ess-style-alist))
|
||||
(error "Bad ESS style: %s" style)))
|
||||
(vars (if keep-local
|
||||
;; Install, but Keep user's buffer-local settings.
|
||||
(cl-loop for (var . _) in (cdr (assq 'DEFAULT ess-style-alist))
|
||||
unless (local-variable-p var)
|
||||
collect var)
|
||||
(mapcar #'car style-alist))))
|
||||
(when (called-interactively-p 'any)
|
||||
(message "Set indentation style to %s" style))
|
||||
(mapc (lambda (var)
|
||||
(make-local-variable var)
|
||||
(set var (cdr (assq var style-alist))))
|
||||
vars)
|
||||
style))
|
||||
|
||||
(defun ess-indent-command (&optional whole-exp)
|
||||
"Indent current line as ESS code, or in some cases insert a tab character.
|
||||
If `tab-always-indent' is non-nil, always indent current line.
|
||||
Otherwise, indent the current line only if point is at the left
|
||||
margin or in the line's indentation; otherwise insert a tab. If
|
||||
given, WHOLE-EXP means indent rigidly all the lines of the
|
||||
expression starting after point so that this line becomes
|
||||
properly indented. The relative indentation among the lines of
|
||||
the expression are preserved.
|
||||
|
||||
If in a roxygen block at the beginning of the line with
|
||||
`ess-roxy-hide-show-p' non-nil, call `ess-roxy-toggle-hiding'
|
||||
instead of indenting."
|
||||
(interactive "P")
|
||||
(cond ((and (fboundp 'ess-roxy-entry-p)
|
||||
(fboundp 'ess-roxy-toggle-hiding)
|
||||
(bolp)
|
||||
(ess-roxy-entry-p)
|
||||
ess-roxy-hide-show-p)
|
||||
(ess-roxy-toggle-hiding))
|
||||
(whole-exp
|
||||
;; If arg, always indent this line as S
|
||||
;; and shift remaining lines of expression the same amount.
|
||||
(let ((shift-amt (funcall indent-line-function))
|
||||
beg end)
|
||||
(save-excursion
|
||||
(if tab-always-indent
|
||||
(beginning-of-line))
|
||||
(setq beg (point))
|
||||
(backward-up-list 1)
|
||||
(forward-list 1)
|
||||
(setq end (point))
|
||||
(goto-char beg)
|
||||
(forward-line 1)
|
||||
(setq beg (point)))
|
||||
(if (> end beg)
|
||||
(indent-code-rigidly beg end shift-amt))))
|
||||
((and (not tab-always-indent)
|
||||
(save-excursion
|
||||
(skip-chars-backward " \t")
|
||||
(not (bolp))))
|
||||
(insert-tab))
|
||||
(t (funcall indent-line-function))))
|
||||
|
||||
(defun ess-indent-or-complete ()
|
||||
"When region is selected indent the region.
|
||||
Otherwise, if `tab-always-indent' is 'complete, try to indent, if
|
||||
code is already indented, complete instead. Also see
|
||||
`ess-first-tab-never-complete'."
|
||||
(interactive)
|
||||
(if (use-region-p)
|
||||
(indent-region (region-beginning) (region-end))
|
||||
(let ((shift (let ((indent (current-indentation)))
|
||||
(ess-indent-command)
|
||||
(- (current-indentation) indent))))
|
||||
(when (and (or (equal tab-always-indent 'complete)
|
||||
ess-tab-complete-in-script)
|
||||
(numberp shift) ;; can be nil if tab-always-indent is nil
|
||||
(equal shift 0)
|
||||
(or (eq last-command 'ess-indent-or-complete)
|
||||
(null ess-first-tab-never-complete)
|
||||
(and (eq ess-first-tab-never-complete 'unless-eol)
|
||||
(looking-at "\\s-*$"))
|
||||
(and (eq ess-first-tab-never-complete 'symbol)
|
||||
(not (looking-at "\\w\\|\\s_")))
|
||||
(and (eq ess-first-tab-never-complete 'symbol-or-paren)
|
||||
(not (looking-at "\\w\\|\\s_\\|\\s)")))
|
||||
(and (eq ess-first-tab-never-complete 'symbol-or-paren-or-punct)
|
||||
(not (looking-at "\\w\\|\\s_\\|\\s)\\|\\s.")))))
|
||||
(completion-at-point)))))
|
||||
|
||||
(defun ess-indent-exp ()
|
||||
"Indent each line of the ESS grouping following point."
|
||||
(interactive)
|
||||
(cond ((and (fboundp 'ess-r-indent-exp)
|
||||
(string= ess-dialect "R"))
|
||||
(ess-r-indent-exp))
|
||||
(t
|
||||
(save-excursion
|
||||
(let ((start (point))
|
||||
(end (ignore-errors (forward-sexp 1) (point))))
|
||||
(when end
|
||||
(indent-region start end)))))))
|
||||
|
||||
(defun ess-indent-line ()
|
||||
"Indent current line as ESS code.
|
||||
Return the amount the indentation changed by."
|
||||
(declare (obsolete 'indent-line-function "ESS 19.04"))
|
||||
(funcall indent-line-function))
|
||||
|
||||
|
||||
;;; Dump Objects
|
||||
|
||||
(defun ess-dump-object-into-edit-buffer (object)
|
||||
"Edit an ESS OBJECT in its own buffer.
|
||||
Without a prefix argument, this simply finds the file pointed to by
|
||||
`ess-source-directory'. If this file does not exist, or if a
|
||||
prefix argument is given, a dump() command is sent to the ESS process to
|
||||
generate the source buffer."
|
||||
(interactive
|
||||
(progn
|
||||
(ess-force-buffer-current "Process to dump from: ")
|
||||
(ess-read-object-name "Object to edit")))
|
||||
(let* ((dirname (file-name-as-directory
|
||||
(if (stringp ess-source-directory)
|
||||
ess-source-directory
|
||||
(with-current-buffer (process-buffer (ess-get-process
|
||||
ess-local-process-name))
|
||||
(ess-setq-vars-local ess-local-customize-alist)
|
||||
(apply ess-source-directory nil)))))
|
||||
(filename (concat dirname (convert-standard-filename (format ess-dump-filename-template object))))
|
||||
(old-buff (get-file-buffer filename)))
|
||||
;; If the directory doesn't exist, offer to create it
|
||||
(unless (file-exists-p (directory-file-name dirname))
|
||||
(if (y-or-n-p (format "Directory %s does not exist. Create it? " dirname))
|
||||
(make-directory (directory-file-name dirname))
|
||||
(error "Directory %s does not exist" dirname)))
|
||||
;; Three options:
|
||||
;; (1) Pop to an existing buffer containing the file in question
|
||||
;; (2) Find an existing file
|
||||
;; (3) Create a new file by issuing a dump() command to S
|
||||
;; Force option (3) if there is a prefix arg
|
||||
(cond (current-prefix-arg
|
||||
(ess-dump-object object filename))
|
||||
(old-buff
|
||||
(pop-to-buffer old-buff))
|
||||
((file-exists-p filename)
|
||||
(ess-find-dump-file-other-window filename)
|
||||
(message "Read %s" filename))
|
||||
(t (ess-dump-object object filename)))))
|
||||
|
||||
(defun ess-dump-object (object filename)
|
||||
"Dump the ESS object OBJECT into file FILENAME."
|
||||
(unless (file-writable-p filename)
|
||||
(error "Can't dump %s as %f is not writeable" object filename))
|
||||
(let ((dump-cmd (format inferior-ess-dump-command object filename)))
|
||||
;; Make sure we start fresh
|
||||
(when (get-file-buffer filename)
|
||||
(kill-buffer (get-file-buffer filename)))
|
||||
(ess-command dump-cmd)
|
||||
(message "Dumped in %s" filename)
|
||||
(ess-find-dump-file-other-window filename)
|
||||
;; PD, 1Apr97
|
||||
;;This ensures that the object gets indented according to ess-mode,
|
||||
;;not as the R/S deparser does it. At the same time, it gets rid
|
||||
;;of the mess generated by sending TAB characters to the readline
|
||||
;;functions in R when you eval-buffer-*.
|
||||
(indent-region (point-min-marker) (point-max-marker) nil)
|
||||
(set-buffer-modified-p nil) ; no need to safe just because of indenting
|
||||
;; Don't make backups for temporary files; it only causes clutter.
|
||||
;; The ESS object itself is a kind of backup, anyway.
|
||||
(unless ess-keep-dump-files
|
||||
(make-local-variable 'make-backup-files)
|
||||
(setq make-backup-files nil))
|
||||
;; Don't get confirmation to delete dumped files when loading
|
||||
(when (eq ess-keep-dump-files 'check)
|
||||
(setq ess-keep-dump-files nil))
|
||||
;; Delete the file if necessary
|
||||
(when ess-delete-dump-files
|
||||
(delete-file (buffer-file-name)))))
|
||||
|
||||
(defun ess-find-dump-file-other-window (filename)
|
||||
"Find ESS source file FILENAME in another window."
|
||||
(unless (file-readable-p filename)
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "%s does not exist. Bad dump, starting fresh." filename)))
|
||||
;; Generate a buffer with the dumped data
|
||||
(find-file-other-window filename)
|
||||
(auto-save-mode 1) ; Auto save in this buffer
|
||||
(when (and ess-function-template
|
||||
(goto-char (point-max))
|
||||
(re-search-backward ess-dumped-missing-re nil t))
|
||||
(replace-match ess-function-template t t)
|
||||
(set-buffer-modified-p nil) ; Don't offer to save if killed now
|
||||
(goto-char (point-min))
|
||||
(ignore-errors
|
||||
;; This may fail if there are no opens
|
||||
(down-list 1))))
|
||||
|
||||
|
||||
;;; Runners
|
||||
|
||||
(defun ess-define-runner (name dialect &optional path)
|
||||
"Create a function NAME.
|
||||
This function starts the inferior process with the specified
|
||||
version. DIALECT can be \"R,\" \"S,\", \"SAS.\" If given, PATH
|
||||
should be the absolute path to the program. It defaults to NAME."
|
||||
(let ((name name)
|
||||
(dialect dialect)
|
||||
(path path))
|
||||
(fset (intern name)
|
||||
(lambda (&optional start-args)
|
||||
"Start this process version in an inferior ESS buffer.
|
||||
Function defined using `ess-define-runner'."
|
||||
(interactive "P")
|
||||
(cond ((string= dialect "R")
|
||||
(let ((inferior-ess-r-program (or path name)))
|
||||
(require 'ess-r-mode)
|
||||
(run-ess-r start-args)))
|
||||
((string= dialect "S")
|
||||
(let ((inferior-S+-program (or path name)))
|
||||
(require 'ess-sp6-d)
|
||||
(S+)))
|
||||
((string= dialect "SAS")
|
||||
(let ((inferior-SAS-program (or path name)))
|
||||
(require 'ess-sas-d)
|
||||
(SAS))))))))
|
||||
|
||||
|
||||
|
||||
(provide 'ess-mode)
|
||||
|
||||
;;; ess-mode.el ends here
|
||||
21
lisp/ess/ess-pkg.el
Normal file
21
lisp/ess/ess-pkg.el
Normal file
@@ -0,0 +1,21 @@
|
||||
(define-package "ess" "20200623.1908" "Emacs Speaks Statistics"
|
||||
'((emacs "25.1"))
|
||||
:commit "ccc01edb7ad8db9cb43a45ac8ec023c80347c33d" :authors
|
||||
'(("David Smith" . "dsmith@stats.adelaide.edu.au")
|
||||
("A.J. Rossini" . "blindglobe@gmail.com")
|
||||
("Richard M. Heiberger" . "rmh@temple.edu")
|
||||
("Kurt Hornik" . "Kurt.Hornik@R-project.org")
|
||||
("Martin Maechler" . "maechler@stat.math.ethz.ch")
|
||||
("Rodney A. Sparapani" . "rsparapa@mcw.edu")
|
||||
("Stephen Eglen" . "stephen@gnu.org")
|
||||
("Sebastian P. Luque" . "spluque@gmail.com")
|
||||
("Henning Redestig" . "henning.red@googlemail.com")
|
||||
("Vitalie Spinu" . "spinuvit@gmail.com")
|
||||
("Lionel Henry" . "lionel.hry@gmail.com")
|
||||
("J. Alexander Branham" . "alex.branham@gmail.com"))
|
||||
:maintainer
|
||||
'("ESS Core Team" . "ESS-core@r-project.org")
|
||||
:url "https://ess.r-project.org/")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
516
lisp/ess/ess-r-completion.el
Normal file
516
lisp/ess/ess-r-completion.el
Normal file
@@ -0,0 +1,516 @@
|
||||
;;; ess-r-completion.el --- R completion -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
||||
;; Author: Vitalie Spinu
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
;; Provide completion support in R buffers.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
;;; ElDoc
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-help)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'subr-x))
|
||||
|
||||
(defvar ac-auto-start)
|
||||
(defvar ac-prefix)
|
||||
(defvar ac-point)
|
||||
(defvar ac-use-comphist)
|
||||
(declare-function company-begin-backend "company")
|
||||
(declare-function company-doc-buffer "company")
|
||||
|
||||
(defcustom ess-R-argument-suffix " = "
|
||||
"Suffix appended by `ac-source-R' and `ac-source-R-args' to candidates."
|
||||
:group 'ess-R
|
||||
:type 'string)
|
||||
|
||||
(defun ess-r-eldoc-function ()
|
||||
"Return the doc string, or nil.
|
||||
If an ESS process is not associated with the buffer, do not try
|
||||
to look up any doc strings."
|
||||
(when (and eldoc-mode ess-can-eval-in-background)
|
||||
(let* ((proc (ess-get-next-available-process))
|
||||
(funname (and proc (or (and ess-eldoc-show-on-symbol ;; Aggressive completion
|
||||
(thing-at-point 'symbol))
|
||||
(car (ess--fn-name-start))))))
|
||||
(when funname
|
||||
(let* ((args (ess-function-arguments funname proc))
|
||||
(bargs (cadr args))
|
||||
(doc (mapconcat (lambda (el)
|
||||
(if (equal (car el) "...")
|
||||
"..."
|
||||
(concat (car el) "=" (cdr el))))
|
||||
bargs ", "))
|
||||
(margs (nth 2 args))
|
||||
(W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
|
||||
(multiline (eq t eldoc-echo-area-use-multiline-p))
|
||||
doc1)
|
||||
(when doc
|
||||
(setq doc (ess-eldoc-docstring-format funname doc (not multiline)))
|
||||
(when (or multiline (and margs (< (length doc1) W)))
|
||||
(setq doc1 (concat doc (propertize " || " 'face font-lock-function-name-face)))
|
||||
(while (and margs (< (length doc1) W))
|
||||
(let ((head (pop margs)))
|
||||
(unless (assoc head bargs)
|
||||
(setq doc doc1
|
||||
doc1 (concat doc1 head "=, ")))))
|
||||
(when (equal (substring doc -2) ", ")
|
||||
(setq doc (substring doc 0 -2)))
|
||||
(when (and margs (< (length doc) W))
|
||||
(setq doc (concat doc " {--}"))))
|
||||
doc))))))
|
||||
|
||||
(defun ess-eldoc-docstring-format (funname doc &optional truncate)
|
||||
(save-match-data
|
||||
(let* (;; Subtract 1 from window width since will cause a wraparound and
|
||||
;; resize of the echo area.
|
||||
(W (1- (- (window-width (minibuffer-window))
|
||||
(+ 2 (length funname))))))
|
||||
(setq doc
|
||||
(if (or (<= (length doc) W)
|
||||
(null ess-eldoc-abbreviation-style)
|
||||
(eq 'none ess-eldoc-abbreviation-style))
|
||||
doc
|
||||
;;MILD filter
|
||||
(setq doc (replace-regexp-in-string "TRUE" "T" doc))
|
||||
(setq doc (replace-regexp-in-string "FALSE" "F" doc))
|
||||
(if (or (<= (length doc) W)
|
||||
(eq 'mild ess-eldoc-abbreviation-style))
|
||||
doc
|
||||
;;NORMAL filter (deal with long defaults)
|
||||
(setq doc (replace-regexp-in-string
|
||||
;; function calls inside default docs foo(xxxx{..})
|
||||
"([^)]\\{8\\}\\([^)]\\{4,\\}\\))"
|
||||
"{.}" doc nil nil 1))
|
||||
(if (<= (length doc) W)
|
||||
doc
|
||||
(setq doc (replace-regexp-in-string
|
||||
" +[^ \t=,\"\]+=[^ \t]\\{10\\}\\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
|
||||
"{.}," doc nil nil 1))
|
||||
(if (<= (length doc) W)
|
||||
doc
|
||||
(setq doc (replace-regexp-in-string
|
||||
" +[^ \t=,\"]+=\\([^ \t]\\{10,\\}\\)\\(,\\|\\'\\)"
|
||||
"{.}," doc nil nil 1))
|
||||
(if (or (<= (length doc) W)
|
||||
(eq 'normal ess-eldoc-abbreviation-style))
|
||||
doc
|
||||
;;STRONG filter (replace defaults)
|
||||
(setq doc (replace-regexp-in-string
|
||||
" *[^ \t=,\"\\]* = \\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
|
||||
"{.}," doc nil nil 1))
|
||||
(if (<= (length doc) W)
|
||||
doc
|
||||
(setq doc (replace-regexp-in-string
|
||||
"\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+=\\|\\'\\)"
|
||||
"" doc nil nil 1))
|
||||
(setq doc (replace-regexp-in-string
|
||||
"\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+,\\|\\'\\)"
|
||||
"" doc nil nil 1))
|
||||
(if (or (<= (length doc) W)
|
||||
(eq 'strong ess-eldoc-abbreviation-style))
|
||||
doc
|
||||
;;AGGRESSIVE filter (truncate what is left)
|
||||
(concat (substring doc 0 (- W 4)) "{--}")))))))))
|
||||
(when (and truncate (> (length doc) W))
|
||||
(setq doc (concat (substring doc 0 (- W 4)) "{--}")))
|
||||
(format "%s: %s" (propertize funname 'face 'font-lock-function-name-face) doc))))
|
||||
|
||||
|
||||
;;; OBJECTS
|
||||
|
||||
(defun ess-r-object-completion ()
|
||||
"Return completions at point in a format required by `completion-at-point-functions'."
|
||||
(if (ess-make-buffer-current)
|
||||
(let* ((funstart (cdr (ess--fn-name-start)))
|
||||
(completions (ess-r-get-rcompletions funstart))
|
||||
(token (pop completions)))
|
||||
(when completions
|
||||
(list (- (point) (length token)) (point)
|
||||
completions)))
|
||||
(when (string-match "complete" (symbol-name last-command))
|
||||
(message "No ESS process associated with current buffer")
|
||||
nil)))
|
||||
|
||||
(defun ess-complete-object-name ()
|
||||
"Perform completion on object preceding point.
|
||||
Uses `ess-r-complete-object-name' when `ess-use-R-completion' is non-nil,
|
||||
and `ess-internal-complete-object-name' otherwise."
|
||||
(interactive)
|
||||
(if (ess-make-buffer-current)
|
||||
(if ess-use-R-completion
|
||||
(ess-r-complete-object-name)
|
||||
(ess-internal-complete-object-name))
|
||||
;; else give a message on second invocation
|
||||
(when (string-match "complete" (symbol-name last-command))
|
||||
(message "No ESS process associated with current buffer")
|
||||
nil)))
|
||||
|
||||
(define-obsolete-function-alias 'ess-list-object-completions #'ess-complete-object-name "ESS 19.04")
|
||||
|
||||
;; This one is needed for R <= 2.6.x -- hence *not* obsoleting it
|
||||
(defun ess-internal-complete-object-name ()
|
||||
"Perform completion on `ess-language' object preceding point.
|
||||
The object is compared against those objects known by
|
||||
`ess-get-object-list' and any additional characters up to ambiguity are
|
||||
inserted. Completion only works on globally-known objects (including
|
||||
elements of attached data frames), and thus is most suitable for
|
||||
interactive `command-line' entry, and not so much for function editing
|
||||
since local objects (e.g. argument names) aren't known.
|
||||
|
||||
Use \\[ess-resynch] to re-read the names of the attached directories.
|
||||
This is done automatically (and transparently) if a directory is
|
||||
modified (S only!), so the most up-to-date list of object names is always
|
||||
available. However attached dataframes are *not* updated, so this
|
||||
command may be necessary if you modify an attached dataframe."
|
||||
(ess-make-buffer-current)
|
||||
(if (memq (char-syntax (preceding-char)) '(?w ?_))
|
||||
(let* ((comint-completion-addsuffix nil)
|
||||
(bounds (ess-bounds-of-symbol))
|
||||
(beg (car bounds))
|
||||
(end (cdr bounds))
|
||||
(full-prefix (buffer-substring beg end))
|
||||
(pattern full-prefix)
|
||||
;; See if we're indexing a list with `$'
|
||||
(listname (if (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$"
|
||||
full-prefix)
|
||||
(progn
|
||||
(setq pattern
|
||||
(if (not (match-beginning 2)) ""
|
||||
(substring full-prefix
|
||||
(match-beginning 2)
|
||||
(match-end 2))))
|
||||
(substring full-prefix (match-beginning 1)
|
||||
(match-end 1)))))
|
||||
;; are we trying to get a slot via `@' ?
|
||||
(classname (if (string-match "\\(.+\\)@\\(\\(\\sw\\|\\s_\\)*\\)$"
|
||||
full-prefix)
|
||||
(progn
|
||||
(setq pattern
|
||||
(if (not (match-beginning 2)) ""
|
||||
(substring full-prefix
|
||||
(match-beginning 2)
|
||||
(match-end 2))))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "(ess-C-O-Name : slots..) : patt=%s"
|
||||
pattern))
|
||||
(substring full-prefix (match-beginning 1)
|
||||
(match-end 1)))))
|
||||
(components (if listname
|
||||
(ess-object-names listname)
|
||||
(if classname
|
||||
(ess-slot-names classname)
|
||||
;; Default case: It hangs here when
|
||||
;; options(error=recover) :
|
||||
(ess-get-object-list ess-current-process-name)))))
|
||||
;; always return a non-nil value to prevent history expansions
|
||||
(or (completion-in-region beg end components) 'none))))
|
||||
|
||||
(defun ess-r-get-rcompletions (&optional start end prefix allow-3-dots)
|
||||
"Call R internal completion utilities (rcomp) for possible completions.
|
||||
Optional START and END delimit the entity to complete, default to
|
||||
bol and point. If PREFIX is given, perform completion on
|
||||
PREFIX. First element of the returned list is the completion
|
||||
token. Needs version of R >= 2.7.0."
|
||||
(let* ((start (or start
|
||||
(if prefix
|
||||
0
|
||||
(save-excursion (comint-bol nil) (point)))))
|
||||
(end (or end (if prefix (length prefix) (point))))
|
||||
(prefix (or prefix (buffer-substring start end)))
|
||||
;; (opts1 (if no-args "op<-rc.options(args=FALSE)" ""))
|
||||
;; (opts2 (if no-args "rc.options(op)" ""))
|
||||
(call1 (format ".ess_get_completions(\"%s\", %d, \"%s\")"
|
||||
(ess-quote-special-chars prefix)
|
||||
(- end start)
|
||||
ess-R-argument-suffix))
|
||||
(cmd (if allow-3-dots
|
||||
(concat call1 "\n")
|
||||
(concat "local({ r <- " call1 "; r[r != '...='] })\n"))))
|
||||
(ess-get-words-from-vector cmd)))
|
||||
|
||||
(defun ess-r-complete-object-name ()
|
||||
"Completion in R via R's completion utilities (formerly 'rcompgen').
|
||||
To be used instead of ESS' completion engine for R versions >= 2.7.0."
|
||||
(let ((possible-completions (ess-r-get-rcompletions))
|
||||
token-string)
|
||||
(when possible-completions
|
||||
(setq token-string (pop possible-completions))
|
||||
(or (completion-in-region (- (point) (length token-string))
|
||||
(point)
|
||||
possible-completions)
|
||||
'none))))
|
||||
|
||||
(defvar ess--cached-sp-objects nil)
|
||||
|
||||
(defun ess--get-cached-completions (prefix &optional _point)
|
||||
(if (string-match-p "[]:$@[]" prefix)
|
||||
;; call proc for objects
|
||||
(cdr (ess-r-get-rcompletions nil nil prefix))
|
||||
;; else, get cached list of objects
|
||||
(with-ess-process-buffer 'no-error ;; use proc buf alist
|
||||
(ess-when-new-input last-cached-completions
|
||||
(if (and ess--cached-sp-objects
|
||||
(not (process-get *proc* 'sp-for-ac-changed?)))
|
||||
;; if global cache is already there, only re-read local .GlobalEnv
|
||||
(progn
|
||||
(unless ess-sl-modtime-alist
|
||||
;; initialize if empty
|
||||
(setq ess-sl-modtime-alist '((".GlobalEnv" nil))))
|
||||
;; fixme: Make adaptive. Not on all remotes are slow; For lots of
|
||||
;; objects in .GlobalEnv,locals could also be slow.
|
||||
(unless (file-remote-p default-directory)
|
||||
(ess-extract-onames-from-alist ess-sl-modtime-alist 1 'force)))
|
||||
(if ess--cached-sp-objects
|
||||
(ess-get-modtime-list 'ess--cached-sp-objects 'exclude-first)
|
||||
(ess-get-modtime-list)
|
||||
(setq ess--cached-sp-objects (cdr ess-sl-modtime-alist)))
|
||||
;; reread new package, but not rda, much faster and not needed anyways
|
||||
(process-put *proc* 'sp-for-ac-changed? nil)))
|
||||
(apply 'append
|
||||
(cl-cddar ess-sl-modtime-alist) ; .GlobalEnv
|
||||
(mapcar 'cddr ess--cached-sp-objects)))))
|
||||
|
||||
|
||||
;;; ARGUMENTS
|
||||
|
||||
(defvar ess-r--funargs-pre-cache
|
||||
'(("plot"
|
||||
(("graphics")
|
||||
(("x" . "") ("y" . "NULL") ("type" . "p") ("xlim" . "NULL") ("ylim" . "NULL") ("log" . "") ("main" . "NULL") ("sub" . "NULL") ("xlab" . "NULL") ("ylab" . "NULL")
|
||||
("ann" . "par(\"ann\")") ("axes" . "TRUE") ("frame.plot" . "axes") ("panel.first" . "NULL") ("panel.last" . "NULL") ("asp" . "NA") ("..." . ""))
|
||||
("x" "y" "..." "ci" "type" "xlab" "ylab" "ylim" "main" "ci.col" "ci.type" "max.mfrow" "ask" "mar" "oma" "mgp" "xpd" "cex.main" "verbose" "scale" "xlim" "log" "sub" "ann" "axes" "frame.plot"
|
||||
"panel.first" "panel.last" "asp" "center" "edge.root" "nodePar" "edgePar" "leaflab" "dLeaf" "xaxt" "yaxt" "horiz"
|
||||
"zero.line" "verticals" "col.01line" "pch" "legend.text" "formula" "data" "subset" "to" "from" "newpage" "vp" "labels"
|
||||
"hang" "freq" "density" "angle" "col" "border" "lty" "add" "predicted.values" "intervals" "separator" "col.predicted"
|
||||
"col.intervals" "col.separator" "lty.predicted" "lty.intervals" "lty.separator" "plot.type" "main2" "par.fit" "grid"
|
||||
"panel" "cex" "dimen" "abbrev" "which" "caption" "sub.caption" "id.n" "labels.id" "cex.id" "qqline" "cook.levels"
|
||||
"add.smooth" "label.pos" "cex.caption" "rows" "levels" "conf" "absVal" "ci.lty" "xval" "do.points" "col.points" "cex.points"
|
||||
"col.hor" "col.vert" "lwd" "set.pars" "range.bars" "col.range" "xy.labels" "xy.lines" "nc" "yax.flip" "mar.multi" "oma.multi")))
|
||||
("print"
|
||||
(("base")
|
||||
(("x" . "") ("digits" . "NULL") ("quote" . "TRUE") ("na.print" . "NULL") ("print.gap" . "NULL") ("right" . "FALSE") ("max" . "NULL") ("useSource" . "TRUE") ("..." . ""))
|
||||
("x" "..." "digits" "signif.stars" "intercept" "tol" "se" "sort" "verbose" "indent" "style" ".bibstyle" "prefix" "vsep" "minlevel" "quote" "right" "row.names" "max" "na.print" "print.gap"
|
||||
"useSource" "diag" "upper" "justify" "title" "max.levels" "width" "steps" "showEnv" "newpage" "vp" "cutoff" "max.level" "give.attr" "units" "abbrCollate" "print.x" "deparse" "locale" "symbolic.cor"
|
||||
"loadings" "zero.print" "calendar"))))
|
||||
"Alist of cached arguments for time consuming functions.")
|
||||
|
||||
|
||||
;;; HELP
|
||||
|
||||
(defun ess-r-get-object-help-string (sym)
|
||||
"Help string for ac."
|
||||
(let ((proc (ess-get-next-available-process)))
|
||||
(if (null proc)
|
||||
"No free ESS process found"
|
||||
(let ((buf (get-buffer-create " *ess-command-output*")))
|
||||
(when (string-match ":+\\(.*\\)" sym)
|
||||
(setq sym (match-string 1 sym)))
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(ess-with-current-buffer buf
|
||||
(ess--flush-help-into-current-buffer sym nil)))
|
||||
(with-current-buffer buf
|
||||
(ess-help-underline)
|
||||
(goto-char (point-min))
|
||||
(buffer-string))))))
|
||||
|
||||
(defun ess-r-get-arg-help-string (sym &optional proc)
|
||||
"Help string for ac."
|
||||
(setq sym (replace-regexp-in-string " *= *\\'" "" sym))
|
||||
(let ((proc (or proc (ess-get-next-available-process))))
|
||||
(if (null proc)
|
||||
"No free ESS process found"
|
||||
(let ((fun (car ess--fn-name-start-cache)))
|
||||
(with-current-buffer (ess-command (format ".ess_arg_help('%s','%s')\n" sym fun)
|
||||
nil nil nil nil proc)
|
||||
(goto-char (point-min))
|
||||
(forward-line)
|
||||
(buffer-substring-no-properties (point) (point-max)))))))
|
||||
|
||||
|
||||
;;; COMPANY
|
||||
;;; https://company-mode.github.io/
|
||||
|
||||
(defun company-R-objects (command &optional arg &rest ignored)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-R-objects))
|
||||
(prefix (unless (ess-inside-string-or-comment-p)
|
||||
(let ((start (ess-symbol-start)))
|
||||
(when start
|
||||
(buffer-substring-no-properties start (point))))))
|
||||
(candidates (let ((proc (ess-get-next-available-process)))
|
||||
(when proc
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(all-completions arg (ess--get-cached-completions arg))))))
|
||||
(doc-buffer (company-doc-buffer (ess-r-get-object-help-string arg)))))
|
||||
|
||||
(defun company-R-args (command &optional arg &rest ignored)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-R-args))
|
||||
(prefix (unless (ess-inside-string-or-comment-p)
|
||||
(let ((start (ess-arg-start)))
|
||||
(when start
|
||||
(let ((prefix (buffer-substring-no-properties start (point))))
|
||||
(if ess-company-arg-prefix-length
|
||||
(cons prefix (>= (length prefix)
|
||||
ess-company-arg-prefix-length))
|
||||
prefix))))))
|
||||
(candidates (let* ((proc (ess-get-next-available-process))
|
||||
(args (delete "..." (nth 2 (ess-function-arguments
|
||||
(car ess--fn-name-start-cache) proc))))
|
||||
(args (mapcar (lambda (a) (concat a ess-R-argument-suffix))
|
||||
args)))
|
||||
(all-completions arg args)))
|
||||
(meta (let ((proc (ess-get-next-available-process)))
|
||||
(when (and proc
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(not (file-remote-p default-directory))))
|
||||
;; fixme: ideally meta should be fetched with args
|
||||
(let ((doc (ess-r-get-arg-help-string arg proc)))
|
||||
(replace-regexp-in-string "^ +\\| +$" ""
|
||||
(replace-regexp-in-string "[ \t\n]+" " " doc))))))
|
||||
(sorted t)
|
||||
(require-match 'never)
|
||||
(doc-buffer (company-doc-buffer (ess-r-get-arg-help-string arg)))))
|
||||
|
||||
(defun company-R-library (command &optional arg &rest ignored)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-R-library))
|
||||
(prefix (and (member (car (ess--fn-name-start))
|
||||
'("library" "require"))
|
||||
(let ((start (ess-symbol-start)))
|
||||
(and start (buffer-substring start (point))))))
|
||||
(candidates (all-completions arg (ess-installed-packages)))
|
||||
(annotation "<pkg>")
|
||||
(duplicates nil)
|
||||
(sorted t)))
|
||||
|
||||
;; FIXME: There's a lot of overlap between `ess-r-package-completion'
|
||||
;; and `company-R-library'. Can we merge them somehow?
|
||||
(defun ess-r-package-completion ()
|
||||
"Return installed packages if in a call to library or require.
|
||||
Return format suitable for `completion-at-point-functions'."
|
||||
(when (member (car (ess--fn-name-start))
|
||||
'("library" "require"))
|
||||
(list (ess-symbol-start)
|
||||
(point)
|
||||
(ess-installed-packages)
|
||||
:annotation-function
|
||||
(lambda (_) " <pkg>"))))
|
||||
|
||||
|
||||
;;; AC SOURCES
|
||||
;;; http://cx4a.org/software/auto-complete/index.html
|
||||
;; auto-complete is de-facto unmaintained, users should switch to `company-mode'.
|
||||
|
||||
(defvar ac-source-R
|
||||
'((prefix . ess-ac-start)
|
||||
;; (requires . 0) ::)
|
||||
(candidates . ess-ac-candidates)
|
||||
;; (action . ess-ac-action-args) ;; interfere with ac-fallback mechanism on RET (which is extremely annoying in inferior buffers)
|
||||
(document . ess-ac-help))
|
||||
"Combined ad-completion source for R function arguments and R objects.")
|
||||
(make-obsolete-variable 'ac-source-R "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
(defun ess-ac-start ()
|
||||
(when (ess-process-live-p)
|
||||
(or (ess-arg-start)
|
||||
(ess-symbol-start))))
|
||||
(make-obsolete-variable 'ess-ac-start "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
(defun ess-ac-candidates ()
|
||||
"OBJECTS + ARGS."
|
||||
(let ((args (with-no-warnings
|
||||
;; suppress obsolete warnings
|
||||
(ess-ac-args))))
|
||||
;; sort of intrusive but right
|
||||
(if (and ac-auto-start
|
||||
(< (length ac-prefix) ac-auto-start))
|
||||
args
|
||||
(if args
|
||||
(append args (with-no-warnings
|
||||
;; suppress obsolete warnings
|
||||
(ess-ac-objects t)))
|
||||
(with-no-warnings
|
||||
;; suppress obsolete warnings
|
||||
(ess-ac-objects))))))
|
||||
(make-obsolete-variable 'ess-ac-candidates "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
(defun ess-ac-help (sym)
|
||||
(if (string-match-p "= *\\'" sym)
|
||||
(ess-r-get-arg-help-string sym)
|
||||
(ess-r-get-object-help-string sym)))
|
||||
(make-obsolete-variable 'ess-ac-help "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
;; OBJECTS
|
||||
(defvar ac-source-R-objects
|
||||
'((prefix . ess-symbol-start)
|
||||
;; (requires . 2)
|
||||
(candidates . ess-ac-objects)
|
||||
(document . ess-r-get-object-help-string))
|
||||
"Auto-completion source for R objects.")
|
||||
(make-obsolete-variable 'ac-source-R-objects "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
(defun ess-ac-objects (&optional no-kill)
|
||||
"Get all cached objects."
|
||||
(declare (obsolete "Use company-mode instead" "ESS 19.04"))
|
||||
(let ((aprf ac-prefix))
|
||||
(when (and aprf (ess-process-live-p))
|
||||
(unless no-kill ;; workaround
|
||||
(kill-local-variable 'ac-use-comphist))
|
||||
(ess--get-cached-completions aprf ac-point))))
|
||||
|
||||
;; ARGS
|
||||
(defvar ac-source-R-args
|
||||
'((prefix . ess-arg-start)
|
||||
;; (requires . 0)
|
||||
(candidates . ess-ac-args)
|
||||
;; (action . ess-ac-action-args)
|
||||
(document . ess-r-get-arg-help-string))
|
||||
"Auto-completion source for R function arguments.")
|
||||
(make-obsolete-variable 'ac-source-R-args "Use company-mode instead" "ESS 19.04")
|
||||
|
||||
(defun ess-ac-args ()
|
||||
"Get the args of the function when inside parentheses."
|
||||
(declare (obsolete "Use company-mode-instead" "ESS 19.04"))
|
||||
(when (and ess--fn-name-start-cache ;; set in a call to ess-arg-start
|
||||
(ess-process-live-p))
|
||||
(let ((args (nth 2 (ess-function-arguments (car ess--fn-name-start-cache)))))
|
||||
(if args
|
||||
(setq-local ac-use-comphist nil)
|
||||
(kill-local-variable 'ac-use-comphist))
|
||||
(delete "..." args)
|
||||
(mapcar (lambda (a) (concat a ess-R-argument-suffix))
|
||||
args))))
|
||||
|
||||
(provide 'ess-r-completion)
|
||||
|
||||
;;; ess-r-completion.el ends here
|
||||
253
lisp/ess/ess-r-flymake.el
Normal file
253
lisp/ess/ess-r-flymake.el
Normal file
@@ -0,0 +1,253 @@
|
||||
;;; ess-r-flymake.el --- A ess-r Flymake backend -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Flymake is the built-in Emacs package that supports on-the-fly
|
||||
;; syntax checking. This file adds support for this in ess-r-mode by
|
||||
;; relying on the lintr package, available on CRAN and currently
|
||||
;; hosted at https://github.com/jimhester/lintr.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
(require 'ess-inf)
|
||||
(require 'flymake)
|
||||
|
||||
;; Appease the byte compiler for Emacs 25. Remove after dropping
|
||||
;; support for Emacs 25.
|
||||
(declare-function flymake-diag-region "flymake")
|
||||
(declare-function flymake-make-diagnostic "flymake")
|
||||
(declare-function flymake--overlays "flymake")
|
||||
|
||||
(defcustom ess-r-flymake-linters
|
||||
'("closed_curly_linter = NULL"
|
||||
"commas_linter = NULL"
|
||||
"commented_code_linter = NULL"
|
||||
"infix_spaces_linter = NULL"
|
||||
"line_length_linter = NULL"
|
||||
"object_length_linter = NULL"
|
||||
"object_name_linter = NULL"
|
||||
"object_usage_linter = NULL"
|
||||
"open_curly_linter = NULL"
|
||||
"pipe_continuation_linter = NULL"
|
||||
"single_quotes_linter = NULL"
|
||||
"spaces_inside_linter = NULL"
|
||||
"spaces_left_parentheses_linter = NULL"
|
||||
"trailing_blank_lines_linter = NULL"
|
||||
"trailing_whitespace_linter = NULL")
|
||||
"Default linters to use.
|
||||
Can be either a string with R expression to be used as
|
||||
is (e.g. 'lintr::default_linters'). Or a list of strings where
|
||||
each element is passed as argument to 'lintr::with_defaults'."
|
||||
:group 'ess-R
|
||||
:type '(choice string (repeat string))
|
||||
:package-version '(ess . "18.10"))
|
||||
|
||||
(defcustom ess-r-flymake-lintr-cache t
|
||||
"If non-nil, cache lintr results."
|
||||
:group 'ess-R
|
||||
:type 'boolean
|
||||
:package-version '(ess . "18.10"))
|
||||
|
||||
(defvar-local ess-r--flymake-proc nil)
|
||||
|
||||
(defvar-local ess-r--lintr-file nil
|
||||
"Location of the .lintr file for this buffer.")
|
||||
|
||||
(defvar ess-r--flymake-def-linter
|
||||
(replace-regexp-in-string
|
||||
"[\n\t ]+" " "
|
||||
"esslint <- function(str, ...) {
|
||||
if (!suppressWarnings(require(lintr, quietly=T))) {
|
||||
cat('@@error: @@`lintr` package not installed')
|
||||
} else {
|
||||
if (packageVersion('lintr') <= '1.0.3') {
|
||||
cat('@@error: @@Need `lintr` version > v1.0.3')
|
||||
} else {
|
||||
tryCatch(lintr::lint(commandArgs(TRUE), ...),
|
||||
error = function(e) {
|
||||
cat('@@warning: @@', e)
|
||||
})
|
||||
}
|
||||
}
|
||||
};"))
|
||||
|
||||
(defun ess-r--find-lintr-file ()
|
||||
"Return the absolute path to the .lintr file.
|
||||
Check first the current directory, then the project root, then
|
||||
the user's home directory. Return nil if we couldn't find a .lintr file."
|
||||
(let ((cur-dir-file (expand-file-name ".lintr" default-directory))
|
||||
(ess-proj-file (and (fboundp 'ess-r-package-project)
|
||||
(ess-r-package-project)
|
||||
(expand-file-name ".lintr" (cdr (ess-r-package-project)))))
|
||||
(proj-file (and (project-current)
|
||||
(project-roots (project-current))
|
||||
(expand-file-name ".lintr" (car (project-roots (project-current))))))
|
||||
(home-file (expand-file-name ".lintr" (getenv "HOME"))))
|
||||
(cond (;; current directory
|
||||
(file-readable-p cur-dir-file)
|
||||
cur-dir-file)
|
||||
;; Project root according to `ess-r-package-project'
|
||||
((and ess-proj-file
|
||||
(file-readable-p ess-proj-file))
|
||||
ess-proj-file)
|
||||
;; Project root according to `project-roots'
|
||||
((and proj-file
|
||||
(file-readable-p proj-file)))
|
||||
;; Home directory
|
||||
((file-readable-p home-file)
|
||||
home-file))))
|
||||
|
||||
(defun ess-r--flymake-linters ()
|
||||
"If `ess-r-flymake-linters' is a string, use that.
|
||||
Otherwise, construct a string to pass to lintr::with_defaults."
|
||||
(replace-regexp-in-string
|
||||
"[\n\t ]+" " "
|
||||
(if (stringp ess-r-flymake-linters)
|
||||
ess-r-flymake-linters
|
||||
(concat "lintr::with_defaults("
|
||||
(mapconcat #'identity
|
||||
ess-r-flymake-linters
|
||||
", ")
|
||||
")"))))
|
||||
|
||||
(defun ess-r--flymake-msg-type (str)
|
||||
"Transform STR into log level."
|
||||
(cond ((string= str "error: ") :error)
|
||||
((string= str "warning: ") :warning)
|
||||
((string= str "style: ") :note)
|
||||
(t (error "Invalid msg type %s" str))))
|
||||
|
||||
(defun ess-r--flymake-check-errors ()
|
||||
"Check for critical errors and return non-nil if such occurred."
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "@@\\(\\(error\\|warning\\): \\)@@" nil t)
|
||||
(let ((type (ess-r--flymake-msg-type (match-string 1)))
|
||||
(msg (buffer-substring-no-properties (match-end 0) (point-max))))
|
||||
(flymake-log type msg)
|
||||
(eq type :error))))
|
||||
|
||||
(defun ess-r--flymake-parse-output (msg-buffer src-buffer report-fn)
|
||||
"Parse the content of MSG-BUFFER for lint locations.
|
||||
SRC-BUFFER is the original source buffer. Collect all messages
|
||||
into a list and call REPORT-FN on it."
|
||||
(with-current-buffer msg-buffer
|
||||
(if (ess-r--flymake-check-errors)
|
||||
(with-current-buffer src-buffer
|
||||
;; we are in the sentinel here; don't throw but remove our hook instead
|
||||
(remove-hook 'flymake-diagnostic-functions 'ess-r-flymake t))
|
||||
(goto-char (point-min))
|
||||
(cl-loop
|
||||
while (search-forward-regexp
|
||||
;; Regex to match the output lint() gives us.
|
||||
(rx line-start "<text>:"
|
||||
;; row
|
||||
(group-n 1 (one-or-more num)) ":"
|
||||
;; column
|
||||
(group-n 2 (one-or-more num)) ": "
|
||||
;; type
|
||||
(group-n 3 (| "style: " "warning: " "error: "))
|
||||
;; msg
|
||||
(group-n 4 (one-or-more not-newline)) line-end)
|
||||
nil t)
|
||||
for msg = (match-string 4)
|
||||
for (beg . end) = (let ((line (string-to-number (match-string 1)))
|
||||
(col (string-to-number (match-string 2))))
|
||||
(flymake-diag-region src-buffer line col))
|
||||
for type = (ess-r--flymake-msg-type (match-string 3))
|
||||
collect (flymake-make-diagnostic src-buffer beg end type msg)
|
||||
into diags
|
||||
finally (funcall report-fn diags)))))
|
||||
|
||||
(defun ess-r-flymake (report-fn &rest _args)
|
||||
"A Flymake backend for ESS-R modes. Relies on the lintr package.
|
||||
REPORT-FN is flymake's callback function."
|
||||
(unless (executable-find inferior-ess-r-program)
|
||||
(error "Cannot find program '%s'" inferior-ess-r-program))
|
||||
;; Kill the process if earlier check was found. The sentinel of the earlier
|
||||
;; check will detect this.
|
||||
(when (process-live-p ess-r--flymake-proc)
|
||||
(kill-process ess-r--flymake-proc))
|
||||
(if (and (eql ess-use-flymake 'process)
|
||||
(not (ess-process-live-p)))
|
||||
(progn
|
||||
(funcall report-fn nil)
|
||||
(mapc #'delete-overlay (flymake--overlays)))
|
||||
(let ((src-buffer (current-buffer)))
|
||||
(setq ess-r--flymake-proc
|
||||
(make-process
|
||||
:name "ess-r-flymake" :noquery t :connection-type 'pipe
|
||||
:buffer (generate-new-buffer " *ess-r-flymake*")
|
||||
:command (list inferior-R-program
|
||||
"--no-save" "--no-restore" "--no-site-file" "--no-init-file" "--slave"
|
||||
"-e" (concat
|
||||
(when ess-r--lintr-file
|
||||
(concat "options(lintr.linter_file = \"" ess-r--lintr-file "\");"))
|
||||
ess-r--flymake-def-linter
|
||||
;; commandArgs(TRUE) returns everything after
|
||||
;; --args as a character vector
|
||||
"esslint(commandArgs(TRUE)"
|
||||
(unless ess-r--lintr-file
|
||||
(concat ", linters = " (ess-r--flymake-linters)))
|
||||
(when ess-r-flymake-lintr-cache
|
||||
", cache = TRUE")
|
||||
")")
|
||||
"--args" (buffer-substring-no-properties
|
||||
(point-min) (point-max)))
|
||||
:sentinel
|
||||
(lambda (proc _event)
|
||||
(cond
|
||||
((eq 'exit (process-status proc))
|
||||
(unwind-protect
|
||||
(if (eq proc (buffer-local-value 'ess-r--flymake-proc src-buffer))
|
||||
(ess-r--flymake-parse-output (process-buffer proc) src-buffer report-fn)
|
||||
(flymake-log :warning "Canceling obsolete check %s" proc))
|
||||
(kill-buffer (process-buffer proc))))
|
||||
((not (eq 'run (process-status proc)))
|
||||
(kill-buffer (process-buffer proc))))))))))
|
||||
|
||||
(defun ess-r-setup-flymake ()
|
||||
"Setup flymake for ESS.
|
||||
Activate flymake only if `ess-use-flymake' is non-nil."
|
||||
(when ess-use-flymake
|
||||
(when (< emacs-major-version 26)
|
||||
(error "ESS-flymake requires Emacs version 26 or later"))
|
||||
(when (string= "R" ess-dialect)
|
||||
(setq ess-r--lintr-file (ess-r--find-lintr-file))
|
||||
(add-hook 'flymake-diagnostic-functions #'ess-r-flymake nil t)
|
||||
;; Try not to enable flymake if flycheck is already running:
|
||||
(unless (bound-and-true-p flycheck-mode)
|
||||
(flymake-mode)))))
|
||||
|
||||
;; Enable flymake in Emacs 26+
|
||||
(when (<= 26 emacs-major-version)
|
||||
(if (eval-when-compile (<= 26 emacs-major-version))
|
||||
(add-hook 'ess-r-mode-hook #'ess-r-setup-flymake)
|
||||
(when ess-use-flymake
|
||||
(display-warning 'ess "ESS was compiled with older version of Emacs;\n `ess-r-flymake' won't be available"))))
|
||||
|
||||
(provide 'ess-r-flymake)
|
||||
|
||||
;;; ess-r-flymake.el ends here
|
||||
2785
lisp/ess/ess-r-mode.el
Normal file
2785
lisp/ess/ess-r-mode.el
Normal file
File diff suppressed because it is too large
Load Diff
590
lisp/ess/ess-r-package.el
Normal file
590
lisp/ess/ess-r-package.el
Normal file
@@ -0,0 +1,590 @@
|
||||
;;; ess-r-package.el --- Package development mode for R. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
||||
;; Author: Lionel Henry, Vitalie Spinu
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; see appropriate documentation section of ESS user manual
|
||||
|
||||
;;; Code:
|
||||
(require 'cl-lib)
|
||||
(require 'ess-inf)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'subr-x)
|
||||
(require 'tramp))
|
||||
;; Silence the byte compiler, OK because this file is only loaded by
|
||||
;; ess-r-mode and has no autoloads.
|
||||
(defvar ess-r-customize-alist)
|
||||
(declare-function inferior-ess-r-force "ess-r-mode")
|
||||
(declare-function ess-r-get-evaluation-env "ess-r-mode")
|
||||
(declare-function ess-r-set-evaluation-env "ess-r-mode")
|
||||
(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
|
||||
;; This can be drop after dropping support for Emacs 25:
|
||||
(declare-function tramp-file-name-localname "tramp" (cl-x))
|
||||
|
||||
(defvar ess-r-prompt-for-attached-pkgs-only nil
|
||||
"If nil provide completion for all installed R packages.
|
||||
If non-nil, only look for attached packages.")
|
||||
|
||||
(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
|
||||
(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
|
||||
(defcustom ess-r-package-auto-enable-namespaced-evaluation t
|
||||
"If non-nil, evaluation env is set to package env automatically.
|
||||
See also `ess-r-set-evaluation-env' and `ess-r-evaluation-env'."
|
||||
:group 'ess-r-package
|
||||
:type 'boolean)
|
||||
|
||||
(defvar-local ess-r-package--info-cache nil
|
||||
"Current package info cache.
|
||||
See `ess-r-package-info' for its structure.")
|
||||
|
||||
(defcustom ess-r-package-library-paths nil
|
||||
"Default path to find user packages.
|
||||
Can be either a string specifying a directory or a list of
|
||||
directories. This variable is also consulted by
|
||||
`xref-find-definitions' in R buffers. See `ess-r-xref-backend'."
|
||||
:group 'ess-r-package-library-paths
|
||||
:type `(choice string (repeat string)))
|
||||
|
||||
(defvar ess-r-package-root-file "DESCRIPTION"
|
||||
"Presence of this file indicates the project's root.")
|
||||
|
||||
(defvar ess-r-package-dirs
|
||||
'(("R" . 1)
|
||||
("r" . 1)
|
||||
("tests" . 1)
|
||||
("testthat" . 2)
|
||||
("inst" . 1)
|
||||
("include" . 2)
|
||||
("src" . 1))
|
||||
"Alist of directories names and their depth in R package hierarchy.
|
||||
This list is used to figure out whether the current file belongs
|
||||
to an R package. If the file specified in `ess-r-package-root-file'
|
||||
\(DESCRIPTION by default) is found at the presumed root directory
|
||||
of the package, the current directory is considered to be part of
|
||||
a R package.")
|
||||
|
||||
(defvar ess-r-package-source-roots
|
||||
'("R" "src" "tests" "inst/include")
|
||||
"List of sub-directories within R package where source files are located.
|
||||
All children of these directories are also considered source
|
||||
containing directories. Use `ess-r-package-source-dirs' to get
|
||||
all source dirs recursively within the current package.")
|
||||
|
||||
|
||||
;;;*;;; Package Detection
|
||||
|
||||
(defun ess-r-package-project (&optional dir)
|
||||
"Return the current package as an Emacs project instance.
|
||||
A project instance is a cons cell of the project type as symbol
|
||||
and the project path as string. If DIR is provided, the package
|
||||
is searched from that directory instead of `default-directory'."
|
||||
(let ((pkg-info (ess-r-package-info dir)))
|
||||
(when (car pkg-info)
|
||||
(cons 'ess-r-package (plist-get pkg-info :root)))))
|
||||
|
||||
(cl-defmethod project-roots ((project (head ess-r-package)))
|
||||
"Return the project root for ESS R packages"
|
||||
(list (cdr project)))
|
||||
|
||||
(defun ess-r-package-name (&optional dir)
|
||||
"Return the name of the current package as a string."
|
||||
(plist-get (ess-r-package-info dir) :name))
|
||||
|
||||
(defun ess-r-package-info (&optional dir)
|
||||
"Get the description of the R project in directory DIR.
|
||||
Return an plist with the keys :name and :root. When not in a
|
||||
package return '(nil). This value is cached buffer-locally for
|
||||
efficiency reasons."
|
||||
(if (and (null dir) (car ess-r-package--info-cache))
|
||||
ess-r-package--info-cache
|
||||
(let* ((path (ess-r-package--find-package-path (or dir default-directory)))
|
||||
(name (when path
|
||||
(ess-r-package--find-package-name path)))
|
||||
(info (if name
|
||||
(list :name name
|
||||
:root path)
|
||||
'(nil))))
|
||||
;; If DIR was supplied we cannot cache in the current buffer.
|
||||
(if dir
|
||||
info
|
||||
(setq-local ess-r-package--info-cache info)))))
|
||||
|
||||
(defun ess-r-package--all-source-dirs (dir)
|
||||
(when (file-directory-p dir)
|
||||
(cl-loop for f in (directory-files-and-attributes dir t "\\`[^.]")
|
||||
if (cadr f)
|
||||
append (cons (car f) (ess-r-package--all-source-dirs (car f))))))
|
||||
|
||||
(defun ess-r-package-source-dirs ()
|
||||
"Get paths within current R package with source files.
|
||||
Return nil if not in a package. Search sub-directories listed in
|
||||
`ess-r-package-source-roots' are searched recursively and
|
||||
return all physically present directories."
|
||||
(let ((pkg-root (plist-get (ess-r-package-info) :root)))
|
||||
(when pkg-root
|
||||
(let ((files (directory-files-and-attributes pkg-root t "\\`[^.]")))
|
||||
(cl-loop for f in files
|
||||
if (and (cadr f)
|
||||
(cl-some (lambda (el) (string-match-p (concat "/" el "$") (car f)))
|
||||
ess-r-package-source-roots))
|
||||
append (cons (car f)
|
||||
(ess-r-package--all-source-dirs (car f))))))))
|
||||
|
||||
(defun ess-r--select-package-name ()
|
||||
(inferior-ess-r-force)
|
||||
(let ((pkgs (ess-get-words-from-vector
|
||||
(format "print(.packages(%s), max = 1e6)\n"
|
||||
(if ess-r-prompt-for-attached-pkgs-only "FALSE" "TRUE"))))
|
||||
(current-pkg (ess-r-package-name)))
|
||||
(let ((env (ess-r-get-evaluation-env)))
|
||||
(when env
|
||||
(setq pkgs (append '("*none*") pkgs))
|
||||
(when (equal env current-pkg)
|
||||
(setq current-pkg "*none*"))))
|
||||
(ess-completing-read "Package" pkgs nil nil nil nil current-pkg)))
|
||||
|
||||
(defun ess-r-package--find-package-path (&optional dir)
|
||||
"Get the root of R package in directory DIR.
|
||||
DIR defaults to the current buffer's file name (if non-nil) or
|
||||
`default-directory'. Root is determined by locating
|
||||
`ess-r-package-root-file'. If the path looks like a tramp file,
|
||||
remove the remote information."
|
||||
(when-let ((path (cond
|
||||
(dir)
|
||||
((buffer-file-name)
|
||||
(file-name-directory (buffer-file-name)))
|
||||
(t
|
||||
default-directory)))
|
||||
(pkg-path
|
||||
(when path
|
||||
(or
|
||||
;; First check current directory
|
||||
(and (file-exists-p (expand-file-name ess-r-package-root-file path))
|
||||
path)
|
||||
;; Check for known directories in current path
|
||||
(let ((current-dir (file-name-nondirectory (directory-file-name path)))
|
||||
known-pkg-dir known-path presumptive-path)
|
||||
(while (and path (not presumptive-path))
|
||||
(setq current-dir (file-name-nondirectory (directory-file-name path)))
|
||||
(if (and (setq known-pkg-dir (assoc current-dir ess-r-package-dirs))
|
||||
(setq known-path (ess--parent-dir path (cdr known-pkg-dir)))
|
||||
(file-exists-p (expand-file-name ess-r-package-root-file known-path)))
|
||||
(setq presumptive-path known-path)
|
||||
(setq path (ess--parent-dir path 1))))
|
||||
presumptive-path)))))
|
||||
(if (file-remote-p pkg-path)
|
||||
(tramp-file-name-localname (tramp-dissect-file-name pkg-path))
|
||||
(directory-file-name pkg-path))))
|
||||
|
||||
(defun ess-r-package--find-package-name (path)
|
||||
(let ((file (expand-file-name ess-r-package-root-file path))
|
||||
(case-fold-search t))
|
||||
(when (file-exists-p file)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents-literally file)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "package: \\(.*\\)" nil t)
|
||||
(match-string 1))))))
|
||||
|
||||
|
||||
;;;*;;; UI
|
||||
|
||||
(defun ess-r-package-use-dir ()
|
||||
"Set process directory to current package directory."
|
||||
(interactive)
|
||||
(let ((pkg-root (plist-get (ess-r-package-info) :root)))
|
||||
(if pkg-root
|
||||
(ess-set-working-directory (abbreviate-file-name pkg-root))
|
||||
(user-error "Not in a project"))))
|
||||
|
||||
|
||||
;;;*;;; Evaluation
|
||||
|
||||
(defun ess-r-package-enable-namespaced-evaluation ()
|
||||
"Enable namespaced evaluation in current buffer.
|
||||
Namespaced evaluation is enabled if
|
||||
`ess-r-package-auto-enable-namespaced-evaluation' is non-nil."
|
||||
(when ess-r-package-auto-enable-namespaced-evaluation
|
||||
(let ((root (plist-get (ess-r-package-info) :root)))
|
||||
;; Check that we are in a file within R/
|
||||
(when (and root
|
||||
default-directory
|
||||
(> (length default-directory) (1+ (length root)))
|
||||
(let ((subpath (substring default-directory
|
||||
(1+ (length root))
|
||||
(length default-directory))))
|
||||
(string= (directory-file-name subpath) "R")))
|
||||
(ess-r-set-evaluation-env (ess-r-package-name))))))
|
||||
|
||||
(add-hook 'ess-r-mode-hook 'ess-r-package-enable-namespaced-evaluation)
|
||||
|
||||
(defun ess-r-package-eval-linewise (command &optional msg p actions)
|
||||
"Send COMMAND to R process.
|
||||
COMMAND is a command string with %s placeholder for the
|
||||
arguments. MSG is the message displayed in minibuffer with %s
|
||||
placeholder for the package name. P is the value of universal
|
||||
argument usually received from the upstream command and indicates
|
||||
which action in ACTIONS list to perform; if 0 or nil, first
|
||||
action, if 1 or (4) second if 2 or (16) third etc. ACTIONS is a
|
||||
list of strings (R arguments), or functions which return R
|
||||
arguments, or expressions which return R arguments."
|
||||
(inferior-ess-r-force)
|
||||
(let ((pkg-info (ess-r-package-info))
|
||||
(args (ess-r-command--build-args p actions)))
|
||||
(unless (car pkg-info)
|
||||
(user-error "Not in a package"))
|
||||
(ess-project-save-buffers)
|
||||
(message msg (plist-get pkg-info :name))
|
||||
(display-buffer (ess-get-process-buffer))
|
||||
(let ((pkg-path (concat "'" (abbreviate-file-name (plist-get pkg-info :root)) "'")))
|
||||
(ess-eval-linewise (format command (concat pkg-path args))))))
|
||||
|
||||
(defun ess-r-command--build-args (ix &optional actions)
|
||||
(let* ((n (cond ((null ix) 0)
|
||||
((listp ix) (round (log (car ix) 4)))
|
||||
((integerp ix) ix)
|
||||
(t (error "Invalid index"))))
|
||||
(action (nth n actions))
|
||||
(args (cond ((null action) "")
|
||||
((stringp action) action)
|
||||
((functionp action) (funcall action))
|
||||
((listp action) (eval action))
|
||||
(t (error "Invalid action")))))
|
||||
(if (string= "" args)
|
||||
args
|
||||
(concat ", " args))))
|
||||
|
||||
|
||||
;;;*;;; Devtools Integration
|
||||
|
||||
(defun ess-r-devtools-load-package (&optional arg)
|
||||
"Interface for `devtools::load_all()'.
|
||||
With prefix ARG ask for extra args."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::load_all(%s)\n" "Loading %s" arg
|
||||
'("" (read-string "Arguments: " "recompile = TRUE"))))
|
||||
|
||||
(defun ess-r-devtools-unload-package ()
|
||||
"Interface to `devtools::unload()'."
|
||||
(interactive)
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::unload(%s)\n" "Unloading %s"))
|
||||
|
||||
(defun ess-r-devtools-check-package (&optional arg)
|
||||
"Interface for `devtools::check()'.
|
||||
With prefix ARG ask for extra args."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::check(%s)\n" "Checking %s" arg
|
||||
'("" (read-string "Arguments: " "vignettes = FALSE"))))
|
||||
|
||||
(defun ess-r-devtools-check-with-winbuilder (&optional arg)
|
||||
"Interface for `devtools::check_win_XYZ()'.
|
||||
With prefix argument, as for arguments to `devtools::check_win_XYZ()' function."
|
||||
(interactive "P")
|
||||
(let ((type (completing-read "Release: " '("devel" "release" "oldrelease") nil t)))
|
||||
(ess-r-package-eval-linewise
|
||||
(format "devtools:::check_win_%s(%%s)\n" type)
|
||||
"Checking %s on CRAN's Windows server" arg
|
||||
'("" (read-string "Arguments: ")))))
|
||||
|
||||
(defvar ess-r-rhub--history nil)
|
||||
(declare-function ess-r-check-install-package "ess-r-mode.el")
|
||||
(defun ess-r-rhub-check-package (&optional arg)
|
||||
"Interface for `rhub::check()'.
|
||||
With prefix ARG allow for editing of the `rhub::check_for_cran()' arguments."
|
||||
(interactive "P")
|
||||
(inferior-ess-r-force)
|
||||
(ess-r-check-install-package "rhub")
|
||||
(let* ((platforms (cons "RECOMMENDED" (ess-get-words-from-vector "rhub::platforms()$name\n")))
|
||||
(platform (completing-read "Platform: " platforms nil t nil
|
||||
ess-r-rhub--history (car ess-r-rhub--history)))
|
||||
(cmd (if (string= "RECOMMENDED" platform)
|
||||
"rhub::check_for_cran(%s)\n"
|
||||
(format "rhub::check_for_cran(%%s, platforms = '%s')\n" platform)))
|
||||
(msg (format "Checking %%s on RHUB (%s)" platform))
|
||||
;; Solaris check is flaky and it seems that solaris check is not run on
|
||||
;; CRAN itself with --as-cran options https://github.com/r-hub/rhub/issues/339
|
||||
(args (cond ((string-match-p "solaris" platform)
|
||||
"check_args = c('--no-stop-on-test-error', '--no-vignettes')")
|
||||
(t "check_args = c('--as-cran', '--no-stop-on-test-error')"))))
|
||||
(ess-r-package-eval-linewise cmd msg arg
|
||||
`(,args (read-string "Arguments: " ,(concat args ", valgrind = FALSE"))))))
|
||||
|
||||
(defun ess-r-devtools-build (&optional arg)
|
||||
"Interface for `devtools::build()'.
|
||||
With prefix ARG, build with 'vignettes = FALSE'."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::build(%s)\n" "Building %s" arg
|
||||
'("" "vignettes = FALSE")))
|
||||
|
||||
(defun ess-r-devtools-test-package (&optional arg)
|
||||
"Interface for `devtools::test()'.
|
||||
With prefix argument ARG, run tests on current file only."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::test(%s)\n" "Testing %s" arg
|
||||
'("" ess-r-devtools--cur-file-filter)))
|
||||
|
||||
(defun ess-r-devtools--cur-file-filter ()
|
||||
(let ((file (or (and buffer-file-name
|
||||
(file-name-nondirectory buffer-file-name))
|
||||
(error "Buffer not visiting a file"))))
|
||||
(format "filter = \"%s\""
|
||||
(if (string-match "test-\\([[:alnum:]_-]+\\)\\.[rR]" file)
|
||||
(match-string-no-properties 1 file)
|
||||
(file-name-base buffer-file-name)))))
|
||||
|
||||
(defvar ess-r-devtools-revdep-check-cmd
|
||||
"local({
|
||||
pkg_path <- %s
|
||||
res <- devtools::revdep_check(pkg_path)
|
||||
|
||||
if (file.exists(file.path(pkg_path, 'revdep'))) {
|
||||
save_path <- file.path(pkg_path, 'revdep')
|
||||
} else {
|
||||
save_path <- file.path(pkg_path, '.metadata', 'revdep')
|
||||
}
|
||||
devtools::revdep_check_save_summary(res, save_path)
|
||||
|
||||
logs_path <- file.path(save_path, 'logs')
|
||||
if (!dir.exists(logs_path)) {
|
||||
dir.create(logs_path)
|
||||
}
|
||||
devtools::revdep_check_save_logs(res, logs_path)
|
||||
})
|
||||
")
|
||||
|
||||
(defun ess-project-save-buffers ()
|
||||
"Offer to save modified files in the current project.
|
||||
Respects `ess-save-silently', which see."
|
||||
(let ((cur-proj ess-r-package--info-cache))
|
||||
(dolist (buf (buffer-list))
|
||||
(when-let ((file (buffer-file-name buf))
|
||||
(buf-proj (buffer-local-value 'ess-r-package--info-cache buf)))
|
||||
(when (equal cur-proj buf-proj)
|
||||
(ess-save-file file))))))
|
||||
|
||||
(defun ess-r-devtools-document-package (&optional arg)
|
||||
"Interface for `devtools::document()'.
|
||||
With prefix ARG ask for extra arguments."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::document(%s)\n" "Documenting %s" arg
|
||||
'("" (read-string "Arguments: "))))
|
||||
|
||||
(defun ess-r-devtools-install-package (&optional arg)
|
||||
"Interface to `devtools::install()'.
|
||||
By default the installation is \"quick\" with arguments quick =
|
||||
TRUE, upgrade = FALSE, build = FALSE. On prefix ARG
|
||||
\\[universal-argument] install with the default
|
||||
`devtools::install()' arguments."
|
||||
(interactive "P")
|
||||
(ess-r-package-eval-linewise
|
||||
"devtools::install(%s)\n" "Installing %s" arg
|
||||
'("quick = TRUE, build = FALSE, upgrade = FALSE, keep_source = TRUE"
|
||||
(read-string "Arguments: " "keep_source = TRUE, force = TRUE"))))
|
||||
|
||||
(defvar ess-r-devtools--install-github-history nil)
|
||||
(defun ess-r-devtools-install-github (&optional arg)
|
||||
"Interface to `devtools::install_github()'.
|
||||
Asks for GitHub repository in the form of user/repo. Force
|
||||
re-installation when called with a prefix ARG."
|
||||
(interactive "P")
|
||||
(let ((command "devtools::install_github(%s%s)")
|
||||
(repo (format "'%s'"
|
||||
(read-string "User/Repo: " nil
|
||||
'ess-r-devtools--install-github-history
|
||||
(car ess-r-devtools--install-github-history))))
|
||||
(args (if arg
|
||||
(ess-r-command--build-args 0 '((read-string "Arguments: " "force = TRUE")))
|
||||
"")))
|
||||
(inferior-ess-r-force)
|
||||
(unless (derived-mode-p 'inferior-ess-mode)
|
||||
(display-buffer (ess-get-process-buffer)
|
||||
'(nil . ((inhibit-same-window . t)))))
|
||||
(message "Installing %s from github" repo)
|
||||
(ess-eval-linewise (format command repo args))))
|
||||
|
||||
(defun ess-r-devtools-create-package ()
|
||||
"Interface to `devtools::create()'.
|
||||
Default location is determined by the first element of
|
||||
`ess-r-package-library-paths'."
|
||||
(interactive)
|
||||
(let* ((command "devtools::create(\"%s\")")
|
||||
(default-path (if (stringp ess-r-package-library-paths)
|
||||
ess-r-package-library-paths
|
||||
(car ess-r-package-library-paths)))
|
||||
(path (read-directory-name "Path: " default-path)))
|
||||
(ess-eval-linewise (format command path))))
|
||||
|
||||
(defun ess-r-devtools-execute-command (&optional arg)
|
||||
"Asks with completion for a devtools command.
|
||||
When called with prefix ARG asks for additional arguments."
|
||||
(interactive "P")
|
||||
(inferior-ess-r-force)
|
||||
(let* ((devtools-funs (ess-get-words-from-vector ".ess_devtools_functions()\n"))
|
||||
(fun (completing-read "Function: " devtools-funs))
|
||||
(command (format "devtools::%s(%%s)\n" fun)))
|
||||
(ess-r-package-eval-linewise
|
||||
command (format "Running %s" fun) arg
|
||||
'("" (read-string "Arguments: ")))))
|
||||
|
||||
|
||||
;;;*;;; Minor Mode
|
||||
|
||||
(defcustom ess-r-package-auto-activate t
|
||||
"If non-nil, `ess-r-package-mode' is turned on within R packages.
|
||||
If 't' the minor mode auto-activates in R packages. See
|
||||
`ess-r-package-exclude-modes' if you wish to inhibit
|
||||
`ess-r-package-mode' in specific buffers."
|
||||
:group 'ess-r-package
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom ess-r-package-exclude-modes '(fundamental-mode)
|
||||
"A list of modes where `ess-r-package' must not be activated.
|
||||
The check is done with `derived-mode-p'."
|
||||
:group 'ess-r-package
|
||||
:type '(repeat symbol)
|
||||
:package-version '(ess "18.10"))
|
||||
|
||||
(defcustom ess-r-package-enter-hook nil
|
||||
"Normal hook run on entering `ess-r-package-mode'."
|
||||
:group 'ess-r-package
|
||||
:type 'hook)
|
||||
|
||||
(defcustom ess-r-package-exit-hook nil
|
||||
"Normal hook run on exiting `ess-r-package-mode'."
|
||||
:group 'ess-r-package
|
||||
:type 'hook)
|
||||
|
||||
(defcustom ess-r-package-mode-line
|
||||
;; FIXME Emacs 25.1: Use `when-let'
|
||||
'(:eval (let ((pkg-name (ess-r-package-name)))
|
||||
(when pkg-name
|
||||
(format " [pkg:%s]" pkg-name))))
|
||||
"Mode line for ESS developer.
|
||||
Set this variable to nil to disable the mode line entirely."
|
||||
:group 'ess-r-package
|
||||
:type 'sexp
|
||||
:risky t)
|
||||
|
||||
(defvar ess-r-package-mode-map
|
||||
(let ((ess-r-package-mode-map (make-sparse-keymap)))
|
||||
(define-key ess-r-package-mode-map "\C-c\C-w" 'ess-r-package-dev-map)
|
||||
ess-r-package-mode-map))
|
||||
|
||||
(define-minor-mode ess-r-package-mode
|
||||
"Minor mode for enabling R package development features.
|
||||
|
||||
\\{ess-r-package-mode-map}"
|
||||
:init-value nil
|
||||
:keymap ess-r-package-mode-map
|
||||
:lighter ess-r-package-mode-line
|
||||
(if ess-r-package-mode
|
||||
(progn
|
||||
;; Forward relevant R settings for interacting with inferior
|
||||
;; processes from any mode
|
||||
(let ((vars '(ess-dialect
|
||||
ess-setwd-command
|
||||
ess-getwd-command
|
||||
ess-quit-function
|
||||
inferior-ess-reload-function)))
|
||||
(mapc (lambda (var)
|
||||
(set (make-local-variable var)
|
||||
(eval (cdr (assq var ess-r-customize-alist)))))
|
||||
vars))
|
||||
(add-hook 'project-find-functions #'ess-r-package-project)
|
||||
(run-hooks 'ess-r-package-enter-hook))
|
||||
(remove-hook 'project-find-functions #'ess-r-package-project)
|
||||
(run-hooks 'ess-r-package-exit-hook)))
|
||||
|
||||
(add-hook 'after-change-major-mode-hook 'ess-r-package-auto-activate)
|
||||
|
||||
|
||||
;;;*;;; Activation
|
||||
|
||||
(defun ess-r-package-auto-activate ()
|
||||
"Activate developer if current file is part of a package."
|
||||
(when (and ess-r-package-auto-activate
|
||||
(or (buffer-name) default-directory)
|
||||
(not (eq major-mode 'minibuffer-inactive-mode))
|
||||
(or
|
||||
;; users probably have these in fundamental mode
|
||||
(member (buffer-name) '("DESCRIPTION" "NAMESPACE"))
|
||||
(if ess-r-package-exclude-modes
|
||||
(not (apply #'derived-mode-p ess-r-package-exclude-modes))
|
||||
t)))
|
||||
(when (car (ess-r-package-info))
|
||||
(ess-r-package-mode 1))))
|
||||
|
||||
(defun ess-r-package-re-activate ()
|
||||
"Restart `ess-r-package-mode'.
|
||||
First, deactivate package mode if active, and activate if in
|
||||
package mode. Use this function if state of the buffer such as
|
||||
`default-directory' has changed."
|
||||
(when ess-r-package-mode
|
||||
(ess-r-package-mode -1))
|
||||
(setq ess-r-package--info-cache nil)
|
||||
(ess-r-package-auto-activate))
|
||||
|
||||
(defvar-local ess-r--old-default-dir nil)
|
||||
(defun ess-r-package-default-directory-tracker (&rest _)
|
||||
(unless (equal ess-r--old-default-dir default-directory)
|
||||
(setq ess-r--old-default-dir default-directory)
|
||||
(ess-r-package-re-activate)))
|
||||
|
||||
(defun ess-r-package-activate-directory-tracker ()
|
||||
(add-hook 'after-change-functions 'ess-r-package-default-directory-tracker t t))
|
||||
|
||||
(add-hook 'shell-mode-hook 'ess-r-package-activate-directory-tracker t)
|
||||
(add-hook 'eshell-mode-hook 'ess-r-package-activate-directory-tracker t)
|
||||
(when (fboundp 'advice-add)
|
||||
(require 'shell)
|
||||
(advice-add 'shell-resync-dirs :after 'ess-r-package-re-activate))
|
||||
|
||||
|
||||
;;;*;;; Deprecated variables and functions
|
||||
(defun ess-developer (&optional _val)
|
||||
(error "As of ESS 16.04, `ess-developer' is deprecated. Use `ess-r-set-evaluation-env' instead"))
|
||||
|
||||
(defalias 'ess-toggle-developer 'ess-developer)
|
||||
(define-obsolete-function-alias 'ess-r-devtools-check-package-buildwin 'ess-r-devtools-check-with-winbuilder)
|
||||
(define-obsolete-function-alias 'ess-r-devtools-ask 'ess-r-devtools-execute-command "18.04")
|
||||
|
||||
(make-obsolete-variable 'ess-developer "Please use `ess-developer-select-package' and `ess-r-set-evaluation-env' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-root-file "Please use `ess-r-package-root-file' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-packages "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-load-on-add-commands "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-activate-in-package "Please use `ess-r-package-auto-activate' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-enter-hook "Please use `ess-r-package-enter-hook' instead." "16.04")
|
||||
(make-obsolete-variable 'ess-developer-exit-hook "Please use `ess-r-package-exit-hook' instead." "16.04")
|
||||
|
||||
|
||||
(provide 'ess-r-package)
|
||||
|
||||
;;; ess-r-package.el ends here
|
||||
1563
lisp/ess/ess-r-syntax.el
Normal file
1563
lisp/ess/ess-r-syntax.el
Normal file
File diff suppressed because it is too large
Load Diff
145
lisp/ess/ess-r-xref.el
Normal file
145
lisp/ess/ess-r-xref.el
Normal file
@@ -0,0 +1,145 @@
|
||||
;;; ess-r-xref.el --- An xref backend for R. -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
;; Author: Aaron Jacobs
|
||||
;; Created: 21 January 2018
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file contains an xref backend for `ess-r-mode'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'xref)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-r-package)
|
||||
(require 'ess-tracebug)
|
||||
|
||||
;; Silence the byte compiler. OK because this file is only loaded by ess-r-mode.
|
||||
(declare-function inferior-ess-r-force "ess-r-mode")
|
||||
|
||||
|
||||
(defvar ess-r-xref-pkg-sources nil
|
||||
"Alist of R package->directory associations.
|
||||
Each element is a cons cell (PACKAGE . DIRECTORY). This variable
|
||||
is used as a cache of package->directory associations, but could
|
||||
be used by the users for a more refined control of package
|
||||
locations than `ess-r-package-library-paths'.")
|
||||
|
||||
(defun ess-r-xref-backend ()
|
||||
"An `xref-backend-functions' implementation for `ess-r-mode'.
|
||||
R's xref backend searches for `ess-r-package-library-paths' when
|
||||
srcrefs point to temporary locations."
|
||||
'ess-r)
|
||||
|
||||
(cl-defmethod xref-backend-identifier-at-point ((_backend (eql ess-r)))
|
||||
(let ((sym (ess-symbol-at-point)))
|
||||
(when sym
|
||||
(symbol-name sym))))
|
||||
|
||||
(cl-defmethod xref-backend-definitions ((_backend (eql ess-r)) symbol)
|
||||
(let ((xref (ess-r-xref--xref symbol)))
|
||||
(when xref
|
||||
(list xref))))
|
||||
|
||||
(cl-defmethod xref-backend-apropos ((_backend (eql ess-r)))
|
||||
;; Not yet supported.
|
||||
nil)
|
||||
|
||||
(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql ess-r)))
|
||||
(inferior-ess-r-force)
|
||||
(ess-get-words-from-vector ".ess_all_functions()\n"))
|
||||
|
||||
(defun ess-r-xref--srcref (symbol)
|
||||
(inferior-ess-r-force)
|
||||
;; Look for `symbol' inside the package namespace
|
||||
(let* ((pkg (ess-r-package-name))
|
||||
(pkg (if pkg
|
||||
(concat "\"" pkg "\"")
|
||||
"NULL")))
|
||||
(with-current-buffer (ess-command (format ".ess_srcref(\"%s\", %s)\n" symbol pkg))
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward "Error" nil t)
|
||||
(progn (message "R srcref lookup failed:\n%s" (buffer-string))
|
||||
(sit-for 1)
|
||||
nil)
|
||||
(when (re-search-forward "(" nil 'noerror)
|
||||
(goto-char (match-beginning 0))
|
||||
(read (current-buffer)))))))
|
||||
|
||||
(defun ess-r-xref--pkg-srcfile (symbol src-file &optional default-pkg)
|
||||
"Look in the source directory of the R package containing symbol SYMBOL for SRC-FILE.
|
||||
DEFAULT-PKG is the name of the package where presumably SYMBOL is located."
|
||||
(let* ((pkgs (delq nil
|
||||
(delete-dups
|
||||
(or (cons default-pkg
|
||||
(ess-get-words-from-vector (format ".ess_fn_pkg(\"%s\")\n" symbol)))
|
||||
(user-error "Can't find package for symbol %s" symbol)))))
|
||||
(lib-dirs (cond ((stringp ess-r-package-library-paths)
|
||||
(list ess-r-package-library-paths))
|
||||
((listp ess-r-package-library-paths)
|
||||
ess-r-package-library-paths)
|
||||
(t (user-error "Invalid value of `ess-r-package-library-paths'"))))
|
||||
(loc (or (cl-loop for pkg in pkgs
|
||||
for dir = (assoc-default pkg ess-r-xref-pkg-sources)
|
||||
when (file-exists-p dir) return (cons pkg dir))
|
||||
(cl-loop for pkg in pkgs
|
||||
for dir in lib-dirs
|
||||
for path = (expand-file-name pkg dir)
|
||||
when (file-exists-p path) return (cons pkg path))))
|
||||
(file (when loc (expand-file-name src-file (cdr loc)))))
|
||||
(when file
|
||||
(unless (file-readable-p file)
|
||||
(error "Can't read %s" file))
|
||||
;; Cache package's source directory.
|
||||
(unless (assoc (car loc) ess-r-xref-pkg-sources)
|
||||
(push loc ess-r-xref-pkg-sources))
|
||||
file)))
|
||||
|
||||
(defun ess-r-xref--xref (symbol)
|
||||
"Create an xref for the source file reference of R symbol SYMBOL."
|
||||
(let ((ref (ess-r-xref--srcref symbol)))
|
||||
(when ref
|
||||
(let ((file (nth 0 ref))
|
||||
(line (nth 1 ref))
|
||||
(col (nth 2 ref)))
|
||||
(or
|
||||
;; 1) Result of ESS evaluation
|
||||
(let* ((ess-ref (gethash file ess--srcrefs))
|
||||
(ess-buff (when ess-ref (ess--dbg-find-buffer (car ess-ref)))))
|
||||
(when ess-buff
|
||||
;; FIXME: this breaks when eval is on larger spans than function
|
||||
(xref-make symbol (xref-make-buffer-location ess-buff (nth 2 ess-ref)))))
|
||||
;; 2) Actual file location
|
||||
(when (file-readable-p file)
|
||||
(xref-make symbol (xref-make-file-location file line col)))
|
||||
;; 3) Temporary sources - truncate and locate in ess-r-package-library-paths
|
||||
(when (string-match "/\\([^/]+\\)/\\(R/.*\\)$" file)
|
||||
(let ((pkg-file (ess-r-xref--pkg-srcfile
|
||||
symbol (match-string 2 file) (match-string 1 file))))
|
||||
(when pkg-file
|
||||
(xref-make symbol (xref-make-file-location
|
||||
(expand-file-name pkg-file) line col))))))))))
|
||||
|
||||
(provide 'ess-r-xref)
|
||||
|
||||
;;; ess-r-xref.el ends here
|
||||
461
lisp/ess/ess-rd.el
Normal file
461
lisp/ess/ess-rd.el
Normal file
@@ -0,0 +1,461 @@
|
||||
;; ess-rd.el --- Support for editing R documentation (Rd) source -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
;; Author: KH <Kurt.Hornik@ci.tuwien.ac.at>
|
||||
;; Created: 25 July 1997
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
(eval-when-compile
|
||||
(require 'subr-x))
|
||||
|
||||
(require 'ess-help)
|
||||
(require 'ess-inf)
|
||||
;; Silence the byte compiler, see TODO below; can we remove these?
|
||||
(defvar ess-help-r-sec-regex)
|
||||
(defvar ess-help-r-sec-keys-alist)
|
||||
(defvar ess-r-customize-alist)
|
||||
|
||||
(defcustom Rd-mode-hook nil
|
||||
"Hook to be run when Rd mode is entered."
|
||||
:type 'hook
|
||||
:group 'ess-R
|
||||
:group 'ess-hooks)
|
||||
|
||||
(define-abbrev-table 'Rd-mode-skeleton-abbrev-table
|
||||
'(("`ag" "\\arguments" nil :system t)
|
||||
("`al" "\\alias" nil :system t)
|
||||
("`au" "\\author" nil :system t)
|
||||
("`bf" "\\bold" nil :system t)
|
||||
("`co" "\\code" nil :system t)
|
||||
("`de" "\\describe" nil :system t)
|
||||
("`dn" "\\description" nil :system t)
|
||||
("`dt" "\\details" nil :system t)
|
||||
("`em" "\\emph" nil :system t)
|
||||
("`en" "\\enumerate" nil :system t)
|
||||
("`ex" "\\examples" nil :system t)
|
||||
("`fi" "\\file" nil :system t)
|
||||
("`fo" "\\format" nil :system t)
|
||||
("`it" "\\item" nil :system t)
|
||||
("`iz" "\\itemize" nil :system t)
|
||||
("`kw" "\\keyword" nil :system t)
|
||||
("`li" "\\link" nil :system t)
|
||||
("`me" "\\method" nil :system t)
|
||||
("`na" "\\name" nil :system t)
|
||||
("`no" "\\note" nil :system t)
|
||||
("`re" "\\references" nil :system t)
|
||||
("`sa" "\\seealso" nil :system t)
|
||||
("`se" "\\section" nil :system t)
|
||||
("`so" "\\source" nil :system t)
|
||||
("`ss" "\\subsection" nil :system t)
|
||||
("`sy" "\\synopsis" nil :system t)
|
||||
("`ta" "\\tabular" nil :system t)
|
||||
("`ti" "\\title" nil :system t)
|
||||
("`us" "\\usage" nil :system t)
|
||||
("`va" "\\value" nil :system t))
|
||||
"Abbrev table for R documentation keywords.
|
||||
All Rd mode abbrevs start with a grave accent (`)."
|
||||
:case-fixed t)
|
||||
|
||||
(define-abbrev-table 'Rd-mode-abbrev-table ()
|
||||
"Abbrev table for Rd mode."
|
||||
:parents (list Rd-mode-skeleton-abbrev-table))
|
||||
|
||||
(defvar Rd-mode-syntax-table
|
||||
(let ((tab (copy-syntax-table text-mode-syntax-table)))
|
||||
(modify-syntax-entry ?\\ "\\" tab)
|
||||
(modify-syntax-entry ?\{ "(}" tab)
|
||||
(modify-syntax-entry ?\} "){" tab)
|
||||
;; Nice for editing, not for parsing ...
|
||||
(modify-syntax-entry ?\( "()" tab)
|
||||
(modify-syntax-entry ?\) ")(" tab)
|
||||
(modify-syntax-entry ?\[ "(]" tab)
|
||||
(modify-syntax-entry ?\] ")[" tab)
|
||||
;; To get strings right
|
||||
;; (modify-syntax-entry ?\' "\"" Rd-mode-syntax-table)
|
||||
(modify-syntax-entry ?\" "\"" tab)
|
||||
;; To make abbrevs starting with a grave accent work ...
|
||||
(modify-syntax-entry ?\` "w" tab)
|
||||
;; Comments
|
||||
(modify-syntax-entry ?\% "<" tab)
|
||||
(modify-syntax-entry ?\n ">" tab)
|
||||
tab)
|
||||
"Syntax table for `Rd-mode'.")
|
||||
|
||||
(defvar Rd-mode-parse-syntax-table
|
||||
(let ((tab (copy-syntax-table Rd-mode-syntax-table)))
|
||||
;; To make parse-partial-sexps do the thing we want for computing
|
||||
;; indentations
|
||||
(modify-syntax-entry ?\( "_" tab)
|
||||
(modify-syntax-entry ?\) "_" tab)
|
||||
(modify-syntax-entry ?\[ "_" tab)
|
||||
(modify-syntax-entry ?\] "_" tab)
|
||||
tab)
|
||||
"Syntax table for parsing Rd mode.")
|
||||
|
||||
(defvar Rd-section-names
|
||||
'("Rdversion" "arguments" "alias" "author" "concept" "describe" "description"
|
||||
"details" "docType" "encoding" "enumerate" "examples" "format"
|
||||
"itemize" "keyword" "name" "note" "preformatted" "references"
|
||||
"seealso" "section" "source" "subsection" "synopsis"
|
||||
"tabular" "title" "usage"
|
||||
"value"))
|
||||
|
||||
(defvar Rd-keywords
|
||||
'(
|
||||
;; the next two lines: only valid in R <= 2.8.1
|
||||
;; commented out on 2011-01-14 for ESS version 5.13:
|
||||
;; "Alpha" "Gamma" "alpha" "beta" "epsilon" "lambda" "mu" "pi" "sigma"
|
||||
;; "ge" "le" "left" "right"
|
||||
;;
|
||||
"R" "RdOpts" "S3method" "S4method" "Sexpr" "acronym"
|
||||
"bold" "cite" "code" "command" "cr" "dQuote" "deqn" "dfn" "dontrun"
|
||||
"dontshow" "donttest" "dots" "email" "emph" "enc" "env" "eqn" "figure" "file"
|
||||
"href" "if" "ifelse"
|
||||
"item" "kbd" "ldots" "linkS4class" "link" "method"
|
||||
"newcommand" "option" "out"
|
||||
"pkg" "sQuote" "renewcommand"
|
||||
"samp" "strong" "tab" "url" "var" "verb"
|
||||
;; System macros (from <R>/share/Rd/macros/system.Rd ):
|
||||
"CRANpkg" "PR" "sspace" "doi"
|
||||
"packageTitle" "packageDescription" "packageAuthor"
|
||||
"packageMaintainer" "packageDESCRIPTION" "packageIndices"
|
||||
))
|
||||
|
||||
(defvar Rd-font-lock-keywords
|
||||
(list
|
||||
(cons
|
||||
(concat "\\\\\\("
|
||||
(mapconcat 'identity Rd-section-names "\\|")
|
||||
"\\>\\)")
|
||||
'font-lock-reference-face) ; Rd-bold-face
|
||||
(cons
|
||||
(concat "\\\\\\("
|
||||
(mapconcat 'identity Rd-keywords "\\|")
|
||||
"\\>\\)")
|
||||
'font-lock-keyword-face)
|
||||
'("^#\\(ifn?def\\)\\s-+\\(\\sw+\\)"
|
||||
(1 font-lock-builtin-face)
|
||||
(2 font-lock-variable-name-face nil t))
|
||||
'("^#\\(endif\\)" 1 font-lock-builtin-face))
|
||||
"Additional Rd expressions to highlight.")
|
||||
|
||||
(defvar Rd-indent-level 2
|
||||
"Indentation of Rd code with respect to containing blocks.")
|
||||
|
||||
(defvar Rd-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "\t" #'indent-according-to-mode)
|
||||
(define-key map "\C-j" #'reindent-then-newline-and-indent)
|
||||
(define-key map "\C-m" #'reindent-then-newline-and-indent)
|
||||
(define-key map "\C-c\C-p" #'Rd-preview-help)
|
||||
(define-key map "\C-c\C-j" #'Rd-mode-insert-item)
|
||||
(define-key map "\C-c\C-e" #'Rd-mode-insert-skeleton)
|
||||
(define-key map "\C-c\C-f" #'Rd-font)
|
||||
(define-key map "\C-c\C-s" #'Rd-mode-insert-section)
|
||||
(define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
|
||||
(define-key map "\C-c\C-r" #'ess-eval-region)
|
||||
(define-key map "\C-c\C-c" #'ess-eval-region-or-function-or-paragraph-and-step)
|
||||
(define-key map "\C-\M-x" #'ess-eval-region-or-function-or-paragraph)
|
||||
(define-key map "\C-c\C-v" #'ess-display-help-on-object)
|
||||
(define-key map "\C-c\C-w" #'ess-switch-process)
|
||||
(define-key map "\C-c\C-y" #'ess-switch-to-ESS)
|
||||
(define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
|
||||
map)
|
||||
"Keymap used in Rd mode.")
|
||||
|
||||
(defvar Rd-mode-menu
|
||||
(list "Rd"
|
||||
["Markup [word]" Rd-font t]
|
||||
["Insert Item" Rd-mode-insert-item t]
|
||||
["Insert Section" Rd-mode-insert-section t]
|
||||
["Insert Skeleton" Rd-mode-insert-skeleton t]
|
||||
"-"
|
||||
["Preview" Rd-preview-help t]
|
||||
"-"
|
||||
["Eval Line" ess-eval-line-visibly-and-step t]
|
||||
["Eval Region" ess-eval-region t]
|
||||
["Switch to ESS Process" ess-switch-to-ESS t]
|
||||
["Switch the ESS Process" ess-switch-process t]
|
||||
["Switch to end{ESS Pr}" ess-switch-to-end-of-ESS t]
|
||||
"-"
|
||||
["Toggle Abbrev Mode" abbrev-mode t]
|
||||
["Toggle Auto-Fill Mode" auto-fill-mode t]
|
||||
"-"
|
||||
["Submit Bug Report" ess-submit-bug-report t]
|
||||
"-"
|
||||
["Describe Rd Mode" describe-mode t])
|
||||
"Menu used in Rd mode.")
|
||||
|
||||
(defvar Rd-to-help-command "R CMD Rd2txt"
|
||||
"Shell command for converting R documentation source to help text.")
|
||||
|
||||
(defvar Rd-font-list
|
||||
'((?\C-b "\\bold{" "}")
|
||||
(?\C-c "\\code{" "}")
|
||||
(?\C-e "\\emph{" "}")
|
||||
(?\C-l "\\link{" "}")
|
||||
(?l "\\code{\\link{" "}}")
|
||||
(?\C-m "\\email{" "}")
|
||||
(?\C-q "\\eqn{" "}")
|
||||
(?\C-u "\\url{" "}")
|
||||
)
|
||||
"List of \"fonts\" used by `Rd-font'.
|
||||
Each entry is a list. The first element is the key to activate
|
||||
the font. The second element is the string to insert before
|
||||
point, and the third element is the string to insert after
|
||||
point.")
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode Rd-mode text-mode "Rd"
|
||||
"Major mode for editing R documentation source files.
|
||||
|
||||
Type \\[list-abbrevs] to display the built-in abbrevs for Rd
|
||||
keywords.To automatically turn on the abbrev(iate) features, add
|
||||
the following to your Emacs configuration file:
|
||||
|
||||
(add-hook 'Rd-mode-hook #'abbrev-mode)"
|
||||
(setq ess-language "S" ess-dialect "R")
|
||||
(require 'ess-r-mode)
|
||||
(ess-setq-vars-local ess-r-customize-alist)
|
||||
|
||||
(setq-local indent-line-function 'Rd-mode-indent-line)
|
||||
(setq fill-column 72)
|
||||
(setq-local comment-start-skip "\\s<+\\s-*")
|
||||
(setq-local comment-start "% ")
|
||||
(setq-local comment-end "")
|
||||
(setq font-lock-defaults
|
||||
'(Rd-font-lock-keywords nil nil))
|
||||
|
||||
;; Here is a workaround for an Emacs bug related to indirect buffers and
|
||||
;; spurious lockfiles that rears its ugly head with .Rd files
|
||||
;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2013-02/msg01368.html
|
||||
;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=14328
|
||||
(setq-local create-lockfiles nil)
|
||||
|
||||
(easy-menu-define Rd-mode-menu-map Rd-mode-map
|
||||
"Menu keymap for Rd mode." Rd-mode-menu)
|
||||
|
||||
(turn-on-auto-fill))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.Rd\\'" . Rd-mode))
|
||||
|
||||
(defun Rd-describe-major-mode ()
|
||||
"Describe the current major mode."
|
||||
(declare (obsolete describe-mode "ESS 19.04"))
|
||||
(describe-function major-mode))
|
||||
|
||||
(defun Rd-mode-in-verbatim-p ()
|
||||
"Return non-nil if in a usage, examples, or synopsis."
|
||||
(let ((pos (point)))
|
||||
(save-excursion
|
||||
(if (and (re-search-backward
|
||||
"\\\\\\(usage\\|examples\\|synopsis\\)" nil t)
|
||||
(re-search-forward "\\s(" nil t))
|
||||
(condition-case ()
|
||||
(progn
|
||||
(up-list 1)
|
||||
(< pos (point)))
|
||||
(error t))
|
||||
nil))))
|
||||
|
||||
(defun Rd-mode-in-preprocessor-line-p ()
|
||||
"Return non-nil if in a preprocessor line."
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(looking-at "[ \t]*#\\(ifdef\\|endif\\)")))
|
||||
|
||||
(defun Rd-mode-calculate-indent ()
|
||||
"Return appropriate indentation for current line in Rd mode."
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(cond
|
||||
((Rd-mode-in-verbatim-p)
|
||||
;; Don't do anything in verbatims
|
||||
nil)
|
||||
((Rd-mode-in-preprocessor-line-p)
|
||||
;; Indent to 0
|
||||
0)
|
||||
(t
|
||||
(let ((p (progn
|
||||
(re-search-forward "[ \t]*\\s)*" (point-at-eol) t)
|
||||
(point))))
|
||||
(if (or (< (forward-line -1) 0)
|
||||
(Rd-mode-in-verbatim-p))
|
||||
0
|
||||
(set-syntax-table Rd-mode-parse-syntax-table)
|
||||
(while (and (or (looking-at "[ \t]*$")
|
||||
(Rd-mode-in-preprocessor-line-p))
|
||||
(not (bobp)))
|
||||
(forward-line -1))
|
||||
(re-search-forward "[ \t]*\\s)*" (point-at-eol) t)
|
||||
(prog1
|
||||
(+ (current-indentation)
|
||||
(* (car (parse-partial-sexp (point) p))
|
||||
Rd-indent-level))
|
||||
(set-syntax-table Rd-mode-syntax-table))))))))
|
||||
|
||||
(defun Rd-mode-indent-line ()
|
||||
"Indent current line as Rd source."
|
||||
(when-let ((ic (Rd-mode-calculate-indent))
|
||||
(rp (- (current-column) (current-indentation))))
|
||||
(when (< ic 0)
|
||||
(error "Unmatched parenthesis"))
|
||||
(indent-line-to ic)
|
||||
(when (> rp 0)
|
||||
(move-to-column (+ ic rp)))))
|
||||
|
||||
(defun Rd-mode-insert-item ()
|
||||
"Insert \\item{ on a newline."
|
||||
(interactive)
|
||||
(reindent-then-newline-and-indent)
|
||||
(insert "\\item{")
|
||||
)
|
||||
|
||||
(defun Rd-mode-insert-section ()
|
||||
"Insert a section from `Rd-section-names'."
|
||||
(interactive)
|
||||
(let ((s (ess-completing-read
|
||||
"Insert section: "
|
||||
(mapcar (lambda (x) (cons x x)) Rd-section-names)
|
||||
nil t)))
|
||||
(if (string= s "")
|
||||
(progn (insert "\\section{}{") (backward-char 2))
|
||||
(insert (format "\\%s{" s)))))
|
||||
|
||||
(defun Rd-mode-insert-skeleton ()
|
||||
"Insert several empty Rd fields."
|
||||
(interactive)
|
||||
;; Hmm: in theory this should be kept in sync with prompt()
|
||||
;; --- maybe using prompt() [or promptClass()...] would be better anyway?!
|
||||
(insert "\\name{}\n")
|
||||
(insert "\\alias{}\n")
|
||||
(insert "\\title{}\n")
|
||||
(insert "\\description{\n}\n")
|
||||
(insert "\\usage{\n}\n")
|
||||
(insert "\\arguments{\n}\n")
|
||||
(insert "\\value{\n}\n")
|
||||
(insert "\\details{\n}\n")
|
||||
(insert "\\references{\n}\n")
|
||||
(insert "\\seealso{\n}\n")
|
||||
(insert "\\examples{\n}\n")
|
||||
(insert "\\author{}\n")
|
||||
(insert "\\keyword{}\n"))
|
||||
|
||||
;; This is an `easy' version of (defun TeX-font ..) in AUCtex's tex.el ;
|
||||
;; see TeX-font-list and also LaTeX-font-list in latex.el
|
||||
|
||||
(defun Rd-font (what)
|
||||
"Insert template for font command.
|
||||
WHAT determines the font to use, as specified by `Rd-font-list'."
|
||||
(interactive "c")
|
||||
;;TeX had : (Rd-update-style)
|
||||
(let* ((entry (assoc what Rd-font-list))
|
||||
(before (nth 1 entry))
|
||||
(after (nth 2 entry)))
|
||||
(cond ((null entry) ;; help on possibilities :
|
||||
(let ((help
|
||||
(concat
|
||||
"Rd Markup (available from C-c C-f):\n\n\t"
|
||||
"KEY Rd-Markup\n\n"
|
||||
(mapconcat
|
||||
(lambda (entry)
|
||||
;; A textual description of an ENTRY in TeX-font-list.
|
||||
(concat (format "%11s "
|
||||
(key-description
|
||||
(char-to-string (nth 0 entry))))
|
||||
(format "%14s %-3s"
|
||||
(nth 1 entry) (nth 2 entry))))
|
||||
Rd-font-list "\n"))))
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(set-buffer "*Help*")
|
||||
(insert help))))
|
||||
|
||||
((region-active-p)
|
||||
(save-excursion
|
||||
(cond ((> (mark) (point))
|
||||
(insert before)
|
||||
(goto-char (mark))
|
||||
(insert after))
|
||||
(t
|
||||
(insert after)
|
||||
(goto-char (mark))
|
||||
(insert before)))))
|
||||
(t
|
||||
(insert before)
|
||||
(save-excursion
|
||||
(insert after))))))
|
||||
|
||||
(defun Rd-preview-help (&optional via-shell)
|
||||
"Preview the current Rd buffer contents as help.
|
||||
If the current buffer is not associated with a file, create a
|
||||
temporary one in variable `temporary-file-directory'."
|
||||
(declare (advertised-calling-convention () "ESS 19.04"))
|
||||
(interactive "P") ; If optional VIA-SHELL is set, using `Rd-to-help-command'.
|
||||
(let ((file buffer-file-name)
|
||||
(pbuf (get-buffer-create "R Help Preview"))
|
||||
del-p)
|
||||
(unless file
|
||||
(setq file (make-temp-file "RD_" nil ".Rd"))
|
||||
(write-region (point-min) (point-max) file)
|
||||
(setq del-p t))
|
||||
|
||||
(if via-shell ;; FIXME eventually get rid of this option
|
||||
;; only method in ESS <= 14.09 -- calls "R" even if in "R-devel"; slower
|
||||
(let ((shcmd (format "%s '%s'" Rd-to-help-command file)))
|
||||
(set-buffer pbuf)
|
||||
(erase-buffer)
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "Rd-preview-help: (shell-command |%s| t)" shcmd))
|
||||
(shell-command shcmd t))
|
||||
;; else directly:
|
||||
(ess-force-buffer-current "R process to use: ")
|
||||
(ess-command (format ".ess_Rd2txt(\"%s\")\n" file) pbuf)
|
||||
(set-buffer pbuf))
|
||||
|
||||
;; FIXME(2): once got rid of via-shell, consider
|
||||
;; (ess--flush-help-into-current-buffer file "tools::Rd2txt(\"%s\")\n")
|
||||
;; instead of all this :
|
||||
(ess-setq-vars-local ess-r-customize-alist)
|
||||
;; mostly cut'n'paste from ess--flush-help* (see FIXME(2)):
|
||||
(ess-help-underline)
|
||||
(ess--help-major-mode)
|
||||
;; FIXME: Is this really needed?
|
||||
(setq ess-help-sec-regex ess-help-r-sec-regex
|
||||
ess-help-sec-keys-alist ess-help-r-sec-keys-alist)
|
||||
(goto-char (point-min))
|
||||
(set-buffer-modified-p 'nil)
|
||||
(setq buffer-read-only t)
|
||||
(setq truncate-lines nil)
|
||||
(when del-p (delete-file file))
|
||||
(unless (get-buffer-window pbuf 'visible)
|
||||
(display-buffer pbuf t))))
|
||||
|
||||
(define-obsolete-function-alias 'Rd-submit-bug-report 'ess-submit-bug-report "2018-08-16")
|
||||
|
||||
(provide 'ess-rd)
|
||||
|
||||
;;; ess-rd.el ends here
|
||||
316
lisp/ess/ess-rdired.el
Normal file
316
lisp/ess/ess-rdired.el
Normal file
@@ -0,0 +1,316 @@
|
||||
;;; ess-rdired.el --- prototype object browser for R, looks like dired mode. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
;; Author: Stephen Eglen <stephen@anc.ed.ac.uk>
|
||||
;; Created: Thu 24 Oct 2002
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This provides a dired-like buffer for R objects. Instead of
|
||||
;; operating on files, we operate on R objects in the current
|
||||
;; environment. Objects can be viewed, edited, deleted, plotted and
|
||||
;; so on.
|
||||
;; Do "M-x R" to start an R session, then create a few variables:
|
||||
;;
|
||||
;; s <- sin(seq(from=0, to=8*pi, length=100))
|
||||
;; x <- c(1, 4, 9)
|
||||
;; y <- rnorm(20)
|
||||
;; z <- TRUE
|
||||
|
||||
;; Then in Emacs, do "M-x ess-rdired" and you should see the following in
|
||||
;; the buffer *R dired*:
|
||||
;; Name Class Length Size
|
||||
;; s numeric 100 848 bytes
|
||||
;; x numeric 3 80 bytes
|
||||
;; y numeric 20 208 bytes
|
||||
;; z logical 1 56 bytes
|
||||
|
||||
;; Type "?" in the buffer to see the documentation. e.g. when the
|
||||
;; cursor is on the line for `s', type 'p' to plot it, or `v' to view
|
||||
;; its contents in a buffer. Then type 'd' to delete it.
|
||||
|
||||
;; How it works.
|
||||
|
||||
;; Most of the hard work is done by the R routine .rdired.objects(),
|
||||
;; which, when called, produces the list of objects in a tidy format.
|
||||
;; This function is stored within the Lisp variable `ess-rdired-objects'.
|
||||
|
||||
;; Todo - How to select alternative environments? Currently only
|
||||
;; shows objects in the .GlobalEnv? See BrowseEnv() in 1.6.x for way
|
||||
;; of browsing other environments.
|
||||
|
||||
;; Todo - problem with fix -- have to wait for fix() command to return
|
||||
;; before *R* buffer can be used again. This can get stuck, umm. not
|
||||
;; sure what is going wrong here. Maybe add a hook to the temp buffer
|
||||
;; so that when buffer is killed, we send an instruction to R to
|
||||
;; update the value of the variable to the contents of the buffer.
|
||||
;; This way *R* doesn't have to wait.
|
||||
|
||||
;; Todo - small bug in .rdired.objects -- if we have a variable called
|
||||
;; `my.x', its value is replaced by the value of my.x used in the
|
||||
;; sapply() calls within .rdired.objects().
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-inf)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'subr-x))
|
||||
|
||||
(defvar ess-rdired-objects "local({.rdired.objects <- function(objs) {
|
||||
if (length(objs)==0) {
|
||||
\"No objects to view!\"
|
||||
} else {
|
||||
mode <- sapply(objs, function(my.x) {
|
||||
eval( parse( text=sprintf('data.class(get(\"%s\"))', my.x))) })
|
||||
length <- sapply(objs, function(my.x) {
|
||||
eval( parse( text=sprintf('length(get(\"%s\"))', my.x))) })
|
||||
size <- sapply(objs, function(my.x) {
|
||||
eval( parse( text=sprintf('format(object.size(get(\"%s\")), units=\"b\")', my.x))) })
|
||||
d <- data.frame(mode, length, size)
|
||||
|
||||
var.names <- row.names(d)
|
||||
|
||||
## If any names contain spaces, we need to quote around them.
|
||||
quotes = rep('', length(var.names))
|
||||
spaces = grep(' ', var.names)
|
||||
if (any(spaces))
|
||||
quotes[spaces] <- '\"'
|
||||
var.names = paste(quotes, var.names, quotes, sep='')
|
||||
row.names(d) <- paste(' ', var.names, sep='')
|
||||
d
|
||||
}
|
||||
}; cat('\n'); print(.rdired.objects(ls(envir = .GlobalEnv)))})\n"
|
||||
"Function to call within R to print information on objects.
|
||||
The last line of this string should be the instruction to call
|
||||
the function which prints the output for rdired.")
|
||||
|
||||
(defvar ess-rdired-buffer "*R dired*"
|
||||
"Name of buffer for displaying R objects.")
|
||||
|
||||
(defvar ess-rdired-auto-update-timer nil
|
||||
"The timer object for auto updates.")
|
||||
|
||||
(defcustom ess-rdired-auto-update-interval 5
|
||||
"Seconds between refreshes of the `ess-rdired' buffer."
|
||||
:type '(choice (const nil :tag "No auto updates") (integer :tag "Seconds"))
|
||||
:group 'ess-R
|
||||
:package-version '(ess . "19.04"))
|
||||
|
||||
(defvar ess-rdired-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "d" #'ess-rdired-delete)
|
||||
(define-key map "x" #'ess-rdired-delete)
|
||||
(define-key map "v" #'ess-rdired-view)
|
||||
(define-key map "V" #'ess-rdired-View)
|
||||
(define-key map "p" #'ess-rdired-plot)
|
||||
(define-key map "y" #'ess-rdired-type)
|
||||
(define-key map "\C-c\C-s" #'ess-rdired-switch-process)
|
||||
(define-key map "\C-c\C-y" #'ess-switch-to-ESS)
|
||||
(define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
|
||||
map))
|
||||
|
||||
(define-derived-mode ess-rdired-mode tabulated-list-mode "Rdired"
|
||||
"Major mode for output from `ess-rdired'.
|
||||
`ess-rdired' provides a dired-like mode for R objects. It shows the
|
||||
list of current objects in the current environment, one-per-line. You
|
||||
can then examine these objects, plot them, and so on."
|
||||
:group 'ess-R
|
||||
(setq mode-name (concat "RDired " ess-local-process-name))
|
||||
(setq tabulated-list-format
|
||||
`[("Name" 18 t)
|
||||
("Class" 10 t)
|
||||
("Length" 10 ess-rdired--length-predicate)
|
||||
("Size" 10 ess-rdired--size-predicate)])
|
||||
(add-hook 'tabulated-list-revert-hook #'ess-rdired-refresh nil t)
|
||||
(when (and (not ess-rdired-auto-update-timer)
|
||||
ess-rdired-auto-update-interval)
|
||||
(setq ess-rdired-auto-update-timer
|
||||
(run-at-time t ess-rdired-auto-update-interval #'ess-rdired-refresh)))
|
||||
(add-hook 'kill-buffer-hook #'ess-rdired-cancel-auto-update-timer nil t)
|
||||
(tabulated-list-init-header))
|
||||
|
||||
;;;###autoload
|
||||
(defun ess-rdired ()
|
||||
"Show R objects from the global environment in a separate buffer.
|
||||
You may interact with these objects, see `ess-rdired-mode' for
|
||||
details."
|
||||
(interactive)
|
||||
(unless (and (string= "R" ess-dialect)
|
||||
ess-local-process-name)
|
||||
(error "Not in an R buffer with attached process"))
|
||||
(let ((proc ess-local-process-name))
|
||||
(pop-to-buffer (get-buffer-create ess-rdired-buffer))
|
||||
(setq ess-local-process-name proc)
|
||||
(ess-rdired-mode)
|
||||
(ess-rdired-refresh)))
|
||||
|
||||
(defun ess-rdired-refresh ()
|
||||
"Refresh the `ess-rdired' buffer."
|
||||
(let* ((buff (get-buffer-create ess-rdired-buffer))
|
||||
(proc-name (buffer-local-value 'ess-local-process-name buff))
|
||||
(proc (get-process proc-name))
|
||||
(out-buff (get-buffer-create " *ess-rdired-output*"))
|
||||
text)
|
||||
(when (and proc-name proc
|
||||
(not (process-get proc 'busy)))
|
||||
(ess-command ess-rdired-objects out-buff nil nil nil proc)
|
||||
(with-current-buffer out-buff
|
||||
(goto-char (point-min))
|
||||
;; Delete two lines. One filled with +'s from R's prompt
|
||||
;; printing, the other with the header info from the data.frame
|
||||
(delete-region (point-min) (1+ (point-at-eol 2)))
|
||||
(setq text (split-string (buffer-string) "\n" t "\n"))
|
||||
(erase-buffer))
|
||||
(with-current-buffer buff
|
||||
(setq tabulated-list-entries
|
||||
(mapcar #'ess-rdired--tabulated-list-entries text))
|
||||
(let ((entry (tabulated-list-get-id))
|
||||
(col (current-column)))
|
||||
(tabulated-list-print)
|
||||
(while (not (equal entry (tabulated-list-get-id)))
|
||||
(forward-line))
|
||||
(move-to-column col))))))
|
||||
|
||||
(defun ess-rdired-cancel-auto-update-timer ()
|
||||
"Cancel the timer `ess-rdired-auto-update-timer'."
|
||||
(setq ess-rdired-auto-update-timer
|
||||
(cancel-timer ess-rdired-auto-update-timer)))
|
||||
|
||||
(defun ess-rdired--tabulated-list-entries (text)
|
||||
"Return a value suitable for `tabulated-list-entries' from TEXT."
|
||||
(let (name class length size)
|
||||
(if (not (string-match-p " +\"" text))
|
||||
;; Normal-world
|
||||
(setq text (split-string text " " t)
|
||||
name (nth 0 text)
|
||||
text (cdr text))
|
||||
;; Else, someone has spaces in their variable names
|
||||
(string-match "\"\\([^\"]+\\)" text)
|
||||
(setq name (substring (match-string 0 text) 1)
|
||||
text (split-string (substring text (1+ (match-end 0))) " " t)))
|
||||
(setq class (nth 0 text)
|
||||
length (nth 1 text)
|
||||
size (nth 2 text))
|
||||
(list name
|
||||
`[(,name
|
||||
help-echo "mouse-2, RET: View this object"
|
||||
action ess-rdired-view)
|
||||
,class
|
||||
,length
|
||||
,size])))
|
||||
|
||||
(defun ess-rdired-edit ()
|
||||
"Edit the object at point."
|
||||
(interactive)
|
||||
(ess-command (concat "edit(" (tabulated-list-get-id) ")\n")))
|
||||
|
||||
(defun ess-rdired-view (&optional _button)
|
||||
"View the object at point."
|
||||
(interactive)
|
||||
(ess-execute (ess-rdired-get (tabulated-list-get-id))
|
||||
nil "R view" ))
|
||||
|
||||
(defun ess-rdired-get (name)
|
||||
"Generate R code to get the value of the variable NAME.
|
||||
This is complicated because some variables might have spaces in their names.
|
||||
Otherwise, we could just pass the variable name directly to *R*."
|
||||
(concat "get(" (ess-rdired-quote name) ")")
|
||||
)
|
||||
|
||||
(defun ess-rdired-quote (name)
|
||||
"Quote NAME if not already quoted."
|
||||
(if (equal (substring name 0 1) "\"")
|
||||
name
|
||||
(concat "\"" name "\"")))
|
||||
|
||||
(defun ess-rdired-View ()
|
||||
"View the object at point in its own buffer.
|
||||
Like `ess-rdired-view', but the object gets its own buffer name."
|
||||
(interactive)
|
||||
(let ((objname (tabulated-list-get-id)))
|
||||
(ess-execute (ess-rdired-get objname)
|
||||
nil (concat "R view " objname ))))
|
||||
|
||||
(defun ess-rdired-plot ()
|
||||
"Plot the object on current line."
|
||||
(interactive)
|
||||
(let ((objname (tabulated-list-get-id)))
|
||||
(ess-eval-linewise (format "plot(%s)" (ess-rdired-get objname)))))
|
||||
|
||||
(defun ess-rdired-type ()
|
||||
"Run the mode() on command at point."
|
||||
(interactive)
|
||||
(let ((objname (tabulated-list-get-id))
|
||||
;; create a temp buffer, and then show output in echo area
|
||||
(tmpbuf (get-buffer-create "**ess-rdired-mode**")))
|
||||
(if objname
|
||||
(progn
|
||||
(ess-command (concat "mode(" (ess-rdired-get objname) ")\n")
|
||||
tmpbuf )
|
||||
(set-buffer tmpbuf)
|
||||
(message "%s" (concat
|
||||
objname ": "
|
||||
(buffer-substring (+ 4 (point-min)) (1- (point-max)))))
|
||||
(kill-buffer tmpbuf)))))
|
||||
|
||||
(defalias 'ess-rdired-expunge #'ess-rdired-delete)
|
||||
|
||||
(defun ess-rdired-delete ()
|
||||
"Delete the object at point."
|
||||
(interactive)
|
||||
(let ((objname (tabulated-list-get-id)))
|
||||
(when (yes-or-no-p (format "Really delete %s? " objname))
|
||||
(ess-eval-linewise (format "rm(%s)" (ess-rdired-quote objname)) nil nil nil t)
|
||||
(revert-buffer))))
|
||||
|
||||
(defun ess-rdired-switch-process ()
|
||||
"Switch to examine different *R* process.
|
||||
If you have multiple R processes running, e.g. *R*, *R:2*, *R:3*, you can
|
||||
use this command to choose which R process you would like to examine.
|
||||
After switching to a new process, the buffer is updated."
|
||||
(interactive)
|
||||
(ess-switch-process)
|
||||
(ess-rdired))
|
||||
|
||||
(defun ess-rdired--length-predicate (A B)
|
||||
"Enable sorting by length in `ess-rdired' buffers.
|
||||
Return t if A's length is < than B's length."
|
||||
(let ((lenA (aref (cadr A) 2))
|
||||
(lenB (aref (cadr B) 2)))
|
||||
(< (string-to-number lenA) (string-to-number lenB))))
|
||||
|
||||
(defun ess-rdired--size-predicate (A B)
|
||||
"Enable sorting by size in `ess-rdired' buffers.
|
||||
Return t if A's size is < than B's size."
|
||||
(let ((lenA (aref (cadr A) 3))
|
||||
(lenB (aref (cadr B) 3)))
|
||||
(< (string-to-number lenA) (string-to-number lenB))))
|
||||
|
||||
(define-obsolete-function-alias 'ess-rdired-quit #'quit-window "ESS 19.04")
|
||||
(define-obsolete-function-alias 'ess-rdired-next-line #'forward-to-indentation "ESS 19.04")
|
||||
(define-obsolete-function-alias 'ess-rdired-previous-line #'backward-to-indentation "ESS 19.04")
|
||||
(define-obsolete-function-alias 'ess-rdired-move-to-object #'back-to-indentation "ESS 19.04")
|
||||
|
||||
(provide 'ess-rdired)
|
||||
|
||||
;;; ess-rdired.el ends here
|
||||
1029
lisp/ess/ess-roxy.el
Normal file
1029
lisp/ess/ess-roxy.el
Normal file
File diff suppressed because it is too large
Load Diff
531
lisp/ess/ess-s-lang.el
Normal file
531
lisp/ess/ess-s-lang.el
Normal file
@@ -0,0 +1,531 @@
|
||||
;;; ess-s-lang.el --- Support for editing S source code -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1989-2020 Free Software Foundation, Inc.
|
||||
;; Author: A.J. Rossini <rossini@biostat.washington.edu>
|
||||
;; Created: 26 Aug 1997
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Code for general editing S source code (specializes to S, S+, R).
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-mode)
|
||||
(require 'ess-help)
|
||||
(require 'ess-inf)
|
||||
|
||||
(declare-function speedbar-add-supported-extension "speedbar" (extension))
|
||||
|
||||
; Configuration variables
|
||||
|
||||
(defvar S-syntax-table
|
||||
(let ((S-syntax-table (make-syntax-table)))
|
||||
(modify-syntax-entry ?\\ "\\" S-syntax-table)
|
||||
(modify-syntax-entry ?+ "." S-syntax-table)
|
||||
(modify-syntax-entry ?- "." S-syntax-table)
|
||||
(modify-syntax-entry ?= "." S-syntax-table)
|
||||
(modify-syntax-entry ?% "." S-syntax-table)
|
||||
(modify-syntax-entry ?< "." S-syntax-table)
|
||||
(modify-syntax-entry ?> "." S-syntax-table)
|
||||
(modify-syntax-entry ?& "." S-syntax-table)
|
||||
(modify-syntax-entry ?| "." S-syntax-table)
|
||||
(modify-syntax-entry ?\' "\"" S-syntax-table)
|
||||
(modify-syntax-entry ?\" "\"" S-syntax-table)
|
||||
(modify-syntax-entry ?# "<" S-syntax-table) ; open comment
|
||||
(modify-syntax-entry ?\n ">" S-syntax-table) ; close comment
|
||||
;;(modify-syntax-entry ?. "w" S-syntax-table) ; "." used in S obj names
|
||||
(modify-syntax-entry ?. "_" S-syntax-table) ; see above/below,
|
||||
; plus consider separation.
|
||||
(modify-syntax-entry ?$ "_" S-syntax-table); foo$comp = 1 symbol(completion)
|
||||
(modify-syntax-entry ?@ "_" S-syntax-table); foo@slot = 1 symbol(completion)
|
||||
(modify-syntax-entry ?_ "_" S-syntax-table)
|
||||
(modify-syntax-entry ?: "_" S-syntax-table)
|
||||
(modify-syntax-entry ?* "." S-syntax-table)
|
||||
(modify-syntax-entry ?< "." S-syntax-table)
|
||||
(modify-syntax-entry ?> "." S-syntax-table)
|
||||
(modify-syntax-entry ?/ "." S-syntax-table)
|
||||
S-syntax-table)
|
||||
"Syntax table for S code."
|
||||
)
|
||||
|
||||
(defvar S-editing-alist
|
||||
'((paragraph-start . (concat "\\s-*$\\|" page-delimiter))
|
||||
(paragraph-separate . (concat "\\s-*$\\|" page-delimiter))
|
||||
(paragraph-ignore-fill-prefix . t)
|
||||
;;(comment-indent-function . 'S-comment-indent)
|
||||
;;(ess-comment-indent . 'S-comment-indent)
|
||||
;;(ess-calculate-indent . 'ess-calculate-indent)
|
||||
;;(ess-keep-dump-files . 'ask)
|
||||
;; For Changelog add, require ' ' before <- : "attr<-" is a function name :
|
||||
(add-log-current-defun-header-regexp . "^\\(.+\\)\\s-+<-[ \t\n]*function"))
|
||||
"General options for S and S+ source files.")
|
||||
|
||||
(defvar inferior-S-language-start
|
||||
'(concat "options("
|
||||
"STERM='" ess-STERM "'"
|
||||
", str.dendrogram.last=\"'\""
|
||||
(if ess-editor (concat ", editor='" ess-editor "'"))
|
||||
(if ess-pager (concat ", pager='" ess-pager "', help.pager='" ess-pager "'"))
|
||||
", show.error.locations=TRUE"
|
||||
")")
|
||||
"S language expression for startup -- default for all S dialects.")
|
||||
|
||||
(defconst S-common-cust-alist
|
||||
'((ess-language . "S")
|
||||
(inferior-ess-exit-command . "q()\n")
|
||||
(inferior-ess-language-start . (eval inferior-S-language-start))
|
||||
(comint-use-prompt-regexp . t) ;;use fields if nil
|
||||
(comint-process-echoes . t)
|
||||
;; these prompt are the same for all S-languages As long as custom prompt
|
||||
;; ends in inferior-ess-primary-prompt everything should work as expected.
|
||||
(inferior-ess-primary-prompt . "> ")
|
||||
;; (inferior-ess-secondary-prompt . "[+:] ") ;; catch Selection: and alike
|
||||
(inferior-ess-secondary-prompt . "+ ") ;; catch Selection: and alike
|
||||
(comment-start . "#")
|
||||
(comment-add . 1)
|
||||
(comment-start-skip . "#+ *")
|
||||
(comment-use-syntax . t) ; see log for bug report 2013-06-07
|
||||
(comment-column . 40)
|
||||
(ess-no-skip-regexp . (concat "^ *@\\|" (default-value 'ess-no-skip-regexp)))
|
||||
;; inferior-ess-prompt is used by comint for navigation, only if
|
||||
;; comint-use-prompt-regexp is t; (transcript-mode also relies on this regexp)
|
||||
(inferior-ess-prompt . inferior-S-prompt)
|
||||
(ess-getwd-command . "getwd()\n")
|
||||
(ess-setwd-command . "setwd('%s')\n")
|
||||
(ess-funargs-command . ".ess_funargs(\"%s\")\n")
|
||||
(fill-nobreak-predicate . 'ess-inside-string-p)
|
||||
(ess-execute-screen-options-command . "options(width=%d, length=99999)\n")
|
||||
(font-lock-defaults . '(ess-build-font-lock-keywords
|
||||
nil nil ((?\. . "w") (?\_ . "w")))))
|
||||
"S-language common settings for all <dialect>-customize-alist.")
|
||||
|
||||
(defconst S+common-cust-alist
|
||||
(append
|
||||
'((ess-suffix . "S")
|
||||
(ess-help-sec-regex . ess-help-S+-sec-regex)
|
||||
(ess-help-sec-keys-alist . ess-help-S+sec-keys-alist)
|
||||
(ess-change-sp-regexp . ess-S+-change-sp-regexp)
|
||||
(ess-function-pattern . ess-s-function-pattern)
|
||||
(ess-function-template . " <- \n#\nfunction()\n{\n\n}\n")
|
||||
(ess-dump-filename-template . (replace-regexp-in-string
|
||||
"S$" ess-suffix ; in the one from custom:
|
||||
ess-dump-filename-template-proto))
|
||||
(ess-traceback-command . "traceback()\n")
|
||||
(ess-mode-editing-alist . S-editing-alist)
|
||||
|
||||
(ess-dumped-missing-re
|
||||
. "\\(\\(<-\\|=\\)\nDumped\n\\'\\)\\|\\(\\(<-\\|=\\)\\(\\s \\|\n\\)*\\'\\)")
|
||||
(ess-syntax-error-re
|
||||
. "\\(Syntax error: .*\\) at line \\([0-9]*\\), file \\(.*\\)$")
|
||||
(inferior-ess-objects-command . inferior-Splus-objects-command)
|
||||
(ess-describe-object-at-point-commands . 'ess-S-describe-object-at-point-commands)
|
||||
(ess-editor . S-editor)
|
||||
(ess-pager . S-pager))
|
||||
S-common-cust-alist)
|
||||
"Common settings for all S+<*>-customize-alist."
|
||||
)
|
||||
|
||||
;;; Changes from S to S-PLUS 3.x. (standard S3 should be in ess-s-lang!).
|
||||
|
||||
(defconst ess-help-S+sec-keys-alist
|
||||
'((?a . "ARGUMENTS:")
|
||||
(?b . "BACKGROUND:")
|
||||
(?B . "BUGS:")
|
||||
(?d . "DESCRIPTION:")
|
||||
(?D . "DETAILS:")
|
||||
(?e . "EXAMPLES:")
|
||||
(?n . "NOTE:")
|
||||
(?O . "OPTIONAL ARGUMENTS:")
|
||||
(?R . "REQUIRED ARGUMENTS:")
|
||||
(?r . "REFERENCES:")
|
||||
(?s . "SEE ALSO:")
|
||||
(?S . "SIDE EFFECTS:")
|
||||
(?u . "USAGE:")
|
||||
(?v . "VALUE:"))
|
||||
"Alist of (key . string) pairs for use in section searching.")
|
||||
;;; `key' indicates the keystroke to use to search for the section heading
|
||||
;;; `string' in an S help file. `string' is used as part of a
|
||||
;;; regexp-search, and so specials should be quoted.
|
||||
|
||||
;; S ver.3 (NOT S-Plus)
|
||||
(defconst ess-help-S3-sec-keys-alist
|
||||
'((?a . "ARGUMENTS:")
|
||||
(?b . "BACKGROUND:")
|
||||
(?B . "BUGS:")
|
||||
(?d . "DESCRIPTION:")
|
||||
(?D . "DETAILS:")
|
||||
(?e . "EXAMPLES:")
|
||||
(?n . "NOTE:")
|
||||
(?r . "REFERENCES:")
|
||||
(?s . "SEE ALSO:")
|
||||
(?S . "SIDE EFFECTS:")
|
||||
(?u . "USAGE:")
|
||||
(?v . "VALUE:"))
|
||||
"Help section keys for S ver.3.")
|
||||
|
||||
;; S ver.4 (NOT S-Plus)
|
||||
(defconst ess-help-S4-sec-keys-alist
|
||||
'((?a . "ARGUMENTS:")
|
||||
(?b . "BACKGROUND:")
|
||||
(?B . "BUGS:")
|
||||
(?d . "DESCRIPTION:")
|
||||
(?D . "DETAILS:")
|
||||
(?e . "EXAMPLES:")
|
||||
(?n . "NOTE:")
|
||||
(?r . "REFERENCES:")
|
||||
(?s . "SEE ALSO:")
|
||||
(?S . "SIDE EFFECTS:")
|
||||
(?u . "USAGE:")
|
||||
(?v . "VALUE:"))
|
||||
"Help section keys for S4.")
|
||||
|
||||
|
||||
(defconst ess-help-S+-sec-regex "^[A-Z.]+:$"
|
||||
"Reg(ular) Ex(pression) of section headers in help file.")
|
||||
|
||||
; Function Definitions
|
||||
|
||||
(defun S-comment-indent ()
|
||||
"Indentation for S comments."
|
||||
(if (or (looking-at "###")
|
||||
(and (looking-at "#!") (= 1 (line-number-at-pos))))
|
||||
(current-column)
|
||||
(if (looking-at "##")
|
||||
(let ((tem (when ;; FIXME ess-calculate-indent is R specific
|
||||
(fboundp 'ess-calculate-indent)
|
||||
(ess-calculate-indent))))
|
||||
(if (listp tem) (car tem) tem))
|
||||
(skip-chars-backward " \t")
|
||||
(max (if (bolp) 0 (1+ (current-column)))
|
||||
comment-column))))
|
||||
|
||||
;;*;; S/R Pretty-Editing
|
||||
|
||||
(defun ess-fix-comments (&optional dont-query verbose)
|
||||
"Fix buffer so that single-line comments start with at least '##',
|
||||
and ensure space before subsequent text."
|
||||
(interactive "P")
|
||||
(ess-replace-regexp-dump-to-src "#\\([A-Za-z0-9]\\)" "# \\1" nil verbose)
|
||||
(ess-replace-regexp-dump-to-src "^\\([ \t]*#\\)\\([^#]\\)"
|
||||
"\\1#\\2" dont-query verbose))
|
||||
|
||||
(defun ess-dump-to-src (&optional dont-query verbose)
|
||||
"Make the change in an S - dump() file to improve human readability.
|
||||
Optional arguments DONT-QUERY and VERBOSE are passed to
|
||||
`ess-replace-regexp-dump-to-src'."
|
||||
(interactive "P")
|
||||
(ess-replace-regexp-dump-to-src "^\"\\([a-z.][a-z.0-9]*\\)\" *<-\n"
|
||||
"\n\\1 <- "
|
||||
dont-query verbose))
|
||||
|
||||
(defun ess-num-var-round (&optional dont-query verbose)
|
||||
"Round endings like 000000 and 99999.
|
||||
Optional argument DONT-QUERY means do not query.
|
||||
Optional argument VERBOSE gives more verbose output."
|
||||
(interactive "P")
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let ((num 0)
|
||||
(str "")
|
||||
(rgxp "000000+[1-9]?[1-9]?\\>")
|
||||
(to ""))
|
||||
(if dont-query
|
||||
(ess-rep-regexp rgxp to nil nil verbose)
|
||||
(query-replace-regexp rgxp to nil))
|
||||
(while (< num 9)
|
||||
(setq str (concat (int-to-string num) "999999+[0-8]*"))
|
||||
(if (and (numberp verbose) (> verbose 1))
|
||||
(message (format "\nregexp: '%s'" str)))
|
||||
(goto-char (point-min))
|
||||
(ess-rep-regexp str (int-to-string (1+ num))
|
||||
'fixedcase 'literal verbose)
|
||||
(setq num (1+ num))))))
|
||||
|
||||
(defun ess-fix-dot (before-chars &optional dont-query verbose)
|
||||
"Remove trailing decimal '.' (\"dot\"), before BEFORE-CHARS.
|
||||
Optional argument DONT-QUERY and VERBOSE get passed to `ess-replace-regexp-dump-to-src'."
|
||||
;; typically, before-chars = "]:" or more
|
||||
(ess-replace-regexp-dump-to-src
|
||||
(concat "\\([0-9]\\)\\.\\( *[" before-chars "]\\)")
|
||||
;; 111 ^
|
||||
"\\1\\2" dont-query verbose))
|
||||
|
||||
(defun ess-fix-dot-1 (&optional do-query verbose)
|
||||
"Remove trailing decimal '.' (\"dot\"), before ':' or ']', i.e.,
|
||||
in cases where it's ugly and nonsense. DO-QUERY(prefix) asks before replacing."
|
||||
(interactive "P")
|
||||
(ess-fix-dot "]:" (not do-query) verbose))
|
||||
|
||||
(defun ess-fix-dot-more (&optional dont-query verbose)
|
||||
"Remove trailing decimal '.' (\"dot\", typically from S+) in more cases
|
||||
than `ess-fix-dot-1'."
|
||||
(interactive "P")
|
||||
(ess-fix-dot-1 nil verbose)
|
||||
(ess-fix-dot ",)" dont-query verbose))
|
||||
|
||||
(defun ess-fix-EQ-assign (&optional dont-query verbose not-all)
|
||||
"Replace \"=\" by \"<-\" in places where it 'might make sense', e.g.,
|
||||
for function assignments and lines not ending in \",\".
|
||||
Be *careful* for list()s of functions and when argument not-all is
|
||||
nil (as by default) !"
|
||||
;;TODO: "in the few places we can be very sure.."
|
||||
;;---- is hard in general: local functions: ok; but functions in
|
||||
;; list(a = function(x) abs(x), b= function(y) bound(y)) *NOT* ok!
|
||||
(interactive "P")
|
||||
(ess-replace-regexp-dump-to-src
|
||||
"^\\( *[a-z.][_a-z.0-9]*\\) *= *\\(function *(\\)"
|
||||
"\\1 <- \\2" dont-query verbose)
|
||||
(unless not-all
|
||||
;; "too" aggressive {proposing to replace function argument specs}:
|
||||
(ess-replace-regexp-dump-to-src ;; all those *not* ending in ","
|
||||
;; including Mat[ i, ] = ...,
|
||||
;; but not `names(x) = "..."' for that is "confused" with plot(x=x,..)
|
||||
"^\\( *[a-z.][][, \"_a-z.0-9]*\\) *= *\\([a-z.0-9({]\\(.*[^,]\\)? *$\\)"
|
||||
"\\1 <- \\2" nil ;; always query - often has many "false positives"
|
||||
verbose)))
|
||||
|
||||
;;; All of the above three :
|
||||
(defun ess-MM-fix-src (&optional dont-query verbose)
|
||||
"Clean up ess-source code which has been produced by dump(..), and other
|
||||
code typically produced by other tools. Produces more readable code,
|
||||
and one that is well formatted in Emacs ess-mode."
|
||||
(interactive "P")
|
||||
;; each of the following does a save-excursion:
|
||||
(ess-dump-to-src dont-query)
|
||||
(ess-fix-comments dont-query)
|
||||
(ess-num-var-round dont-query verbose)
|
||||
(ess-fix-dot-more dont-query verbose)
|
||||
(ess-fix-EQ-assign dont-query verbose 'not-all))
|
||||
|
||||
(defun ess-fix-miscellaneous (&optional from verbose)
|
||||
"Fix Miscellaneous S/R `ill-formation's from current \\[point].
|
||||
Particularly use \"<-\"and put spaces around operators."
|
||||
(interactive "d\nP"); Defaults: point and prefix (C-u)
|
||||
;; activate by (setq ess-verbose t)
|
||||
(ess-if-verbose-write
|
||||
(format "ess-fix-misc begin (from = %s, verbose = %s)\n" from verbose))
|
||||
(save-excursion
|
||||
|
||||
(when (and (string= ess-dialect "R")
|
||||
(fboundp 'ess-r-fix-T-F))
|
||||
(ess-r-fix-T-F from (not verbose)))
|
||||
|
||||
;; activate by (setq ess-verbose t)
|
||||
(ess-if-verbose-write "ess-fix-misc: after fix-T-F\n");___D___
|
||||
|
||||
;; former C and matlab programmers leave trailing ";" :
|
||||
;; (goto-char from) (ess-rep-regexp "; *$" "" nil 'literal verbose)
|
||||
;; (ess-if-verbose-write "ess-fix-misc: after trailing ';'\n");___D___
|
||||
(goto-char from) (ess-rep-regexp ";\\( *\\)#" "\\1#" nil nil verbose)
|
||||
(ess-if-verbose-write "ess-fix-misc: after ';' before #\n");___D___
|
||||
|
||||
;;from R 1.9.x "_" is valid in names; here assume no initial / trailing '_'
|
||||
;; BUG: The following changes "beta_ " or " _abc"
|
||||
;; (goto-char from) (ess-rep-regexp " +_ *" " <- " nil 'literal verbose)
|
||||
;; (goto-char from) (ess-rep-regexp "_ +" " <- " nil 'literal verbose)
|
||||
|
||||
(ess-if-verbose-write "ess-fix-misc: before 'around \"<-\"' :\n");___D___
|
||||
;; ensure space around "<-" ---- but only replace if necessary:
|
||||
(goto-char from)
|
||||
(ess-rep-regexp "\\([^< \t\n]\\)\\(<<?-\\)" "\\1 \\2" nil nil verbose)
|
||||
(goto-char from)(ess-rep-regexp "<-\\([^ \t\n]\\)" "<- \\1" nil nil verbose)
|
||||
;; ensure space around "<" (not in "<-","<=","<<-") and ">" (not ">=") :
|
||||
(goto-char from);; --> " <", care with "->":
|
||||
(ess-rep-regexp "\\([^-< \t\n]\\)\\([<>]\\)" "\\1 \\2" nil nil verbose)
|
||||
;; ">" -> "> " , for "<", don't split "<-" nor "<<-":
|
||||
(goto-char from)
|
||||
(ess-rep-regexp "\\(>=?\\)\\([^= \t\n]\\)" "\\1 \\2" nil nil verbose)
|
||||
(goto-char from)
|
||||
(ess-rep-regexp "\\(<=?\\)\\([^-<= \t\n]\\)" "\\1 \\2" nil nil t)
|
||||
|
||||
(ess-if-verbose-write "ess-fix-misc: before \"=\" \"==\" .. :\n");___D___
|
||||
;; -- ensure space around "=", "==", "!=" :
|
||||
(goto-char from) ;; --> " ="
|
||||
(ess-rep-regexp "\\([^=!<> ]\\)\\([=!]?\\)=" "\\1 \\2=" nil nil verbose)
|
||||
(goto-char from) (ess-rep-regexp "=\\([^= ]\\)" "= \\1" nil nil verbose)
|
||||
|
||||
(goto-char from) ;; add a space between "{" and surrounding ..char:
|
||||
(ess-rep-regexp "{\\([.A-Za-z()]\\)" "{ \\1" 'fix nil verbose)
|
||||
(ess-rep-regexp "\\([()]\\){" "\\1 {" 'fix nil verbose)
|
||||
(goto-char from) ;; add a space between "}" and a preceding wordchar:
|
||||
(ess-rep-regexp "\\([A-Za-z0-9()]\\)}" "\\1 }" 'fix nil verbose)
|
||||
(ess-space-around "else" from verbose)
|
||||
|
||||
(ess-if-verbose-write "ess-fix-misc: after \"{ ... }\" :\n");___D___
|
||||
(goto-char from) ;; add a space inside "){"
|
||||
(ess-rep-regexp "){" ") {" 'fix nil verbose)
|
||||
|
||||
;; add a newline and indent before a "}"
|
||||
;; --- IFF there's NO "{" or "#" AND some NON-white text on the same line:
|
||||
;;D (if verbose (message "\t R-fix-misc..: Hard.. '}'"))
|
||||
(goto-char from)
|
||||
(ess-rep-regexp "^\\([^#{\n]*[^#{ \t\n]+[ \t]*\\)}[ \t]*$"
|
||||
"\\1\n}" 'fix nil verbose)
|
||||
(ess-if-verbose-write "ess-fix-misc __end__\n");___D___
|
||||
))
|
||||
|
||||
(defun ess-cycle-assign ()
|
||||
"Cycle between assignment symbols in `ess-assign-list'.
|
||||
On consecutive calls, replace the assignment symbol before point
|
||||
with the next symbol from that list. This function sets the last
|
||||
keypress to repeat it, so if it is bound to \"C-c C-=\" pressing
|
||||
\"=\" again cycles to the next assignment."
|
||||
(interactive)
|
||||
(if (eq last-command this-command)
|
||||
(let ((slist ess-assign-list)
|
||||
str)
|
||||
;; The or statements in the setq allow cycling past the end of
|
||||
;; ess-assign-list.
|
||||
(while (and (setq str (or (car slist) (car ess-assign-list))
|
||||
slist (or (cdr slist) ess-assign-list))
|
||||
(not (and (re-search-backward str
|
||||
(- (point) (length str)) t)
|
||||
(not (replace-match (car slist))))))))
|
||||
(insert (car ess-assign-list)))
|
||||
(set-transient-map
|
||||
(let ((map (make-sparse-keymap))
|
||||
(key (format "%c" (event-basic-type last-input-event))))
|
||||
(define-key map (kbd key) #'ess-cycle-assign)
|
||||
map)))
|
||||
|
||||
(defun ess-insert-assign (arg)
|
||||
"Insert the first element of `ess-assign-list' unless in string or comment.
|
||||
If the character before point is the first element of
|
||||
`ess-assign-list', replace it with the last character typed.
|
||||
|
||||
If `ess-language' is not \"S\", call `self-insert-command' with ARG."
|
||||
(interactive "p")
|
||||
(if (string= ess-language "S")
|
||||
(let* ((assign (car ess-assign-list))
|
||||
(event (event-basic-type last-input-event))
|
||||
(char (ignore-errors (format "%c" event))))
|
||||
(cond ((and char (ess-inside-string-or-comment-p))
|
||||
(insert char))
|
||||
((re-search-backward assign (- (point) (length assign)) t)
|
||||
(if (and char (numberp event))
|
||||
(replace-match char t t)
|
||||
(replace-match "")))
|
||||
(t (insert assign))))
|
||||
(funcall #'self-insert-command arg)))
|
||||
|
||||
;; In case people had this in their config don't cause errors:
|
||||
(define-obsolete-function-alias 'ess-smart-S-assign 'ess-insert-assign "ESS 18.10")
|
||||
(define-obsolete-function-alias 'ess-disable-smart-S-assign #'ignore "ESS 18.10")
|
||||
|
||||
(defun ess-add-MM-keys ()
|
||||
"Define MM's user keys."
|
||||
(declare (obsolete "Setup your own keybindings." "ESS 19.04"))
|
||||
(define-key inferior-ess-mode-map "\C-cw" #'ess-execute-screen-options)
|
||||
(define-key ess-mode-map [?\M--] #'ess-insert-assign)
|
||||
(define-key inferior-ess-mode-map [?\M--] #'ess-insert-assign))
|
||||
|
||||
(defun ess-dump-args-and-go (Sfunc)
|
||||
"Dump the function name, with arguments, to a buffer for editing.
|
||||
|
||||
Currently, this needs to:
|
||||
1. set the buffer to the right mode, with the right settings
|
||||
2. format the statement,
|
||||
3. c/function/Sfunc/
|
||||
and I need to relearn Emacs lisp (but I had to, anyway."
|
||||
(interactive "sFunction ? ")
|
||||
(declare (obsolete 'ess-execute "ESS 19.04"))
|
||||
(let* ((buffname "ess-complete.R"))
|
||||
(ess-execute (format "args(%s)" Sfunc) t buffname)
|
||||
(pop-to-buffer (concat "*" buffname "*"))
|
||||
(while (search-forward "function" nil t)
|
||||
(replace-match Sfunc nil t))
|
||||
(when (fboundp 'ess-r-mode)
|
||||
(ess-r-mode))))
|
||||
|
||||
;;; S imenu support
|
||||
|
||||
;; don't use syntax classes, bad for etags
|
||||
(defvar ess-imenu-S-generic-expression
|
||||
'(("Functions" "^\\([^ \t\n]+\\)[ \t\n]*\\(?:<-\\|=\\)[ \t\n]*function[ ]*(" 1)
|
||||
("Classes" "^.*setClass(\\(.*\\)," 1)
|
||||
("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
|
||||
("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
|
||||
("Methods" "^.*set\\(Group\\|Replace\\)?Method(\\([^,]+,[^,]*\\)" 2)
|
||||
("Package" "^.*\\(library\\|require\\)(\\([^)]*\\)" 2)
|
||||
("Data" "^\\(.+\\)[ \t\n]-*\\(?:<-\\|=\\)[ \t\n]*\\(read\\|.*data\\.frame\\).*(" 1))
|
||||
"Imenu generic expression for S modes.
|
||||
See `imenu-generic-expression'.")
|
||||
|
||||
(defun ess-imenu-S (&optional _arg)
|
||||
"S Language Imenu support for ESS.
|
||||
ARG is ignored."
|
||||
(declare (obsolete "It is set automatically in major modes" "ESS 19.04"))
|
||||
(imenu-add-to-menubar "Imenu-S"))
|
||||
|
||||
(define-obsolete-function-alias 'ess-imenu-R 'ess-imenu-S "ESS 19.04")
|
||||
|
||||
|
||||
;;; Speedbar stuff.
|
||||
|
||||
(eval-after-load "speedbar"
|
||||
'(progn
|
||||
(speedbar-add-supported-extension ".R")
|
||||
(speedbar-add-supported-extension ".S")
|
||||
(speedbar-add-supported-extension ".s")
|
||||
(speedbar-add-supported-extension ".q")))
|
||||
|
||||
(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "R"))
|
||||
"Return a list of current S help topics associated with process PROC.
|
||||
If 'sp-for-help-changed?' process variable is non-nil or
|
||||
`ess-help-topics-list' is nil, (re)-populate the latter and
|
||||
return it. Otherwise, return `ess-help-topics-list'."
|
||||
(with-ess-process-buffer nil
|
||||
(cond
|
||||
;; (Re)generate the list of topics
|
||||
((or (not ess-help-topics-list)
|
||||
(ess-process-get 'sp-for-help-changed?))
|
||||
(ess-process-put 'sp-for-help-changed? nil)
|
||||
(setq ess-help-topics-list
|
||||
(delete-dups
|
||||
(append (ess-get-object-list proc 'exclude-1st)
|
||||
(ess-get-help-files-list)
|
||||
(ess-get-help-aliases-list)))))
|
||||
(t
|
||||
ess-help-topics-list))))
|
||||
|
||||
(defalias 'S 'S+)
|
||||
(defalias 's-mode 'S+-mode)
|
||||
(defalias 's-transcript-mode 'S+-transcript-mode)
|
||||
(defalias 'S-transcript-mode 's-transcript-mode)
|
||||
(defalias 'S-mode 's-mode)
|
||||
|
||||
|
||||
(define-obsolete-function-alias 'ess-toggle-S-assign-key #'ignore "ESS 18.10")
|
||||
(define-obsolete-function-alias 'ess-smart-underscore 'ess-insert-assign "ESS 18.10")
|
||||
(define-obsolete-function-alias 'ess-insert-S-assign 'ess-insert-assign "ESS 18.10")
|
||||
|
||||
(define-obsolete-function-alias 'ess-toggle-underscore 'ess-disable-smart-S-assign "ESS 18.10")
|
||||
(define-obsolete-function-alias 'ess-toggle-S-assign 'ess-disable-smart-S-assign "ESS 18.10")
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Ss]t\\'" . S-transcript-mode))
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.Sout" . S-transcript-mode))
|
||||
|
||||
(provide 'ess-s-lang)
|
||||
|
||||
;;; ess-s-lang.el ends here
|
||||
1456
lisp/ess/ess-sas-a.el
Normal file
1456
lisp/ess/ess-sas-a.el
Normal file
File diff suppressed because it is too large
Load Diff
334
lisp/ess/ess-sas-d.el
Normal file
334
lisp/ess/ess-sas-d.el
Normal file
@@ -0,0 +1,334 @@
|
||||
;;; ess-sas-d.el --- SAS customization
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
;; Author: Richard M. Heiberger <rmh@temple.edu>
|
||||
;; Created: 20 Aug 1997
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file defines all the SAS customizations for ESS behaviors. See
|
||||
;; ess-sas-l and ess-sas-a for the underlying general modifications.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'shell)
|
||||
(require 'ess-sas-l)
|
||||
|
||||
(defcustom SAS-mode-hook nil
|
||||
"Hook to run when entering SAS mode."
|
||||
:type 'hook
|
||||
:group 'ess-sas)
|
||||
|
||||
(defvar inferior-SAS-args "-stdio -linesize 80 -noovp -nosyntaxcheck"
|
||||
"Arguments to use for starting SAS.")
|
||||
|
||||
(defvar inferior-SAS-args-temp nil
|
||||
"Hack variable, needed for args preprocessing.
|
||||
Better logic needed! (see 2 uses, in this file).")
|
||||
|
||||
(defvar SAS-mode-syntax-table
|
||||
(let ((tab (make-syntax-table)))
|
||||
(modify-syntax-entry ?\\ "." tab) ;; backslash is punctuation
|
||||
(modify-syntax-entry ?+ "." tab)
|
||||
(modify-syntax-entry ?- "." tab)
|
||||
(modify-syntax-entry ?= "." tab)
|
||||
(modify-syntax-entry ?% "w" tab)
|
||||
(modify-syntax-entry ?< "." tab)
|
||||
(modify-syntax-entry ?> "." tab)
|
||||
(modify-syntax-entry ?& "w" tab)
|
||||
(modify-syntax-entry ?| "." tab)
|
||||
(modify-syntax-entry ?\' "\"" tab)
|
||||
(modify-syntax-entry ?* ". 23" tab) ; comment character
|
||||
(modify-syntax-entry ?\; "." tab)
|
||||
(modify-syntax-entry ?_ "w" tab)
|
||||
(modify-syntax-entry ?< "." tab)
|
||||
(modify-syntax-entry ?> "." tab)
|
||||
(modify-syntax-entry ?/ ". 14" tab) ; comment character
|
||||
(modify-syntax-entry ?. "w" tab)
|
||||
tab)
|
||||
"Syntax table for `SAS-mode'.")
|
||||
|
||||
(defun ess-SAS-pre-run-hook (temp-ess-dialect)
|
||||
"Set up log and list files for interactive SAS."
|
||||
|
||||
(let* ((ess-shell-buffer-name-flag (get-buffer "*shell*"))
|
||||
ess-shell-buffer-name
|
||||
;; isn't pretty yet.
|
||||
;; ess-local-process-name is defined after this function.
|
||||
;; it needs to be defined prior to this function.
|
||||
(tmp-procname (let ((ntry 0)
|
||||
(done nil))
|
||||
;; find a non-existent process
|
||||
(while (not done)
|
||||
(setq ntry (1+ ntry)
|
||||
done (not
|
||||
(get-process (ess-proc-name
|
||||
ntry
|
||||
temp-ess-dialect)))))
|
||||
(ess-proc-name ntry temp-ess-dialect)))
|
||||
;; Following was tmp-local-process-name. Stolen from inferior-ess
|
||||
(ess-sas-lst-bufname (concat "*" tmp-procname ".lst*"))
|
||||
(ess-sas-log-bufname (concat "*" tmp-procname ".log*"))
|
||||
(explicit-shell-file-name "/bin/sh")
|
||||
inferior-SAS-redirect-args
|
||||
ess-sas-lst
|
||||
ess-sas-log)
|
||||
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "(ess-SAS-pre-run-hook 1): ess-lang=%s, ess-dialect=%s, temp-dialect=%s, buf=%s \n"
|
||||
ess-language
|
||||
ess-dialect
|
||||
temp-ess-dialect
|
||||
(current-buffer)))
|
||||
;; If someone is running a *shell* buffer, rename it to avoid
|
||||
;; inadvertent nuking.
|
||||
(if ess-shell-buffer-name-flag
|
||||
(with-current-buffer "*shell*"
|
||||
(setq ess-shell-buffer-name
|
||||
(rename-buffer "*ess-shell-regular*" t))))
|
||||
|
||||
;; Construct the LST buffer for output
|
||||
(if (get-buffer ess-sas-lst-bufname)
|
||||
nil
|
||||
(shell)
|
||||
(accept-process-output (get-buffer-process (current-buffer)))
|
||||
(sleep-for 2) ; need to wait, else working too fast!
|
||||
(setq ess-sas-lst (ess-insert-accept "tty"))
|
||||
(SAS-listing-mode)
|
||||
(shell-mode)
|
||||
(ess-listing-minor-mode t)
|
||||
(rename-buffer ess-sas-lst-bufname t))
|
||||
|
||||
;; Construct the LOG buffer for output
|
||||
(if (get-buffer ess-sas-log-bufname)
|
||||
nil
|
||||
(shell)
|
||||
(accept-process-output (get-buffer-process (current-buffer)))
|
||||
(sleep-for 2) ; need to wait, else working too fast!
|
||||
(setq ess-sas-log (ess-insert-accept "tty"))
|
||||
;(SAS-log-mode)
|
||||
(shell-mode)
|
||||
(ess-transcript-minor-mode t)
|
||||
(rename-buffer ess-sas-log-bufname t))
|
||||
|
||||
(setq inferior-SAS-redirect-args (concat " "
|
||||
ess-sas-lst
|
||||
" "
|
||||
ess-sas-log
|
||||
" ")
|
||||
inferior-SAS-args-temp (concat inferior-SAS-redirect-args
|
||||
inferior-SAS-args))
|
||||
|
||||
;; Restore the *shell* buffer
|
||||
(if ess-shell-buffer-name-flag
|
||||
(with-current-buffer ess-shell-buffer-name
|
||||
(rename-buffer "*shell*")))
|
||||
|
||||
(delete-other-windows)
|
||||
(split-window-vertically)
|
||||
(split-window-vertically)
|
||||
(switch-to-buffer (nth 2 (buffer-list)))
|
||||
(other-window 2)
|
||||
(switch-to-buffer ess-sas-log-bufname)
|
||||
(split-window-vertically)
|
||||
(other-window 1)
|
||||
(switch-to-buffer ess-sas-lst-bufname)
|
||||
(other-window 2)
|
||||
|
||||
;;workaround
|
||||
(setq inferior-SAS-program
|
||||
(concat (file-name-as-directory ess-etc-directory)
|
||||
"ess-sas-sh-command"))
|
||||
(setq inferior-ess-program inferior-SAS-program)))
|
||||
|
||||
(defun ess-insert-accept (command)
|
||||
"Submit command to process, get next line."
|
||||
(interactive)
|
||||
(goto-char (point-max))
|
||||
(insert command)
|
||||
(comint-send-input)
|
||||
(accept-process-output (get-buffer-process (current-buffer)))
|
||||
(forward-line -1)
|
||||
(let* ((beg (point))
|
||||
(ess-tty-name (progn (end-of-line) (buffer-substring beg (point)))))
|
||||
(goto-char (point-max))
|
||||
ess-tty-name))
|
||||
|
||||
|
||||
(defvar SAS-customize-alist
|
||||
'((ess-local-customize-alist . 'SAS-customize-alist)
|
||||
(ess-language . "SAS")
|
||||
(ess-dialect . "SAS")
|
||||
(inferior-ess-program . inferior-SAS-program)
|
||||
(ess-help-sec-regex . "^[A-Z. ---]+:$")
|
||||
(ess-help-sec-keys-alist . " ")
|
||||
(ess-object-name-db-file . "ess-sas-namedb.el")
|
||||
(inferior-ess-objects-command . "objects(%d)");;FIXME
|
||||
(inferior-ess-help-command . "help(\"%s\",pager=\"cat\",window=F)\n");;FIXME
|
||||
(inferior-ess-exit-command . "endsas;\n")
|
||||
(ess-loop-timeout . 500000 )
|
||||
(inferior-ess-primary-prompt . "^")
|
||||
(inferior-ess-secondary-prompt . "^")
|
||||
(comint-use-prompt-regexp . t)
|
||||
(inferior-ess-start-args . inferior-SAS-args-temp)
|
||||
;; (ess-pre-run-hook . 'ess-SAS-pre-run-hook)
|
||||
;; (ess-local-process-name . nil)
|
||||
)
|
||||
"Variables to customize for SAS")
|
||||
|
||||
;;; The functions of interest (mode, inferior mode)
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode SAS-mode ess-mode "[SAS]"
|
||||
"Major mode for editing SAS source. See `ess-mode' for more help."
|
||||
:group 'ess-sas
|
||||
(ess-setq-vars-local SAS-customize-alist)
|
||||
(setq ess-local-customize-alist SAS-customize-alist)
|
||||
(setq-local sentence-end ";[\t\n */]*")
|
||||
(setq-local paragraph-start "^[ \t]*$")
|
||||
(setq-local paragraph-separate "^[ \t]*$")
|
||||
(setq-local paragraph-ignore-fill-prefix t)
|
||||
(setq-local adaptive-fill-mode nil)
|
||||
(setq-local indent-line-function #'sas-indent-line)
|
||||
(setq-local comment-start "/*")
|
||||
(setq-local comment-start-skip "/[*]")
|
||||
(setq-local comment-end "*/")
|
||||
(setq-local comment-end-skip "[*]/")
|
||||
(setq-local comment-column 40)
|
||||
(setq-local ess-local-process-name nil)
|
||||
(setq-local tab-stop-list ess-sas-tab-stop-list)
|
||||
(setq-local font-lock-keywords-case-fold-search t)
|
||||
;; Local map settings, AFTER initialization (only if not yet defined)
|
||||
(unless sas-mode-local-map
|
||||
(setq sas-mode-local-map (copy-keymap (current-local-map)))
|
||||
(ess-sas-edit-keys-set ess-sas-edit-keys-toggle)
|
||||
(if ess-sas-local-unix-keys (ess-sas-local-unix-keys))
|
||||
(if ess-sas-local-pc-keys (ess-sas-local-pc-keys))
|
||||
(if ess-sas-global-unix-keys (ess-sas-global-unix-keys))
|
||||
(if ess-sas-global-pc-keys (ess-sas-global-pc-keys)))
|
||||
(define-key sas-mode-local-map ";" 'ess-electric-run-semicolon)
|
||||
(define-key sas-mode-local-map (kbd "\C-c\C-w") 'ess-multi-frame-SAS)
|
||||
;; this is a mess
|
||||
;; interactive and batch commands share sas-mode-local-map,
|
||||
;; but the associated commands are very different
|
||||
;; what would be better is two maps like
|
||||
;; sas-batch-mode-local-map and sas-interactive-mode-local-map
|
||||
;; or smart function definitions that would do the appropriate
|
||||
;; thing for either batch or interactive sessions
|
||||
;; however, neither of these solutions are planned
|
||||
;; therefore, no key definitions can be shared between
|
||||
;; batch and interactive at this time, hence the lines that
|
||||
;; are commented below: uncomment at your own risk
|
||||
;; (define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
|
||||
;; (define-key sas-mode-local-map "\C-c\C-b" 'ess-sas-submit)
|
||||
;; (define-key sas-mode-local-map "\C-c\C-r" 'ess-sas-submit-region)
|
||||
;; (define-key sas-mode-local-map "\C-c\C-x" 'ess-sas-goto-log)
|
||||
;; (define-key sas-mode-local-map "\C-c\C-y" 'ess-sas-goto-lst)
|
||||
|
||||
(use-local-map sas-mode-local-map)
|
||||
|
||||
(setq font-lock-defaults
|
||||
;; KEYWORDS KEYWORDS-ONLY CASE-FOLD .....
|
||||
'(SAS-mode-font-lock-defaults nil t)))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.[Ss][Aa][Ss]\\'" . SAS-mode))
|
||||
|
||||
;; rmh Jul 10 2003
|
||||
(defun ess-electric-run-semicolon (arg)
|
||||
"Insert character. If the line contains \"run;\" or \"quit;\" and nothing else then indent line."
|
||||
(interactive "P")
|
||||
(if ess-sas-edit-keys-toggle (insert ";") (let (insertpos)
|
||||
(if (and (not arg)
|
||||
(eolp)
|
||||
(save-excursion
|
||||
(skip-chars-backward " \t")
|
||||
(backward-word 1)
|
||||
(and (looking-at "run\\|quit")
|
||||
(progn
|
||||
(skip-chars-backward " \t")
|
||||
(bolp)))))
|
||||
(progn
|
||||
(insert last-command-event)
|
||||
(funcall indent-line-function)
|
||||
(save-excursion
|
||||
(if insertpos (goto-char (1+ insertpos)))
|
||||
(delete-char -1))))
|
||||
(if insertpos
|
||||
(save-excursion
|
||||
(goto-char insertpos)
|
||||
(self-insert-command (prefix-numeric-value arg)))
|
||||
(self-insert-command (prefix-numeric-value arg))))))
|
||||
|
||||
(defun SAS-menu ()
|
||||
"Start SAS from the menu."
|
||||
(interactive)
|
||||
(if ess-microsoft-p
|
||||
;; replace with other choices for starting SAS?
|
||||
(error "SAS cannot be started this way in ESS on Windows.")
|
||||
(SAS)))
|
||||
|
||||
(defun SAS ()
|
||||
"Call 'SAS', from SAS Institute."
|
||||
(interactive)
|
||||
(let* ((temp-dialect "SAS")) ;(cdr (rassoc ess-dialect SAS-customize-alist))))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "(SAS): ess-dial=%s, temp-dial=%s\n"
|
||||
ess-dialect
|
||||
temp-dialect))
|
||||
(ess-SAS-pre-run-hook temp-dialect)
|
||||
(setq ess-eval-visibly-p nil)
|
||||
;; FIXME: `inferior-SAS-args' is defined from
|
||||
;; `inferior-SAS-args-temp' in `ess-SAS-pre-run-hook'
|
||||
(let ((inf-buf (inferior-ess nil SAS-customize-alist)))
|
||||
(with-current-buffer inf-buf
|
||||
(use-local-map sas-mode-local-map))
|
||||
inf-buf)))
|
||||
|
||||
(defun ess-multi-frame-SAS ()
|
||||
"Put running SAS buffers into separate frames.
|
||||
Load this function M-x load-file essx-sas.el RET.
|
||||
Then find-file myfile.sas. If myfile.sas is already in a buffer, kill-buffer
|
||||
it and then find-file it again.
|
||||
Place the cursor in a myfile.sas buffer. Run SAS with M-x SAS,
|
||||
Return the cursor to the myfile.sas buffer,
|
||||
then enter C-c C-w to put *SAS* *SAS.log* *SAS.lst* buffers into
|
||||
their own frames."
|
||||
(interactive)
|
||||
(delete-other-windows)
|
||||
(with-current-buffer "*SAS*"
|
||||
(make-frame))
|
||||
(with-current-buffer "*SAS.log*"
|
||||
(make-frame))
|
||||
(with-current-buffer "*SAS.lst*"
|
||||
(make-frame)))
|
||||
|
||||
(defun ess-num-or-zero (arg)
|
||||
"If a number, then return that number, otherwise return 0."
|
||||
(or (and (numberp arg) arg) 0))
|
||||
|
||||
; Provide package
|
||||
|
||||
(provide 'ess-sas-d)
|
||||
|
||||
;;; ess-sas-d.el ends here
|
||||
1813
lisp/ess/ess-sas-l.el
Normal file
1813
lisp/ess/ess-sas-l.el
Normal file
File diff suppressed because it is too large
Load Diff
65
lisp/ess/ess-site.el
Normal file
65
lisp/ess/ess-site.el
Normal file
@@ -0,0 +1,65 @@
|
||||
;;; ess-site.el --- user customization of ESS -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1993-2020 Free Software Foundation, Inc.
|
||||
;; Author: David Smith <D.M.Smith@lancaster.ac.uk>
|
||||
;; Created: 12 Nov 1993
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Load path, autoloads, and major modes
|
||||
;; ========================================
|
||||
;;
|
||||
;; This file defines all the site-specific customizations for ESS. It should be
|
||||
;; edited on a per-site basis. users who wish to use ESS should add the path to
|
||||
;; ess-site to their `load-path' and require it:
|
||||
;;
|
||||
;; (add-to-list 'load-path "/path/to/ess/lisp-directory");;
|
||||
;; (require 'ess-site)
|
||||
;;
|
||||
;; For most users the variable ess-lisp-directory will automatically be set
|
||||
;; correctly. If you are working with an old Emacs, one in which file-truename
|
||||
;; is not defined, then you might need to change the value of ess-lisp-directory
|
||||
;; to the directory which is to contain the file ess-site.elc. This is probably
|
||||
;; the current directory, or the value of LISPDIR if it was set in the Makefile.
|
||||
;;
|
||||
;; Debug startup: (setq ess-show-load-messages t)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(when load-file-name
|
||||
;; Modify this if ess-site.el is not in the ./lisp/ directory
|
||||
(defvar ess-lisp-directory (file-name-directory load-file-name)
|
||||
"Directory containing ess-site.el(c) and other ESS Lisp files.")
|
||||
(add-to-list 'load-path (directory-file-name ess-lisp-directory)))
|
||||
|
||||
;;; Loading popular dialects (they should become optional in the future)
|
||||
|
||||
(require 'ess-r-mode)
|
||||
(require 'essd-els) ;; ess-remote
|
||||
(require 'ess-sas-d)
|
||||
(require 'ess-bugs-d)
|
||||
(require 'ess-jags-d)
|
||||
(require 'ess-toolbar)
|
||||
|
||||
(provide 'ess-site)
|
||||
|
||||
;;; ess-site.el ends here
|
||||
197
lisp/ess/ess-sp6-d.el
Normal file
197
lisp/ess/ess-sp6-d.el
Normal file
@@ -0,0 +1,197 @@
|
||||
;;; ess-sp6-d.el --- S-Plus 6 & 7 & 8 customization
|
||||
|
||||
;; Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
;; Author: A.J. Rossini <rossini@u.washington.edu>
|
||||
;; Created: 2001/02/06
|
||||
;; Maintainer: ESS Core Team <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; AJR copied S+5 to be S+6.
|
||||
;; AJR copied S4 to be S+5.
|
||||
;; DB contributed the changes from ess-sp3-d.el to
|
||||
;; ess-s4-d.el. (removed the old ugly approach).
|
||||
;; This file defines Sp5 customizations for ess-mode. Lots of thanks
|
||||
;; to RMH and JMC for code and suggestions
|
||||
;; Thanks to MM for making this sensible.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-mode)
|
||||
(require 'ess-inf)
|
||||
(require 'ess-s-lang)
|
||||
(require 'ess-trns)
|
||||
|
||||
|
||||
;; You now need to make sure you've defined if you are running 5.0 or 5.1.
|
||||
;; Lots of things are broken between them, GRR...
|
||||
|
||||
(defun S+-directory-p (directory)
|
||||
"Splus 5++ directories have a .Data directory and a __Meta directory within."
|
||||
(and directory
|
||||
(file-directory-p (concat directory ".Data"))
|
||||
(file-directory-p (concat directory ".Data/__Meta"))))
|
||||
|
||||
(defvar S+-directory-function #'inferior-ess-default-directory)
|
||||
|
||||
(defvaralias 'S+6-setup-directory-function 'S+-setup-directory-function)
|
||||
(defvar S+-setup-directory-function
|
||||
(lambda (startdir)
|
||||
(when (and startdir (S+-directory-p startdir))
|
||||
(setenv "S_WORK"
|
||||
(if (getenv "S_WORK")
|
||||
(concat startdir ":" (getenv "S_WORK"))
|
||||
;;(message "adding %s to S_WORK" startdir)
|
||||
startdir)))))
|
||||
|
||||
|
||||
|
||||
(defvaralias 'S+6-customize-alist 'S+-customize-alist)
|
||||
(defvar S+-customize-alist
|
||||
(append
|
||||
'((ess-local-customize-alist . 'S+-customize-alist)
|
||||
(ess-dialect . S+-dialect-name)
|
||||
(ess-function-pattern . ess-r-function-pattern)
|
||||
|
||||
(ess-object-name-db-file . "ess-sp6-namedb.el")
|
||||
(inferior-ess-program . inferior-S+-program)
|
||||
(inferior-ess-help-command . "help(\"%s\", pager=\"slynx -dump\", window=FALSE)\n")
|
||||
(inferior-ess-search-list-command . "searchPaths()\n")
|
||||
|
||||
(ess-directory-function . S+-directory-function)
|
||||
(ess-setup-directory-function . S+-setup-directory-function)
|
||||
(ess-STERM . "iESS"))
|
||||
S+common-cust-alist)
|
||||
|
||||
"Variables to customize for S+.")
|
||||
|
||||
(defvar ess-S+-post-run-hook nil
|
||||
"Functions run in process buffer after the initialization of S+
|
||||
process.")
|
||||
|
||||
(defvar ess-S+--injected-code
|
||||
".ess_funargs <- function(funname){
|
||||
## funname <- deparse(substitute(object))
|
||||
fun <- try(eval(parse(text=funname)), silent = TRUE)
|
||||
if(is.function(fun)) {
|
||||
special <- grepl('[:$@[]', funname)
|
||||
args <- args(fun)
|
||||
fmls <- formals(args)
|
||||
fmls.names <- names(fmls)
|
||||
fmls <- gsub('\\\"', '\\\\\\\"', as.character(fmls), fixed = TRUE)
|
||||
args.alist <- sprintf(\"'(%s)\", paste(\"(\\\"\", fmls.names, \"\\\" . \\\"\", fmls, \"\\\")\", sep = '', collapse = ' '))
|
||||
## envname <- environmentName(environment(fun))
|
||||
envname <- if (special) '' else 'S+'
|
||||
cat(sprintf('(list \\\"%s\\\" %s )\\n', envname, args.alist))
|
||||
}
|
||||
}
|
||||
")
|
||||
|
||||
(defalias 'S+6 'S+)
|
||||
(defun S+ (&optional proc-name)
|
||||
"Call 'Splus6', based on S version 4, from Bell Labs.
|
||||
New way to do it."
|
||||
(interactive)
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "\n(S+): ess-dialect=%s, buf=%s\n" ess-dialect (current-buffer)))
|
||||
(let ((inf-buf (inferior-ess nil S+-customize-alist)))
|
||||
(ess-command ess-S+--injected-code)
|
||||
(when inferior-ess-language-start
|
||||
(ess-eval-linewise inferior-ess-language-start))
|
||||
(with-current-buffer inf-buf
|
||||
(run-mode-hooks 'ess-S+-post-run-hook))
|
||||
inf-buf))
|
||||
|
||||
|
||||
(defalias 'S+6-mode 'S+-mode)
|
||||
;;;###autoload
|
||||
(defun S+-mode (&optional proc-name)
|
||||
"Major mode for editing S+ source. See `ess-mode' for more help."
|
||||
(interactive)
|
||||
(setq-local ess-local-customize-alist S+-customize-alist)
|
||||
(ess-mode)
|
||||
(if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
|
||||
(setq imenu-generic-expression ess-imenu-S-generic-expression)
|
||||
(when ess-imenu-use-S (imenu-add-to-menubar "Imenu-S")))
|
||||
|
||||
(defalias 'S+6-transcript-mode 'S+-transcript-mode)
|
||||
(define-derived-mode S+-transcript-mode ess-transcript-mode "ESS S Transcript"
|
||||
"S-PLUS 6 transcript mode."
|
||||
:syntax-table S-syntax-table
|
||||
:group 'ess-S)
|
||||
|
||||
(defvar ess-s-versions '("Splus")
|
||||
"List of partial strings for versions of S to access within ESS.
|
||||
Each string specifies the start of a filename. If a filename
|
||||
beginning with one of these strings is found on `exec-path', a M-x
|
||||
command for that version of S is made available. For example, if the
|
||||
file \"Splus7\" is found and this variable includes the string
|
||||
\"Splus\", a function called `M-x Splus7' will be available to run that
|
||||
version of S.
|
||||
If duplicate versions of the same program are found (which happens if
|
||||
the same path is listed on `exec-path' more than once), they are
|
||||
ignored by calling `delete-dups'.
|
||||
Set this variable to nil to disable searching for other versions
|
||||
of S using this method.
|
||||
If you set this variable, you need to restart Emacs (and set this variable
|
||||
before ess-site is loaded) for it to take effect.")
|
||||
(define-obsolete-variable-alias
|
||||
'ess-s-versions-created 'ess-s-created-runners "ESS 18.10")
|
||||
(defvar ess-s-created-runners)
|
||||
(defun ess-s-define-runners ()
|
||||
"Generate functions for starting other versions of S.
|
||||
See `ess-s-versions' for strings that determine which functions are created.
|
||||
It assumes these versions of S can be run as a substitute for Splus6.
|
||||
|
||||
This function returns the list of functions, if any, that were
|
||||
created. The functions will normally be placed on the menubar upon
|
||||
ESS initialization."
|
||||
(when ess-s-versions
|
||||
(let ((versions
|
||||
(delete-dups
|
||||
(mapcar #'file-name-nondirectory
|
||||
(apply #'nconc
|
||||
(mapcar #'ess-find-exec-completions
|
||||
ess-s-versions))))))
|
||||
;; Iterate over each string in VERSIONS, creating a new defun
|
||||
;; each time.
|
||||
(setq ess-s-created-runners
|
||||
(mapc (lambda (v) (ess-define-runner v "S")) versions))
|
||||
;; Add to menu
|
||||
(when ess-s-created-runners
|
||||
;; new-menu will be a list of 3-vectors, of the form:
|
||||
;; ["R-1.8.1" R-1.8.1 t]
|
||||
(let ((new-menu (mapcar (lambda (x) (vector x (intern x) t))
|
||||
ess-s-created-runners)))
|
||||
(easy-menu-add-item ess-mode-menu '("Start Process")
|
||||
(cons "Other" new-menu)))))))
|
||||
;; Define the runners
|
||||
(ess-s-define-runners)
|
||||
(define-obsolete-function-alias
|
||||
'ess-s-versions-create 'ess-s-define-runners "ESS 18.10")
|
||||
|
||||
|
||||
|
||||
; Provide package
|
||||
|
||||
(provide 'ess-sp6-d)
|
||||
|
||||
;;; ess-sp6-d.el ends here
|
||||
184
lisp/ess/ess-toolbar.el
Normal file
184
lisp/ess/ess-toolbar.el
Normal file
@@ -0,0 +1,184 @@
|
||||
;;; ess-toolbar.el --- Support for a toolbar in ESS. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
;; Author: Stephen Eglen
|
||||
;; Created: 2004-05-06
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This code adds a toolbar to ESS modes for editing R and S code.
|
||||
;; Support can be added for other modes (e.g. STATA), just ask!
|
||||
;;
|
||||
;; This code is experimental. It has been tested only on Linux
|
||||
;; machines. All feedback appreciated.
|
||||
;;
|
||||
;; If your Emacs can support images, the ESS toolbar should be loaded.
|
||||
;;
|
||||
;; If you see a toolbar, but no icons, check out the value of
|
||||
;; ess-icon-directory.
|
||||
;;
|
||||
;; The toolbar can be customized in several ways. To see options, do:
|
||||
;; M-x customize-group RET ess-toolbar RET
|
||||
;; If you change any of the variables, you _may_ need to restart Emacs
|
||||
;; to see any effect. See also the documentation for ess-toolbar-items
|
||||
;; if you wish to change its value.
|
||||
|
||||
;;; Technical issues.
|
||||
|
||||
;; 2009-03-16: toolbar code in Emacs 23 has changed slightly to 22,
|
||||
;; and presumably once Emacs 22 is no longer supported, this code can
|
||||
;; be cleaned up a bit (i.e. no need to set load-path.)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-mode)
|
||||
|
||||
(defgroup ess-toolbar nil
|
||||
"ESS: toolbar support."
|
||||
:group 'ess
|
||||
:link '(emacs-commentary-link :tag "Commentary" "ess-toolbar.el")
|
||||
:prefix "ess-")
|
||||
|
||||
(defcustom ess-use-toolbar
|
||||
(and (fboundp 'display-images-p) (display-images-p))
|
||||
"Non-nil means ESS should support the toolbar."
|
||||
:type 'boolean)
|
||||
|
||||
|
||||
(defcustom ess-toolbar-own-icons nil
|
||||
"Non-nil means that we only put our toolbar entries in ESS.
|
||||
Otherwise we get standard toolbar as well as ESS entries.
|
||||
The standard toolbar items are copied from the default toolbar."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom ess-toolbar-global nil
|
||||
"*Non-nil means that the ESS toolbar is available in all Emacs buffers.
|
||||
Otherwise, the ESS toolbar is present only in R/S mode buffers.
|
||||
For beginners, this is probably better set to a non-nil value."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom ess-toolbar-items
|
||||
'( (R "startr")
|
||||
;;(S "spluslogo" "Start S process")
|
||||
(S "splus_letter_small")
|
||||
(ess-eval-line-and-step "rline")
|
||||
(ess-eval-region "rregion")
|
||||
(ess-eval-function-or-paragraph-and-step "rregion")
|
||||
(ess-load-file "rbuffer")
|
||||
(ess-eval-function "rfunction")
|
||||
(ess-switch-to-ESS "switch_ess"))
|
||||
"Items to be added to the ESS toolbar.
|
||||
Each list element has two items:
|
||||
1. the name of the function to run
|
||||
2. the icon to be used (without .xpm extension)
|
||||
|
||||
General toolbar items are also added to the ESS toolbar
|
||||
iff `ess-toolbar-own-icons' is nil.
|
||||
|
||||
Setting this variable with setq doesn't take effect once you have
|
||||
loaded ess-site, unless you follow it by a call to
|
||||
`ess-make-toolbar' afterwards. Instead, change its value using
|
||||
Custom, and then on all new ESS buffers you should see the
|
||||
toolbar has changed."
|
||||
:set (lambda (symbol value)
|
||||
(set-default symbol value)
|
||||
(if (fboundp 'ess-make-toolbar)
|
||||
(ess-make-toolbar)))
|
||||
:type '(repeat (list (function :tag "Function to run")
|
||||
(string :tag "Icon"))))
|
||||
|
||||
(defvar ess-icon-directory
|
||||
(expand-file-name "icons" ess-etc-directory)
|
||||
"*Location for ESS icons.
|
||||
This variable should be set automatically by the ESS install process.
|
||||
Icons should be found in ESS/etc/icons/ directory.
|
||||
If `ess-icon-directory' is invalid, please report a bug.")
|
||||
|
||||
(unless (file-directory-p ess-icon-directory)
|
||||
(ess-write-to-dribble-buffer
|
||||
"`ess-icon-directory' does not exist; using `ess-etc-directory'.\n")
|
||||
(setq ess-icon-directory ess-etc-directory))
|
||||
|
||||
(defvar ess-toolbar nil
|
||||
"Toolbar items to be added to ESS editing buffers.")
|
||||
|
||||
(defun ess-make-toolbar ()
|
||||
"Make the ESS toolbar."
|
||||
;; Under Emacs, only worth building the toolbar if tool-bar-map is
|
||||
;; available. e.g. when running Emacs within a terminal, tool-bar-map
|
||||
;; is not available, so no need to make the tool-bar.
|
||||
(when (boundp 'tool-bar-map)
|
||||
(setq ess-toolbar
|
||||
(if (or ess-toolbar-own-icons (null tool-bar-map))
|
||||
(make-sparse-keymap)
|
||||
(copy-keymap tool-bar-map)))
|
||||
(let ((tool-bar-map ess-toolbar)
|
||||
(load-path (list ess-icon-directory)))
|
||||
;; in Emacs 22, icons are found by examining load-path, bound here
|
||||
;; whereas Emacs 23 seems to want them in image-load-path, set at the
|
||||
;; bottom of this file.
|
||||
(mapc #'ess-add-icon ess-toolbar-items))))
|
||||
|
||||
(defun ess-add-icon (x)
|
||||
"Add an ESS item to the Emacs toolbar.
|
||||
X should be a list, see `ess-toolbar-items' for the format."
|
||||
;; By using tool-bar-add-item-from-menu instead of tool-bar-add-item
|
||||
;; we get the tooltips "for free" from ess-mode-map.
|
||||
(tool-bar-add-item-from-menu (car x) (cadr x) ess-mode-map))
|
||||
|
||||
(defun ess-add-toolbar ()
|
||||
"Add the ESS toolbar to a particular mode.
|
||||
The toolbar is added iff `ess-toolbar-global' is nil, else the toolbar
|
||||
is added globally when ess-toolbar.el is loaded."
|
||||
(when (and ess-toolbar (not ess-toolbar-global))
|
||||
(setq-local tool-bar-map ess-toolbar)))
|
||||
|
||||
;; Make the toolbars. Each toolbar is hopefully made only when this file
|
||||
;; is loaded; we don't need it to be remade every time.
|
||||
(if ess-use-toolbar
|
||||
(progn
|
||||
(ess-make-toolbar)
|
||||
;; After making the toolbar, if ESS toolbar is needed globally,
|
||||
;; add it here.
|
||||
(if ess-toolbar-global
|
||||
(setq tool-bar-map ess-toolbar)
|
||||
(ess-write-to-dribble-buffer "Creating global Emacs toolbar"))
|
||||
|
||||
;; Check for toolbar support - needed iff ess-use-toolbar is non-nil.
|
||||
(or
|
||||
;; Emacs support for images:
|
||||
(and (fboundp 'display-images-p) (display-images-p))
|
||||
;; if above tests failed, give a warning.
|
||||
(progn
|
||||
(message "Toolbar support for ESS not available in this Emacs.")
|
||||
;; Not sure if we want to delay startup of ESS.
|
||||
;;(sit-for 2)
|
||||
))
|
||||
))
|
||||
|
||||
;; Following needed for Emacs 23, not Emacs 22
|
||||
(when (boundp 'image-load-path)
|
||||
(add-to-list 'image-load-path ess-icon-directory))
|
||||
|
||||
(provide 'ess-toolbar)
|
||||
|
||||
;;; ess-toolbar.el ends here
|
||||
2806
lisp/ess/ess-tracebug.el
Normal file
2806
lisp/ess/ess-tracebug.el
Normal file
File diff suppressed because it is too large
Load Diff
232
lisp/ess/ess-trns.el
Normal file
232
lisp/ess/ess-trns.el
Normal file
@@ -0,0 +1,232 @@
|
||||
;;; ess-trns.el --- Support for manipulating S transcript files -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1989-2020 Free Software Foundation, Inc.
|
||||
;; Author: David Smith <dsmith@stats.adelaide.edu.au>
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Code for dealing with ESS transcripts.
|
||||
|
||||
;;; Code:
|
||||
|
||||
; Requires and autoloads
|
||||
|
||||
(require 'ess-mode)
|
||||
(require 'ess-inf)
|
||||
(require 'comint)
|
||||
|
||||
(declare-function ess-display-help-on-object "ess-help" (object &optional command))
|
||||
|
||||
; ess-transcript-mode
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; In this section:
|
||||
;;;;
|
||||
;;;; * The major mode ess-transcript-mode
|
||||
;;;; * Commands for ess-transcript-mode
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defcustom ess-transcript-mode-hook nil
|
||||
"Hook for customizing ESS transcript mode."
|
||||
:group 'ess-hooks
|
||||
:type 'hook)
|
||||
|
||||
;;*;; Major mode definition
|
||||
(defvar ess-transcript-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "\C-c\C-s" #'ess-switch-process)
|
||||
(define-key map "\C-c\C-r" #'ess-eval-region)
|
||||
(define-key map "\C-c\M-r" #'ess-eval-region-and-go)
|
||||
(define-key map "\C-c\C-k" #'ess-force-buffer-current)
|
||||
(define-key map "\C-c\C-q" #'ess-quit)
|
||||
(define-key map "\C-c\C-j" #'ess-transcript-send-command)
|
||||
(define-key map "\C-c\M-j" #'ess-transcript-send-command-and-move)
|
||||
(define-key map "\M-\C-a" #'ess-goto-end-of-function-or-para)
|
||||
(define-key map "\M-\C-e" #'ess-goto-end-of-function-or-para)
|
||||
(define-key map "\C-c\C-y" #'ess-switch-to-ESS)
|
||||
(define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
|
||||
(define-key map "\C-c\C-v" #'ess-display-help-on-object)
|
||||
(define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
|
||||
(define-key map "\C-a" #'comint-bol)
|
||||
(define-key map "\M-\t" #'comint-replace-by-expanded-filename)
|
||||
(define-key map "\M-?" #'comint-dynamic-list-completions)
|
||||
(define-key map "\C-c\C-k" #'ess-request-a-process)
|
||||
(define-key map "{" #'skeleton-pair-insert-maybe)
|
||||
(define-key map "}" #'skeleton-pair-insert-maybe)
|
||||
(define-key map "\e\C-h" #'ess-mark-function-or-para)
|
||||
(define-key map "\e\C-q" #'ess-indent-exp)
|
||||
(define-key map "\t" #'ess-indent-command)
|
||||
(define-key map "\C-c\C-p" #'comint-previous-prompt)
|
||||
(define-key map "\C-c\C-n" #'comint-next-prompt)
|
||||
(define-key map "\r" #'ess-transcript-send-command-and-move)
|
||||
(define-key map "\M-\r" #'ess-transcript-send-command)
|
||||
(define-key map "\C-c\r" #'ess-transcript-copy-command)
|
||||
(define-key map "\C-c\C-w" #'ess-transcript-DO-clean-region)
|
||||
(define-key map "\C-c\M-c" #'ess-transcript-clean-buffer)
|
||||
map)
|
||||
"Keymap for `ess-transcript-mode'.")
|
||||
|
||||
(easy-menu-define
|
||||
ess-transcript-mode-menu ess-transcript-mode-map
|
||||
"Menu for use in S transcript mode."
|
||||
'("ESS-trans"
|
||||
["Describe" describe-mode t]
|
||||
["About" (ess-goto-info "Transcript Mode") t]
|
||||
["Send bug report" ess-submit-bug-report t]
|
||||
"------"
|
||||
["Mark cmd group" mark-paragraph t]
|
||||
["Previous prompt" comint-previous-prompt t]
|
||||
["Next prompt" comint-next-prompt t]
|
||||
"------"
|
||||
["Send and move" ess-transcript-send-command-and-move t]
|
||||
["Copy command" ess-transcript-copy-command t]
|
||||
["Send command" ess-transcript-send-command t]
|
||||
["Clean Region" ess-transcript-DO-clean-region t]
|
||||
["Clean Whole Buffer" ess-transcript-clean-buffer t]
|
||||
["Switch S process" ess-switch-process t]
|
||||
))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode ess-transcript-mode ess-mode "ESS Transcript"
|
||||
"Major mode for transcript files.
|
||||
|
||||
Type \\[ess-transcript-send-command] to send a command in the
|
||||
transcript to the current inferior process. \\[ess-transcript-copy-command]
|
||||
copies the command but does not execute it, allowing you to edit it in
|
||||
the process buffer first.
|
||||
|
||||
Type \\[ess-transcript-clean-region] to delete all outputs and prompts
|
||||
in the region, leaving only the commands."
|
||||
:group 'ess
|
||||
(setq buffer-read-only t
|
||||
ess-local-process-name nil
|
||||
mode-line-process '(" [" ess-local-process-name "]"))
|
||||
;; TODO: Set this more normally in various major modes
|
||||
(unless inferior-ess-prompt ;; For S languages it is set in custom-alist
|
||||
(setq inferior-ess-prompt
|
||||
;; Do not anchor to bol with `^'
|
||||
(concat "\\("
|
||||
inferior-ess-primary-prompt
|
||||
"\\|"
|
||||
inferior-ess-secondary-prompt
|
||||
"\\)")))
|
||||
(setq-local paragraph-start (concat "^" inferior-ess-prompt "\\|^\^L"))
|
||||
(setq-local paragraph-separate "^\^L")
|
||||
(setq-local comint-use-prompt-regexp t)
|
||||
(setq-local comint-prompt-regexp (concat "^" inferior-ess-prompt))
|
||||
(setq font-lock-defaults '(ess-build-font-lock-keywords
|
||||
nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
|
||||
|
||||
;;*;; Commands used in S transcript mode
|
||||
|
||||
(defun ess-transcript-send-command ()
|
||||
"Send the command at point in the transcript to the ESS process.
|
||||
The line should begin with a prompt. The ESS process buffer is displayed if it
|
||||
is not already."
|
||||
(interactive)
|
||||
(let* ((proc (or ess-local-process-name
|
||||
(ess-request-a-process "Evaluate into which process? " t)))
|
||||
(ess-buf (ess-get-process-buffer proc)))
|
||||
(setq ess-local-process-name proc)
|
||||
(if (get-buffer-window ess-buf) nil
|
||||
(display-buffer ess-buf t))
|
||||
(let ((input (inferior-ess-get-old-input)))
|
||||
(with-current-buffer ess-buf
|
||||
(goto-char (point-max))
|
||||
(ess-eval-linewise input)))))
|
||||
|
||||
(defun ess-transcript-send-command-and-move ()
|
||||
"Send the command on this line, and move point to the next command."
|
||||
(interactive)
|
||||
(let* ((proc (or ess-local-process-name
|
||||
(ess-request-a-process "Evaluate into which process? " t)))
|
||||
(ess-buf (ess-get-process-buffer proc)))
|
||||
(setq ess-local-process-name proc)
|
||||
(if (get-buffer-window ess-buf) nil
|
||||
(display-buffer ess-buf t))
|
||||
(let ((input (inferior-ess-get-old-input)))
|
||||
(with-current-buffer ess-buf
|
||||
(goto-char (point-max))
|
||||
(ess-eval-linewise input nil nil nil 1))))
|
||||
(comint-next-prompt 1))
|
||||
|
||||
(defun ess-transcript-copy-command ()
|
||||
"Copy the command at point to the command line of the ESS process."
|
||||
(interactive)
|
||||
(let* ((proc (or ess-local-process-name
|
||||
(ess-request-a-process "Evaluate into which process? " t)))
|
||||
(ess-buf (process-buffer (get-process proc)))
|
||||
(input (inferior-ess-get-old-input)))
|
||||
(setq ess-local-process-name proc)
|
||||
(if (get-buffer-window ess-buf) nil
|
||||
(display-buffer ess-buf t))
|
||||
(with-current-buffer ess-buf
|
||||
(goto-char (point-max))
|
||||
(insert input)))
|
||||
(ess-switch-to-end-of-ESS))
|
||||
|
||||
(defun ess-transcript-clean-region (beg end even-if-read-only)
|
||||
"Strip the transcript in the region, leaving only (R/S/Lsp/..) commands.
|
||||
Deletes any lines not beginning with a prompt, and then removes the
|
||||
prompt from those lines that remain. Prefix argument means to
|
||||
clean even if the buffer is \\[read-only]."
|
||||
(interactive "r\nP")
|
||||
(unless inferior-ess-prompt
|
||||
(error "Cannot clean ESS transcript region in this mode!
|
||||
That only works in ess-transcript-mode or inferior-ess-mode ('*R*' etc)."
|
||||
;; Maybe call ess-clean-region-in-new-transcript ?"))
|
||||
))
|
||||
(let ((do-toggle (and buffer-read-only even-if-read-only))
|
||||
(ess-prompt-rx (if inferior-ess-secondary-prompt
|
||||
(concat "^\\(\\("
|
||||
inferior-ess-prompt
|
||||
"\\)\\|\\("
|
||||
inferior-ess-secondary-prompt
|
||||
"\\)\\)")
|
||||
(concat "^" inferior-ess-prompt))))
|
||||
(save-excursion
|
||||
(if do-toggle (setq buffer-read-only nil))
|
||||
(save-restriction
|
||||
(deactivate-mark)
|
||||
(narrow-to-region beg end)
|
||||
(goto-char (point-min))
|
||||
(delete-non-matching-lines ess-prompt-rx)
|
||||
(goto-char (point-min))
|
||||
;; (replace-regexp * * ) :
|
||||
(while (re-search-forward ess-prompt-rx nil t)
|
||||
(replace-match "" nil nil)))
|
||||
|
||||
(if do-toggle (setq buffer-read-only t)))))
|
||||
|
||||
(defun ess-transcript-DO-clean-region (beg end)
|
||||
"Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
|
||||
(interactive "r")
|
||||
(ess-transcript-clean-region beg end 'In-ANY-case))
|
||||
|
||||
(defun ess-transcript-clean-buffer ()
|
||||
"Cleanup the whole buffer.
|
||||
Use point-min/max to obey `narrow-to-region'."
|
||||
(interactive)
|
||||
(ess-transcript-clean-region (point-min) (point-max) 'In-ANY-case))
|
||||
|
||||
(provide 'ess-trns)
|
||||
|
||||
;;; ess-trns.el ends here
|
||||
1039
lisp/ess/ess-utils.el
Normal file
1039
lisp/ess/ess-utils.el
Normal file
File diff suppressed because it is too large
Load Diff
227
lisp/ess/ess.el
Normal file
227
lisp/ess/ess.el
Normal file
@@ -0,0 +1,227 @@
|
||||
;;; ess.el --- Emacs Speaks Statistics -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: David Smith <dsmith@stats.adelaide.edu.au>
|
||||
;; A.J. Rossini <blindglobe@gmail.com>
|
||||
;; Richard M. Heiberger <rmh@temple.edu>
|
||||
;; Kurt Hornik <Kurt.Hornik@R-project.org>
|
||||
;; Martin Maechler <maechler@stat.math.ethz.ch>
|
||||
;; Rodney A. Sparapani <rsparapa@mcw.edu>
|
||||
;; Stephen Eglen <stephen@gnu.org>
|
||||
;; Sebastian P. Luque <spluque@gmail.com>
|
||||
;; Henning Redestig <henning.red@googlemail.com>
|
||||
;; Vitalie Spinu <spinuvit@gmail.com>
|
||||
;; Lionel Henry <lionel.hry@gmail.com>
|
||||
;; J. Alexander Branham <alex.branham@gmail.com>
|
||||
;;
|
||||
;; Maintainer: ESS Core Team <ESS-core@r-project.org>
|
||||
;; Created: 7 Jan 1994
|
||||
;; Version: 18.10.3snapshot
|
||||
;; URL: https://ess.r-project.org/
|
||||
;; Package-Requires: ((emacs "25.1"))
|
||||
;; ESSR-Version: 1.6
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Emacs Speaks Statistics (ESS) is a package designed to support editing of
|
||||
;; scripts and interaction with various statistical analysis programs such as R,
|
||||
;; S-Plus, SAS, Stata and OpenBUGS/JAGS. For more details please visit ESS home
|
||||
;; page at https://ess.r-project.org/
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-utils)
|
||||
(require 'cl-generic)
|
||||
|
||||
(defvar reporter-prompt-for-summary-p)
|
||||
|
||||
|
||||
;; Versions
|
||||
|
||||
(defconst ess-version (eval-when-compile
|
||||
(require 'lisp-mnt)
|
||||
(lm-version (or load-file-name buffer-file-name)))
|
||||
"Version of ESS currently loaded.")
|
||||
|
||||
(defconst essr-version (eval-when-compile
|
||||
(require 'lisp-mnt)
|
||||
(save-excursion (lm-header "ESSR-Version")))
|
||||
"Version of ESSR package.")
|
||||
|
||||
(defvar ess-revision nil
|
||||
"The revision and date of ESS.
|
||||
Is set by \\[ess-version-string].")
|
||||
|
||||
;;;###autoload
|
||||
(defun ess-version ()
|
||||
"Return a string with ESS version information."
|
||||
(interactive)
|
||||
(message (format "ess-version: %s (loaded from %s)"
|
||||
(ess-version-string)
|
||||
(file-name-directory ess-lisp-directory))))
|
||||
|
||||
(defun ess-version-string ()
|
||||
(let* ((ess-dir (file-name-directory ess-lisp-directory)) ; if(<from source>) the top-level 'ess/'
|
||||
(is-release (file-exists-p (concat ess-etc-directory ".IS.RELEASE")))
|
||||
(rel-string (if is-release "Released "))
|
||||
(git-ref-fn (concat ess-dir ".git/HEAD"))
|
||||
(git-ref (when (file-exists-p git-ref-fn)
|
||||
(with-current-buffer (find-file-noselect git-ref-fn)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "ref: \\(.*\\)\n" nil t)
|
||||
(match-string 1)))))
|
||||
(git-fname (if git-ref
|
||||
(concat ess-dir ".git/" git-ref)
|
||||
;; For release
|
||||
(concat ess-etc-directory "git-ref")))
|
||||
(git-rev (when (file-exists-p git-fname)
|
||||
(with-current-buffer (find-file-noselect git-fname)
|
||||
(goto-char (point-min))
|
||||
(concat "git: "(buffer-substring 1 (point-at-eol))))))
|
||||
(elpa-fname (concat ess-dir "ess-pkg.el"))
|
||||
(elpa-rev (when (file-exists-p elpa-fname)
|
||||
;; Get it from ELPA dir name, (probably won't work if installed manually)
|
||||
(concat "elpa: "
|
||||
(replace-regexp-in-string "ess-" ""
|
||||
(file-name-nondirectory
|
||||
(substring ess-dir 1 -1)))))))
|
||||
;; Set the "global" ess-revision:
|
||||
(setq ess-revision (format "%s%s%s"
|
||||
(or rel-string "")
|
||||
(or git-rev "")
|
||||
(or elpa-rev "")))
|
||||
(when (string= ess-revision "")
|
||||
(setq ess-revision "<unknown>"))
|
||||
(concat ess-version " [" ess-revision "]")))
|
||||
|
||||
|
||||
;;; Bug Reporting
|
||||
|
||||
;;;###autoload
|
||||
(defun ess-submit-bug-report ()
|
||||
"Submit a bug report to the ESS maintainers."
|
||||
(interactive)
|
||||
(let ((reporter-prompt-for-summary-p 't))
|
||||
(reporter-submit-bug-report
|
||||
"ess-bugs@r-project.org"
|
||||
(concat "ess-mode " (ess-version-string))
|
||||
(list 'ess-language
|
||||
'ess-dialect
|
||||
'ess-ask-for-ess-directory
|
||||
'ess-ask-about-transfile
|
||||
'default-directory
|
||||
'ess-keep-dump-files
|
||||
'ess-source-directory
|
||||
'ess-use-ido
|
||||
'ess-use-eldoc
|
||||
'ess-use-tracebug
|
||||
'ess-use-auto-complete
|
||||
'ess-use-company
|
||||
'ess-eval-visibly-p
|
||||
'ess-can-eval-in-background
|
||||
'ess-local-process-name)
|
||||
nil
|
||||
(lambda ()
|
||||
;;(goto-char (point-max))
|
||||
(rfc822-goto-eoh)
|
||||
(forward-line 1)
|
||||
(insert "\n\n-------------------------------------------------------\n")
|
||||
(insert "This bug report will be sent to the ESS bugs email list\n")
|
||||
(insert "Press C-c C-c when you are ready to send your message.\n")
|
||||
(insert "-------------------------------------------------------\n\n")
|
||||
(insert (with-current-buffer ess-dribble-buffer
|
||||
(goto-char (point-max))
|
||||
(forward-line -100)
|
||||
(buffer-substring-no-properties (point) (point-max))))))))
|
||||
|
||||
|
||||
|
||||
;;; Timer
|
||||
|
||||
(defcustom ess-idle-timer-interval 1
|
||||
"Number of idle seconds to wait before running function in `ess-idle-timer-functions'."
|
||||
:type '(integer)
|
||||
:group 'ess)
|
||||
|
||||
(defvar ess-idle-timer-functions nil
|
||||
"A list of functions to run each `ess-idle-timer-interval' idle seconds.
|
||||
If your function calls the process, you better use
|
||||
`ess-when-new-input' to wrap your call. If you call the
|
||||
subprocess please respect `ess-can-eval-in-background' variable.
|
||||
|
||||
These functions are run with `run-hooks'. Use `add-hook' to add
|
||||
symbols to this variable.
|
||||
|
||||
Most likely you will need a local hook. Then you should specify
|
||||
the LOCAL argument to `add-hook' and initialize it in
|
||||
`ess-mode-hook' or `ess-post-run-hook', or one of the more
|
||||
specialized hooks `ess-r-post-run-hook',`ess-stata-post-run-hook'
|
||||
etc.")
|
||||
|
||||
(defun ess--idle-timer-function nil
|
||||
"Internal function executed by `ess--idle-timer'."
|
||||
(run-hooks 'ess-idle-timer-functions))
|
||||
|
||||
(require 'timer)
|
||||
(defvar ess--idle-timer
|
||||
(run-with-idle-timer ess-idle-timer-interval 'repeat 'ess--idle-timer-function)
|
||||
"Timer used to run `ess-idle-timer-functions'.")
|
||||
|
||||
|
||||
;;; Dispatch on ess-dialect
|
||||
;; Inspired by major-mode specializer in cl-generic.el
|
||||
|
||||
;; FIXME: Implement a notion of derived dialects. major-mode specializer cannot
|
||||
;; be used here as we need same dialect in different major-modes.
|
||||
|
||||
;; Two parts:
|
||||
;; 1) first define a specializer (ess-dialect= DIALECT) to match symbols
|
||||
;; representing ess dialects.
|
||||
;; 2) then define a context-rewriter so you can write
|
||||
;; `&context (ess-dialect "R")` rather than
|
||||
;; `&context (ess-dialect (ess-dialect= "R"))`.
|
||||
|
||||
(cl-generic-define-generalizer ess--generic-dialect-generalizer
|
||||
95
|
||||
(lambda (name &rest _) `(if (stringp ,name) (intern ,name)
|
||||
(if (symbolp ,name) ,name)))
|
||||
(lambda (tag &rest _) `((ess-dialect= ,tag))))
|
||||
|
||||
(cl-defmethod cl-generic-generalizers ((_specializer (head ess-dialect=)))
|
||||
"Support for (ess-dialect DIALECT) context specializer."
|
||||
(list ess--generic-dialect-generalizer))
|
||||
|
||||
(cl-generic-define-context-rewriter ess-dialect (dialect)
|
||||
`(ess-dialect (ess-dialect= ,(if (stringp dialect)
|
||||
(intern dialect)
|
||||
dialect))))
|
||||
|
||||
;; (cl-defgeneric ess-print-dialect ()
|
||||
;; (error "unknown dialect %s" ess-dialect))
|
||||
;; (cl-defmethod ess-print-dialect (&context (ess-dialect "R"))
|
||||
;; (message "dialect: R"))
|
||||
;; (cl-defmethod ess-print-dialect (&context (ess-dialect "julia"))
|
||||
;; (message "dialect: julia"))
|
||||
|
||||
(provide 'ess)
|
||||
|
||||
;;; ess.el ends here
|
||||
5032
lisp/ess/ess.info
Normal file
5032
lisp/ess/ess.info
Normal file
File diff suppressed because it is too large
Load Diff
185
lisp/ess/essd-els.el
Normal file
185
lisp/ess/essd-els.el
Normal file
@@ -0,0 +1,185 @@
|
||||
;;; essd-els.el --- S-PLUS 3.x at another location customization -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1998-2020 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Richard M. Heiberger <rmh@temple.edu>
|
||||
;; Created: December 1998
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file defines all the S-PLUS 3.x customizations for ess-mode.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ess-r-mode)
|
||||
(require 'ess-sp6-d)
|
||||
(require 'ess-sas-d)
|
||||
(require 'ess-trns)
|
||||
(require 'ess-utils)
|
||||
(defvar ess-julia-customize-alist)
|
||||
|
||||
;; Easily changeable in a user's .emacs
|
||||
(defvar S+elsewhere-dialect-name "S+6"
|
||||
"Name of 'dialect' for S-PLUS at another location.")
|
||||
|
||||
(defvar S+elsewhere-start-args "-i"
|
||||
"Arguments for `S+elsewhere-dialect-name'.")
|
||||
|
||||
(defcustom inferior-ess-remote-pager nil
|
||||
"Remote pager to use for reporting help files and similar things.
|
||||
The default value is nil."
|
||||
:group 'ess-proc
|
||||
:type '(choice (const nil) string))
|
||||
|
||||
|
||||
(defvar S+elsewhere-customize-alist
|
||||
(append
|
||||
'((ess-local-customize-alist . 'S+elsewhere-customize-alist)
|
||||
(ess-dialect . S+elsewhere-dialect-name)
|
||||
(ess-object-name-db-file . "ess-spelsewhere-namedb.el" )
|
||||
(inferior-ess-program . inferior-S-elsewhere-program)
|
||||
(inferior-ess-help-command . "help(\"%s\", pager=\"cat\", window=F)\n")
|
||||
(ess-STERM . "iESS")
|
||||
)
|
||||
S+common-cust-alist)
|
||||
"Variables to customize for S+elsewhere.")
|
||||
|
||||
(defun S+elsewhere (&optional _proc-name)
|
||||
"Call 'S-PLUS 3.x', the 'Real Thing' from StatSci."
|
||||
;; git commit 104c4d7c56bc239ea245562763caa317bc3a1a84
|
||||
(declare (obsolete ess-remote "2000"))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "\n(S+elsewhere): ess-dialect=%s, buf=%s\n" ess-dialect
|
||||
(current-buffer)))
|
||||
(let ((inf-buf (inferior-ess nil S+elsewhere-customize-alist)))
|
||||
(when inferior-ess-language-start
|
||||
(ess-eval-linewise inferior-ess-language-start))
|
||||
inf-buf))
|
||||
|
||||
(defun S+elsewhere-mode (&optional _proc-name)
|
||||
"Major mode for editing S+3 source. See `ess-mode' for more help."
|
||||
(declare (obsolete ess-remote "2000"))
|
||||
(setq-local ess-local-customize-alist S+elsewhere-customize-alist)
|
||||
(ess-mode))
|
||||
|
||||
(define-obsolete-function-alias 'S+elsewhere-transcript-mode #'S-transcript-mode "2000")
|
||||
|
||||
;; This REALLY shouldn't need an editing mode. Just a transcript and
|
||||
;; an inferior process handler.
|
||||
|
||||
(defun ess-select-alist-dialect (&optional dialect)
|
||||
"Query user for an ESS DIALECT and return the matching customize-alist."
|
||||
(interactive)
|
||||
(let* ((dialects '("R" "S+" "julia" "s3" "s4"
|
||||
"sp3" "sp4" "sqpe4" "sp5" "sqpe" "SAS"))
|
||||
(dialect (or dialect
|
||||
(ess-completing-read "Dialect" dialects nil t))))
|
||||
(cond
|
||||
((string= dialect "julia") (progn (require 'julia-mode)
|
||||
ess-julia-customize-alist))
|
||||
((string= dialect "R") ess-r-customize-alist)
|
||||
((string= dialect "SAS") SAS-customize-alist)
|
||||
(t S+elsewhere-customize-alist))))
|
||||
|
||||
(defun ess-add-ess-process ()
|
||||
"Execute this command from within a buffer running a process to add
|
||||
the process to `ess-process-name-alist' and to make it the
|
||||
`ess-current-process-name'. This command will normally be run in a
|
||||
telnet buffer connected to another computer or in a shell or comint
|
||||
buffer on the local computer."
|
||||
(interactive)
|
||||
(let ((proc (get-buffer-process (buffer-name))))
|
||||
(if (not proc)
|
||||
(error "No process is associated with this buffer")
|
||||
(set-process-filter proc 'inferior-ess-output-filter)
|
||||
(setq ess-current-process-name (process-name proc))
|
||||
(add-to-list 'ess-process-name-list
|
||||
(list ess-current-process-name)))))
|
||||
|
||||
(defvar ess-remote nil
|
||||
"Indicator, t in remote buffers.")
|
||||
|
||||
;;;###autoload
|
||||
(defun ess-remote (&optional proc-name dialect)
|
||||
"Execute this command from within a buffer running a process.
|
||||
It runs `ess-add-ess-process' to add the PROC-NAME to
|
||||
`ess-process-name-alist' and to make it the
|
||||
`ess-current-process-name'. It then prompts the user for an ESS
|
||||
language and sets the editing characteristics appropriately.
|
||||
|
||||
To use this command, first start a process on a remote computer by
|
||||
manual use of telnet, rlogin, ssh, or some other protocol. Start the
|
||||
relevant program (\"S\" or \"R\" or \"sas -stdio\") in that buffer. Once
|
||||
you are talking to S or R or SAS, then do \\[ess-remote] to make
|
||||
the current buffer an inferior-ess buffer with the right behavior for
|
||||
the language you are currently working with. With S and R, use C-c
|
||||
C-n to send lines over. With SAS, use C-c i
|
||||
`ess-eval-line-and-step-invisibly' to send lines over invisibly.
|
||||
|
||||
DIALECT is the desired ess-dialect. If nil, ask for dialect"
|
||||
|
||||
(interactive)
|
||||
(ess-add-ess-process)
|
||||
;; Need to select a remote-customize-alist
|
||||
(let ((customize-alist (ess-select-alist-dialect dialect)))
|
||||
(ess-write-to-dribble-buffer
|
||||
(format "\n(ESS-remote): ess-dialect=%s, buf=%s\n" ess-dialect
|
||||
(current-buffer)))
|
||||
(ess-setq-vars-local customize-alist)
|
||||
(inferior-ess--set-major-mode ess-dialect)
|
||||
(setq-local ess-remote t)
|
||||
(setq ess-local-process-name (or proc-name ess-current-process-name))
|
||||
|
||||
(goto-char (point-max))
|
||||
|
||||
(when (equal ess-dialect "R")
|
||||
;; ugly fix for evn variable. What can we do :(
|
||||
(ess-eval-linewise (format "options(pager='%s')\n"
|
||||
(or inferior-ess-remote-pager inferior-ess-pager))
|
||||
nil nil nil 'wait)
|
||||
(ess-r-load-ESSR))
|
||||
|
||||
(when (equal ess-dialect "S+")
|
||||
(ess-command ess-S+--injected-code))
|
||||
|
||||
(when (equal ess-language "SAS")
|
||||
(font-lock-mode 0)
|
||||
(SAS-log-mode)
|
||||
(shell-mode)
|
||||
(setq buffer-read-only nil)
|
||||
(font-lock-mode 1))
|
||||
|
||||
(ess-process-put 'funargs-cache (make-hash-table :test 'equal))
|
||||
(ess-process-put 'funargs-pre-cache nil)
|
||||
;; auto-complete
|
||||
(ess--setup-auto-complete ess-r-ac-sources t)
|
||||
;; company
|
||||
(ess--setup-company ess-r-company-backends t)
|
||||
|
||||
(when inferior-ess-language-start
|
||||
(ess-eval-linewise inferior-ess-language-start
|
||||
nil nil nil 'wait-prompt))))
|
||||
|
||||
|
||||
; Provide package
|
||||
|
||||
(provide 'essd-els)
|
||||
|
||||
;;; essd-els.el ends here
|
||||
BIN
lisp/ess/etc/ESSR.rds
Normal file
BIN
lisp/ess/etc/ESSR.rds
Normal file
Binary file not shown.
10
lisp/ess/etc/ESSR/BUILDESSR
Executable file
10
lisp/ess/etc/ESSR/BUILDESSR
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/Rscript
|
||||
## -*- mode: R -*-
|
||||
## code to build ESSR environemnt.
|
||||
## Assume that current directory is etc/ESSR
|
||||
## run "./BUILDESSR" to create ../ESSR.rda
|
||||
|
||||
## exactly as in inferior-ess-r-load-ESSR in ess-r-d.el
|
||||
source('./R/.load.R', local=TRUE)
|
||||
ESSR <- .ess.load.ESSR('./R/')
|
||||
saveRDS(ESSR, file = "../ESSR.rds")
|
||||
24
lisp/ess/etc/ESSR/LOADREMOTE
Normal file
24
lisp/ess/etc/ESSR/LOADREMOTE
Normal file
@@ -0,0 +1,24 @@
|
||||
## -*- mode: R -*-
|
||||
## loading code which is first sent to R on remote sessions
|
||||
local({
|
||||
ver <- '%s' ## <- passed from elisp
|
||||
root <- '~/.config/ESSR'
|
||||
if(!file.exists(root))
|
||||
dir.create(root, recursive = TRUE)
|
||||
## cannot use sprintf here
|
||||
essr_file <- file.path(root, paste('ESSRv', ver, '.rds', sep = ''))
|
||||
tryCatch({
|
||||
if(!file.exists(essr_file)) {
|
||||
url <- paste('https://github.com/emacs-ess/ESS/raw/ESSRv', ver, '/etc/ESSR.rds', sep = '')
|
||||
utils::download.file(url, essr_file)
|
||||
}
|
||||
ESSR <- readRDS(essr_file)
|
||||
ESSR[[".ess.Rversion"]] <- ESSR[[".ess.getRversion"]]()
|
||||
attach(ESSR)
|
||||
print(TRUE)
|
||||
},
|
||||
error = function(e) {
|
||||
print(e)
|
||||
print(FALSE)
|
||||
})
|
||||
})
|
||||
134
lisp/ess/etc/ESSR/R/.basic.R
Normal file
134
lisp/ess/etc/ESSR/R/.basic.R
Normal file
@@ -0,0 +1,134 @@
|
||||
#### Essential functionality needed by ESS
|
||||
|
||||
## Should work on *all* vesions of R.
|
||||
## Do not use _ in names, nor :: , nor 1L etc, as they
|
||||
## cannot be parsed in old R versions
|
||||
|
||||
.ess.getRversion <- function() {
|
||||
if(exists("getRversion", mode="function")) getRversion()
|
||||
else paste(R.version$major, R.version$minor, sep=".")
|
||||
}
|
||||
|
||||
## loading ESSR.rda might fail, so re-assign here:
|
||||
.ess.Rversion <- .ess.getRversion()
|
||||
|
||||
.ess.R.has.utils <- (.ess.Rversion >= "1.9.0")
|
||||
.ess.utils.name <- paste("package",
|
||||
if(.ess.Rversion >= "1.9.0") "utils" else "base",
|
||||
sep = ":")
|
||||
|
||||
## Instead of modern utils::help use one that works in R 1.0.0:
|
||||
.ess.findFUN <- get("find", .ess.utils.name)
|
||||
|
||||
|
||||
### HELP
|
||||
.ess.help <- function(..., help.type = getOption("help_type")) {
|
||||
if (is.null(help.type)) {
|
||||
help.type <- "text"
|
||||
}
|
||||
|
||||
## - get("help", ..) searching in global env works with devtools redefines
|
||||
## - Redefining to .ess.help this way is necessary because
|
||||
## utils:::print.help_files_with_topic (used internally when there's
|
||||
## more than one a package) uses the quoted call
|
||||
## MM: don't understand; more specifically?
|
||||
.ess.help <- function(...) {
|
||||
do.call(get("help", envir = .GlobalEnv), list(...))
|
||||
}
|
||||
|
||||
if (.ess.Rversion > "2.10") {
|
||||
## Abbreviating help_type to avoid underscore
|
||||
.ess.help(..., help = help.type)
|
||||
} else {
|
||||
.ess.help(..., htmlhelp = help.type == "html")
|
||||
}
|
||||
}
|
||||
|
||||
.ess.getHelpAliases <- function(){
|
||||
readrds <-
|
||||
if(.ess.Rversion >= '2.13.0') readRDS
|
||||
else .readRDS
|
||||
rds.files <- paste(searchpaths(), "/help/aliases.rds", sep = "")
|
||||
unlist(lapply(rds.files,
|
||||
function(f){
|
||||
if( file.exists(f) )
|
||||
try(names(readrds(f)))
|
||||
}),
|
||||
use.names = FALSE)
|
||||
}
|
||||
|
||||
### SOURCING
|
||||
.ess.eval <- function(string, visibly = TRUE, output = FALSE,
|
||||
max.deparse.length = 300,
|
||||
file = tempfile("ESS"), local = NULL)
|
||||
{
|
||||
if (is.null(local)) {
|
||||
local <- if (.ess.Rversion > '2.13') parent.frame() else FALSE
|
||||
}
|
||||
|
||||
## create FILE, put string into it. Then source.
|
||||
## arguments are like in source and .ess.source
|
||||
cat(string, file = file)
|
||||
## The following on.exit infloops in R 3.3.0
|
||||
## https://github.com/emacs-ess/ESS/issues/334
|
||||
## https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16971
|
||||
## So we are cleanning it in .ess.source instead.
|
||||
## on.exit(file.remove(file))
|
||||
.ess.source(file, visibly = visibly, output = output,
|
||||
max.deparse.length = max.deparse.length,
|
||||
local = local, fake.source = TRUE)
|
||||
}
|
||||
|
||||
.ess.strip.error <- function(msg, srcfile) {
|
||||
pattern <- paste0(srcfile, ":[0-9]+:[0-9]+: ")
|
||||
sub(pattern, "", msg)
|
||||
}
|
||||
|
||||
.ess.file.remove <- function(file){
|
||||
if (base::file.exists(file)) base::file.remove(file)
|
||||
else FALSE
|
||||
}
|
||||
|
||||
.ess.source <- function(file, visibly = TRUE, output = FALSE,
|
||||
max.deparse.length = 300, local = NULL,
|
||||
fake.source = FALSE, keep.source = TRUE,
|
||||
message.prefix = "") {
|
||||
if (is.null(local)) {
|
||||
local <- if (.ess.Rversion > "2.13")
|
||||
parent.frame()
|
||||
else FALSE
|
||||
}
|
||||
|
||||
ss <-
|
||||
if (.ess.Rversion >= "3.4")
|
||||
base::source
|
||||
else if (.ess.Rversion >= "2.8")
|
||||
function(..., spaced) base::source(...)
|
||||
else function(..., spaced, keep.source) base::source(...)
|
||||
|
||||
on.exit({
|
||||
if (fake.source)
|
||||
.ess.file.remove(file)
|
||||
})
|
||||
|
||||
out <- ss(file, echo = visibly, local = local, print.eval = output, spaced = FALSE,
|
||||
max.deparse.length = max.deparse.length, keep.source = keep.source)
|
||||
|
||||
if(!fake.source)
|
||||
cat(sprintf("%sSourced file %s\n", message.prefix, file))
|
||||
|
||||
## Return value for org-babel
|
||||
invisible(out$value)
|
||||
}
|
||||
|
||||
if(.ess.Rversion < "1.8")
|
||||
## (works for "1.7.2"): bquote() was new in 1.8.0
|
||||
bquote <- function(expr, where=parent.frame()){
|
||||
unquote <- function(e)
|
||||
if (is.pairlist(e)) as.pairlist(lapply(e, unquote))
|
||||
else if (length(e) <= 1) e
|
||||
else if (e[[1]] == as.name(".")) eval(e[[2]], where)
|
||||
else as.call(lapply(e, unquote))
|
||||
|
||||
unquote(substitute(expr))
|
||||
}
|
||||
53
lisp/ess/etc/ESSR/R/.load.R
Normal file
53
lisp/ess/etc/ESSR/R/.load.R
Normal file
@@ -0,0 +1,53 @@
|
||||
## This file is sourced when R starts and `load.ESSR` is called. See
|
||||
## inferior-ess-r-load-ESSR--local.
|
||||
## Do not use _ in names, nor :: as they cannot be parsed in old R versions
|
||||
|
||||
## load .base.R and all other files into ESSR environment; then attach ESSR
|
||||
.ess.load.ESSR <- function(dir) {
|
||||
.source <-
|
||||
if(any("keep.source" == names(formals(sys.source))))
|
||||
sys.source
|
||||
else
|
||||
function(..., keep.source) sys.source(...)
|
||||
|
||||
Rver <- if(exists("getRversion", mode="function")) getRversion()
|
||||
else paste(R.version$major, R.version$minor, sep=".")
|
||||
oldR <- Rver <= "1.3.0"
|
||||
|
||||
ESSR <-
|
||||
if(oldR) ## really old library() revert order a bit
|
||||
attach(NULL, name = "ESSR")
|
||||
else if(length(nn <- names(formals(new.env))) && any(nn == "parent"))
|
||||
new.env(parent =
|
||||
if(Rver >= "1.9.0") getNamespace("utils")
|
||||
else .BaseNamespaceEnv)
|
||||
else
|
||||
new.env()
|
||||
|
||||
assign(".ess.Rversion", Rver, envir = ESSR)
|
||||
|
||||
## updated by make !!
|
||||
VERSION <- "1.6"
|
||||
assign(".ess.ESSRversion", VERSION, envir = ESSR)
|
||||
|
||||
|
||||
## .basic.R:
|
||||
try(.source(paste(dir,'/.basic.R', sep = ""), envir = ESSR, keep.source = FALSE))
|
||||
|
||||
## all others try(*) as it will fail in old R
|
||||
if(!oldR) # no sense if(oldR)
|
||||
for( f in dir(dir, pattern='\\.R$', full.names=TRUE) )
|
||||
try(.source(f, envir = ESSR, keep.source = FALSE))
|
||||
|
||||
if(Rver >= "2.4.0")
|
||||
attach(ESSR)
|
||||
else if(!oldR) { ## borrow from older library()
|
||||
e <- attach(NULL, name = "ESSR")
|
||||
.Internal(lib.fixup(ESSR, e))
|
||||
} else { ## if(oldR), use as in that old library():
|
||||
.Internal(lib.fixup(ESSR, .GlobalEnv))
|
||||
}
|
||||
|
||||
## BUILDESSR needs this:
|
||||
invisible(ESSR)
|
||||
}
|
||||
168
lisp/ess/etc/ESSR/R/completion.R
Normal file
168
lisp/ess/etc/ESSR/R/completion.R
Normal file
@@ -0,0 +1,168 @@
|
||||
## Do *NOT* use 1L -- it gives parse errors in historical versions of R
|
||||
|
||||
## Try a setup working in as old R as possible.
|
||||
## ===>
|
||||
## 1) do not use "_" in names! --- seems impossible for the Millenials ..
|
||||
## 2) use our own simplified definition of '::' and ':::' ?
|
||||
##
|
||||
if(!exists("local"))
|
||||
local <- function(expr, envir = environment()) { invisible(eval(expr, envir=envir)) }
|
||||
|
||||
##' Robust version of
|
||||
##' utils:::.addFunctionInfo(c = c("recursive", "use.names"))
|
||||
local({
|
||||
U <- asNamespace("utils"); fn <- ".addFunctionInfo"
|
||||
EX <- exists(fn, envir=U)
|
||||
if(EX && is.function(FN <- get(fn, envir=U))) {
|
||||
FN(c = c("recursive", "use.names")); ##dbg: cat("Calling utils:::",fn,"(c = ...)\n")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
.ess_eval <- function(str, env = globalenv()) {
|
||||
## don't remove; really need eval(parse( here!!
|
||||
tryCatch(eval(parse(text=str), envir = env),
|
||||
error=function(e) NULL) ## also works for special objects containing @:$ etc
|
||||
}
|
||||
|
||||
.ess_nonull <- function(x, default = "") {
|
||||
if (is.null(x)) default
|
||||
else x
|
||||
}
|
||||
|
||||
.ess_srcref <- function(name, pkg) {
|
||||
if (!is.null(pkg) && requireNamespace(pkg)) {
|
||||
env <- asNamespace(pkg)
|
||||
} else {
|
||||
env <- globalenv()
|
||||
}
|
||||
fn <- .ess_eval(name, env)
|
||||
if (is.null(fn)) {
|
||||
objs <- utils::getAnywhere(name)$objs
|
||||
for (o in objs) {
|
||||
if (is.function(o)) {
|
||||
fn <- o
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
out <- "()\n"
|
||||
if (is.function(fn) && !is.null(utils::getSrcref(fn))) {
|
||||
file <- utils::getSrcFilename(fn, full.names = TRUE)
|
||||
if (file != "") {
|
||||
line <- .ess_nonull(utils::getSrcLocation(fn, "line"), 1)
|
||||
col <- .ess_nonull(utils::getSrcLocation(fn, "column"), 1)
|
||||
out <- sprintf("(\"%s\" %d %d)\n", file, line, col - 1)
|
||||
}
|
||||
}
|
||||
cat(out)
|
||||
}
|
||||
|
||||
|
||||
.ess_fn_pkg <- function(fn_name) {
|
||||
objs <- utils::getAnywhere(fn_name)
|
||||
print(sub("(package|namespace):", "", objs$where))
|
||||
}
|
||||
|
||||
.ess_funargs <- function(funname) {
|
||||
if(.ess.Rversion > '2.14.1') {
|
||||
## temporarily disable JIT compilation and errors
|
||||
comp <- compiler::enableJIT(0)
|
||||
op <- options(error=NULL)
|
||||
on.exit({ options(op); compiler::enableJIT(comp) })
|
||||
}
|
||||
fun <- .ess_eval(funname)
|
||||
if(is.function(fun)) {
|
||||
special <- grepl('[:$@[]', funname)
|
||||
args <- if(!special){
|
||||
fundef <- paste(funname, '.default',sep='')
|
||||
do.call('argsAnywhere', list(fundef))
|
||||
}
|
||||
|
||||
if(is.null(args))
|
||||
args <- args(fun)
|
||||
if(is.null(args))
|
||||
args <- do.call('argsAnywhere', list(funname))
|
||||
|
||||
fmls <- formals(args)
|
||||
fmls_names <- names(fmls)
|
||||
fmls <- gsub('\"', '\\\"',
|
||||
gsub("\\", "\\\\", as.character(fmls), fixed = TRUE),
|
||||
fixed=TRUE)
|
||||
args_alist <-
|
||||
sprintf("'(%s)",
|
||||
paste("(\"", fmls_names, "\" . \"", fmls, "\")",
|
||||
sep = '', collapse = ' '))
|
||||
allargs <-
|
||||
if (special) fmls_names
|
||||
else tryCatch(gsub(' ?= ?', '', utils:::functionArgs(funname, ''), fixed = FALSE),
|
||||
error=function(e) NULL)
|
||||
allargs <- sprintf("'(\"%s\")",
|
||||
paste(allargs, collapse = '\" "'))
|
||||
envname <-
|
||||
if (is.primitive(fun)) "base"
|
||||
else environmentName(environment(fun))
|
||||
if (envname == "R_GlobalEnv") envname <- ""
|
||||
cat(sprintf('(list \"%s\" %s %s)\n',
|
||||
envname, args_alist, allargs))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ess_get_completions <- function(string, end, suffix = " = ") {
|
||||
oldopts <- utils::rc.options(funarg.suffix = suffix)
|
||||
on.exit(utils::rc.options(oldopts))
|
||||
if(.ess.Rversion > '2.14.1'){
|
||||
comp <- compiler::enableJIT(0)
|
||||
op <- options(error=NULL)
|
||||
on.exit({ options(op); compiler::enableJIT(comp)}, add = TRUE)
|
||||
}
|
||||
utils:::.assignLinebuffer(string)
|
||||
utils:::.assignEnd(end)
|
||||
utils:::.guessTokenFromLine()
|
||||
utils:::.completeToken()
|
||||
c(get('token', envir=utils:::.CompletionEnv),
|
||||
utils:::.retrieveCompletions())
|
||||
}
|
||||
|
||||
.ess_arg_help <- function(arg, func){
|
||||
op <- options(error=NULL)
|
||||
on.exit(options(op))
|
||||
fguess <-
|
||||
if(is.null(func)) get('fguess', envir=utils:::.CompletionEnv)
|
||||
else func
|
||||
findArgHelp <- function(fun, arg){
|
||||
file <- help(fun, try.all.packages=FALSE)[[1]]
|
||||
hlp <- utils:::.getHelpFile(file)
|
||||
id <- grep('arguments', tools:::RdTags(hlp), fixed=TRUE)
|
||||
if(length(id)){
|
||||
arg_section <- hlp[[id[[1]]]]
|
||||
items <- grep('item', tools:::RdTags(arg_section), fixed=TRUE)
|
||||
## cat('items:', items, fill=TRUE)
|
||||
if(length(items)){
|
||||
arg_section <- arg_section[items]
|
||||
args <- unlist(lapply(arg_section,
|
||||
function(el) paste(unlist(el[[1]][[1]], TRUE, FALSE), collapse='')))
|
||||
fits <- grep(arg, args, fixed=TRUE)
|
||||
## cat('args', args, 'fits', fill=TRUE)
|
||||
if(length(fits))
|
||||
paste(unlist(arg_section[[fits[1]]][[2]], TRUE, FALSE), collapse='')
|
||||
}
|
||||
}
|
||||
}
|
||||
funcs <- c(fguess, tryCatch(methods(fguess),
|
||||
warning=function(w) {NULL},
|
||||
error=function(e) {NULL}))
|
||||
if(length(funcs) > 1 && length(pos <- grep('default', funcs))){
|
||||
funcs <- c(funcs[[pos[[1]]]], funcs[-pos[[1]]])
|
||||
}
|
||||
i <- 1; found <- FALSE
|
||||
out <- 'No help found'
|
||||
while(i <= length(funcs) && is.null(out <-
|
||||
tryCatch(findArgHelp(funcs[[i]], arg),
|
||||
warning=function(w) {NULL},
|
||||
error=function(e) {NULL})
|
||||
))
|
||||
i <- i + 1
|
||||
cat('\n\n', as.character(out), '\n')
|
||||
}
|
||||
227
lisp/ess/etc/ESSR/R/debug.R
Normal file
227
lisp/ess/etc/ESSR/R/debug.R
Normal file
@@ -0,0 +1,227 @@
|
||||
### BREAKPOINTS
|
||||
.ESSBP. <- new.env()
|
||||
|
||||
### DEBUG/UNDEBUG
|
||||
.ess_find_funcs <- function(env) {
|
||||
objs <- ls(envir = env, all.names = TRUE)
|
||||
if (length(objs) > 0)
|
||||
objs <- objs[sapply(objs, exists, envir = env,
|
||||
mode = 'function', inherits = FALSE)]
|
||||
objs
|
||||
}
|
||||
|
||||
.ess_all_functions <- function(packages = c(), env = NULL) {
|
||||
if(is.null(env))
|
||||
env <- parent.frame()
|
||||
empty <- emptyenv()
|
||||
coll <- list()
|
||||
for(p in packages){
|
||||
## package might not be attached
|
||||
try(
|
||||
{
|
||||
objNS <- .ess_find_funcs(asNamespace(p))
|
||||
objPKG <- .ess_find_funcs(as.environment(paste0('package:', p)))
|
||||
objNS <- setdiff(objNS, objPKG)
|
||||
if(length(objPKG))
|
||||
coll[[length(coll) + 1]] <- paste0(p, ':::', objNS)
|
||||
}, silent = TRUE)
|
||||
}
|
||||
while(!identical(empty, env)){
|
||||
coll[[length(coll) + 1]] <- .ess_find_funcs(env)
|
||||
env <- parent.env(env)
|
||||
}
|
||||
grep('^\\.ess', unlist(coll, use.names = FALSE),
|
||||
invert = TRUE, value = TRUE)
|
||||
}
|
||||
|
||||
|
||||
.ess_dbg_flag_for_debuging <- function(fname){
|
||||
all <- utils::getAnywhere(fname)
|
||||
if(length(all$obj) == 0){
|
||||
msg <- sprintf("No functions names '%s' found", fname)
|
||||
} else {
|
||||
msg <- sprintf("Flagged '%s' for debugging", fname)
|
||||
tryCatch(lapply(all$obj, debug),
|
||||
error = function(e){
|
||||
msg <- paste0("Error: ", e$message)
|
||||
})
|
||||
}
|
||||
cat(msg)
|
||||
.ess_mpi_message(msg)
|
||||
}
|
||||
|
||||
.ess_dbg_getTracedAndDebugged <- function()
|
||||
{
|
||||
packages <- base::.packages()
|
||||
tr_state <- tracingState(FALSE)
|
||||
on.exit(tracingState(tr_state))
|
||||
generics <- methods::getGenerics()
|
||||
all_traced <- c()
|
||||
for(i in seq_along(generics)){
|
||||
genf <- methods::getGeneric(generics[[i]],
|
||||
package=generics@package[[i]])
|
||||
if(!is.null(genf)){ ## might happen !! v.2.13
|
||||
menv <- methods::getMethodsForDispatch(genf)
|
||||
traced <- unlist(eapply(menv, is, 'traceable', all.names=TRUE))
|
||||
if(length(traced) && any(traced))
|
||||
all_traced <- c(paste(generics[[i]],':',
|
||||
names(traced)[traced],sep=''), all_traced)
|
||||
tfn <- getFunction(generics[[i]], mustFind=FALSE, where = .GlobalEnv)
|
||||
if(!is.null(tfn ) && is(tfn, 'traceable')) # if the default is traced, it does not appear in the menv :()
|
||||
all_traced <- c(generics[[i]], all_traced)
|
||||
}
|
||||
}
|
||||
debugged_pkg <- unlist(lapply(packages, function(pkgname){
|
||||
ns <- asNamespace(pkgname)
|
||||
funcs <- .ess_find_funcs(ns)
|
||||
dbged <- funcs[unlist(lapply(funcs,
|
||||
function(f){
|
||||
isdebugged(get(f, envir = ns, inherits = FALSE))
|
||||
}))]
|
||||
if(length(dbged))
|
||||
paste0(pkgname, ':::`', dbged, '`')
|
||||
}))
|
||||
env <- parent.frame()
|
||||
## traced function don't appear here. Not realy needed and would affect performance.
|
||||
all <- .ess_all_functions(packages = packages, env = env)
|
||||
which_deb <- lapply(all, function(nm){
|
||||
## if isdebugged is called with string it doess find
|
||||
tryCatch(isdebugged(get(nm, envir = env)),
|
||||
error = function(e) FALSE)
|
||||
## try(eval(substitute(isdebugged(nm), list(nm = as.name(nm)))), silent = T)
|
||||
})
|
||||
debugged <- all[which(unlist(which_deb, recursive=FALSE, use.names=FALSE))]
|
||||
unique(c(debugged_pkg, debugged, all_traced))
|
||||
}
|
||||
|
||||
|
||||
.ess_dbg_UntraceOrUndebug <- function(name, env = parent.frame()) {
|
||||
tr_state <- tracingState(FALSE)
|
||||
on.exit(tracingState(tr_state))
|
||||
if( grepl('::', name) ){
|
||||
## foo:::bar name
|
||||
eval(parse(text = sprintf('undebug(%s)', name)))
|
||||
}else{
|
||||
## name is a name of a function to be undebugged or has a form
|
||||
## name:Class1#Class2#Class3 for traced methods
|
||||
name <- strsplit(name, ':', fixed = TRUE)[[1]]
|
||||
if( length(name)>1 ){
|
||||
## a method
|
||||
fun <- name[[1]]
|
||||
sig <- strsplit(paste(name[-1], collapse=''), '#', fixed=TRUE)[[1]]
|
||||
untrace(fun, signature = sig)
|
||||
}else{
|
||||
## function
|
||||
if( is(getFunction(name, where = parent.frame()), 'traceable') )
|
||||
untrace(name)
|
||||
else if(grepl(":", name))
|
||||
undebug(name)
|
||||
else
|
||||
undebug(get(name, envir = env))
|
||||
}}
|
||||
}
|
||||
|
||||
.ess_dbg_UndebugALL <- function(funcs)
|
||||
{
|
||||
tr_state <- tracingState(FALSE)
|
||||
on.exit(tracingState(tr_state))
|
||||
env <- parent.frame()
|
||||
invisible(lapply(funcs, function( nm ) {
|
||||
## ugly tryCatch, but there might be several names pointing to the
|
||||
## same function, like foo:::bar and bar. An alternative would be
|
||||
## to call .ess_dbg_getTracedAndDebugged each time but that might
|
||||
## be ery slow
|
||||
try(.ess_dbg_UntraceOrUndebug(nm, env = env), TRUE)
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
### WATCH
|
||||
.ess_watch_expressions <- list()
|
||||
|
||||
.ess_watch_eval <- function()
|
||||
{
|
||||
env <- as.environment("ESSR")
|
||||
exps <- get('.ess_watch_expressions', envir = env)
|
||||
if(length(exps) == 0) {
|
||||
## using old style so this can be parsed by R 1.9.1 (e.g):
|
||||
cat('\n# Watch list is empty!\n',
|
||||
'# a append new expression',
|
||||
'# i insert new expression',
|
||||
'# k kill',
|
||||
'# e edit the expression',
|
||||
'# r rename',
|
||||
'# n/p navigate',
|
||||
'# u/d,U move the expression up/down',
|
||||
'# q kill the buffer',
|
||||
sep="\n")
|
||||
} else {
|
||||
.parent_frame <- parent.frame()
|
||||
.essWEnames <- allNames(exps)
|
||||
len0p <- !nzchar(.essWEnames)
|
||||
.essWEnames[len0p] <- seq_along(len0p)[len0p]
|
||||
for(i in seq_along(exps)) {
|
||||
cat('\n@---- ', .essWEnames[[i]], ' ',
|
||||
rep.int('-', max(0, 35 - nchar(.essWEnames[[i]]))), '-@\n', sep = '')
|
||||
cat(paste('@---:', deparse(exps[[i]][[1]])), ' \n', sep = '')
|
||||
tryCatch(print(eval(exps[[i]],
|
||||
envir = .parent_frame)),
|
||||
error = function(e) cat('Error:', e$message, '\n' ),
|
||||
warning = function(w) cat('warning: ', w$message, '\n' ))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ess_watch_assign_expressions <- function(elist) {
|
||||
assign(".ess_watch_expressions", elist, envir = as.environment("ESSR"))
|
||||
}
|
||||
|
||||
.ess_log_eval <- function(log_name) {
|
||||
env <- as.environment("ESSR")
|
||||
if(!exists(log_name, envir = env, inherits = FALSE))
|
||||
assign(log_name, list(), envir = env)
|
||||
log <- get(log_name, envir = env, inherits = FALSE)
|
||||
.essWEnames <- allNames(.ess_watch_expressions)
|
||||
cur_log <- list()
|
||||
.parent_frame <- parent.frame()
|
||||
for(i in seq_along(.ess_watch_expressions)) {
|
||||
capture.output( {
|
||||
cur_log[[i]] <-
|
||||
tryCatch(eval(.ess_watch_expressions[[i]]),
|
||||
envir = .parent_frame,
|
||||
error = function(e) paste('Error:', e$message, '\n'),
|
||||
warning = function(w) paste('warning: ', w$message, '\n'))
|
||||
if(is.null(cur_log[i][[1]]))
|
||||
cur_log[i] <- list(NULL)
|
||||
})
|
||||
}
|
||||
names(cur_log) <- .essWEnames
|
||||
assign(log_name, c(log, list(cur_log)), envir = env)
|
||||
invisible(NULL)
|
||||
}
|
||||
|
||||
|
||||
.ess_package_attached <- function(pack_name){
|
||||
as.logical(match(paste0("package:", pack_name), search()))
|
||||
}
|
||||
|
||||
## magrittr debug_pipe
|
||||
.ess_pipe_browser <- function(x){
|
||||
if(is.list(x))
|
||||
evalq({
|
||||
browser(skipCalls = 2)
|
||||
x
|
||||
}, envir = x)
|
||||
else if(is.environment(x))
|
||||
## enclos argumentn has no effect for unclear reason, need to hack
|
||||
eval(bquote({
|
||||
x <- .(environment())
|
||||
browser(skipCalls = 2)
|
||||
x
|
||||
}), envir = x)
|
||||
else {
|
||||
browser(skipCalls = 0)
|
||||
x
|
||||
}
|
||||
}
|
||||
143
lisp/ess/etc/ESSR/R/misc.R
Normal file
143
lisp/ess/etc/ESSR/R/misc.R
Normal file
@@ -0,0 +1,143 @@
|
||||
.ess_weave <- function(command, file, encoding = NULL){
|
||||
cmd_symb <- substitute(command)
|
||||
if (grepl('knit|purl', deparse(cmd_symb))) require(knitr)
|
||||
od <- getwd()
|
||||
on.exit(setwd(od))
|
||||
setwd(dirname(file))
|
||||
frame <- parent.frame()
|
||||
if (is.null(encoding))
|
||||
eval(bquote(.(cmd_symb)(.(file))), envir = frame)
|
||||
else
|
||||
eval(bquote(.(cmd_symb)(.(file), encoding = .(encoding))), envir = frame)
|
||||
}
|
||||
|
||||
.ess_knit <- function(file, output = NULL){
|
||||
library(knitr)
|
||||
frame <- parent.frame()
|
||||
od <- getwd()
|
||||
on.exit(setwd(od))
|
||||
setwd(dirname(file))
|
||||
## this bquote is really needed for data.table := operator to work correctly
|
||||
eval(bquote(knit(.(file), output = .(output))), envir = frame)
|
||||
}
|
||||
|
||||
|
||||
.ess_sweave <- function(file, output = NULL){
|
||||
od <- getwd()
|
||||
frame <- parent.frame()
|
||||
on.exit(setwd(od))
|
||||
setwd(dirname(file))
|
||||
eval(bquote(Sweave(.(file), output = .(output))), envir = frame)
|
||||
}
|
||||
|
||||
## Users might find it useful. So don't prefix with .ess.
|
||||
.ess_htsummary <- function(x, hlength = 4, tlength = 4, digits = 3) {
|
||||
## fixme: simplify and generalize
|
||||
snames <- c("mean", "sd", "min", "max", "nlev", "NAs")
|
||||
d <- " "
|
||||
num_sumr <- function(x){
|
||||
c(f(mean(x, na.rm = TRUE)),
|
||||
f(sd(x, na.rm = TRUE)),
|
||||
f(min(x, na.rm = TRUE)),
|
||||
f(max(x, na.rm = TRUE)),
|
||||
d,
|
||||
f(sum(is.na(x), na.rm = TRUE)))
|
||||
}
|
||||
f <- function(x) format(x, digits = digits)
|
||||
|
||||
if (is.data.frame(x) | is.matrix(x)) {
|
||||
if (nrow(x) <= tlength + hlength){
|
||||
print(x)
|
||||
} else {
|
||||
if (is.matrix(x))
|
||||
x <- data.frame(unclass(x))
|
||||
## conversion needed, to avoid problems with derived classes suchs
|
||||
## as data.table
|
||||
h <- as.data.frame(head(x, hlength))
|
||||
t <- as.data.frame(tail(x, tlength))
|
||||
for (i in 1:ncol(x)) {
|
||||
h[[i]] <- f(h[[i]])
|
||||
t[[i]] <- f(t[[i]])
|
||||
}
|
||||
## summaries
|
||||
sumr <- sapply(x, function(c){
|
||||
if (is.logical(c))
|
||||
## treat logical as numeric; it's harmless
|
||||
c <- as.integer(c)
|
||||
if (is.numeric(c))
|
||||
num_sumr(c)
|
||||
else if (is.factor(c)) c(d, d, d, d, nlevels(c), sum(is.na(c)))
|
||||
else rep.int(d, length(snames))
|
||||
})
|
||||
sumr <- as.data.frame(sumr)
|
||||
row.names(sumr) <- snames
|
||||
dots <- rep("...", ncol(x))
|
||||
empty <- rep.int(" ", ncol(x))
|
||||
lines <- rep.int(" ", ncol(x))
|
||||
df <- rbind(h, ... = dots, t, `_____` = lines, sumr, ` ` = empty)
|
||||
print(df)
|
||||
}
|
||||
} else {
|
||||
cat("head(", hlength, "):\n", sep = "")
|
||||
print(head(x, hlength))
|
||||
if (length(x) > tlength + hlength){
|
||||
cat("\ntail(", tlength, "):\n", sep = "")
|
||||
print(tail(x, tlength))
|
||||
}
|
||||
cat("_____\n")
|
||||
if (is.numeric(x) || is.logical(x))
|
||||
print(structure(num_sumr(x), names = snames), quote = FALSE)
|
||||
else if (is.factor(x)){
|
||||
cat("NAs: ", sum(is.na(x), na.rm = TRUE), "\n")
|
||||
cat("levels: \n")
|
||||
print(levels(x))
|
||||
}
|
||||
}
|
||||
invisible(NULL)
|
||||
}
|
||||
|
||||
|
||||
.ess_vignettes <- function(all=FALSE) {
|
||||
vs <- unclass(browseVignettes(all = all))
|
||||
vs <- vs[sapply(vs, length) > 0]
|
||||
|
||||
mat2elist <- function(mat) {
|
||||
if (!is.null(dim(mat))){
|
||||
apply(mat, 1, function(r)
|
||||
sprintf("(list \"%s\")",
|
||||
paste0(gsub("\"", "\\\\\"",
|
||||
as.vector(r[c("Title", "Dir", "PDF",
|
||||
"File", "R")])),
|
||||
collapse = "\" \"")))
|
||||
}
|
||||
}
|
||||
cat("(list \n",
|
||||
paste0(mapply(function(el, name) {
|
||||
sprintf("(list \"%s\" %s)",
|
||||
name, paste0(mat2elist(el), collapse = "\n"))
|
||||
},
|
||||
vs, names(vs)), collapse = "\n"), ")\n")
|
||||
}
|
||||
|
||||
.ess_Rd2txt <- function(rd) {
|
||||
fun <- tools::Rd2txt
|
||||
if (length(formals(fun)["stages"]))# newer R version
|
||||
fun(rd, stages = c("build", "install", "render"))
|
||||
else
|
||||
fun(rd)
|
||||
}
|
||||
|
||||
## Hacked help.start() to use with ess-rutils.el
|
||||
.ess_help_start <- function(update=FALSE, remote=NULL) {
|
||||
home <- if (is.null(remote)) {
|
||||
port <- tools::startDynamicHelp(NA)
|
||||
if (port > 0L) {
|
||||
if (update)
|
||||
make.packages.html(temp=TRUE)
|
||||
paste0("http://127.0.0.1:", port)
|
||||
}
|
||||
else stop(".ess_help_start() requires the HTTP server to be running",
|
||||
call.=FALSE)
|
||||
} else remote
|
||||
paste0(home, "/doc/html/index.html")
|
||||
}
|
||||
28
lisp/ess/etc/ESSR/R/mpi.R
Normal file
28
lisp/ess/etc/ESSR/R/mpi.R
Normal file
@@ -0,0 +1,28 @@
|
||||
## simple Message Parsing Inerface
|
||||
|
||||
.ess_mpi_send <- function(head, ...){
|
||||
dots <- lapply(list(...), function(el) {
|
||||
if (is.null(el)) "nil"
|
||||
else if (is.logical(el)) {if (el) "t" else "nil"}
|
||||
else as.character(el)
|
||||
})
|
||||
payload <- paste(dots, collapse = "")
|
||||
cat(sprintf("_%s%s\\", head, payload))
|
||||
}
|
||||
|
||||
.ess_mpi_message <- function(msg){
|
||||
.ess_mpi_send("message", msg)
|
||||
}
|
||||
|
||||
.ess_mpi_y_or_n <- function(prompt, callback = NULL){
|
||||
.ess_mpi_send("y-or-n", prompt, callback)
|
||||
}
|
||||
|
||||
.ess_mpi_eval <- function(expr, callback = NULL){
|
||||
.ess_mpi_send("eval", expr, callback)
|
||||
}
|
||||
|
||||
.ess_mpi_error <- function(msg) {
|
||||
.ess_mpi_send("error", msg)
|
||||
}
|
||||
|
||||
421
lisp/ess/etc/ESSR/R/ns-eval.R
Normal file
421
lisp/ess/etc/ESSR/R/ns-eval.R
Normal file
@@ -0,0 +1,421 @@
|
||||
## NOTE ON S3 METHODS: New S3 methods are not automatically registered. You can
|
||||
## register them manually after you have inserted method_name.my_class into your
|
||||
## package environment using ess-developer, like follows:
|
||||
##
|
||||
## registerS3method("method_name", "my_class", my_package:::method_name.my_class)
|
||||
##
|
||||
## If an S3 methods already exists in a package, ESS-developer will do the right
|
||||
## thing.
|
||||
|
||||
## evaluate the STRING by saving into a file and calling .ess.ns_source
|
||||
.ess.ns_eval <- function(string, visibly, output, package,
|
||||
file = tempfile("ESSDev"), verbose = FALSE,
|
||||
fallback_env = NULL, local_env = parent.frame()) {
|
||||
cat(string, file = file)
|
||||
on.exit(.ess.file.remove(file))
|
||||
.ess.ns_source(file, visibly, output, package = package,
|
||||
verbose = verbose, fake.source = TRUE,
|
||||
fallback_env = fallback_env, local_env = local_env)
|
||||
}
|
||||
|
||||
|
||||
##' Source FILE into an environment. After having a look at each new object in
|
||||
##' the environment, decide what to do with it. Handles plain objects,
|
||||
##' functions, existing S3 methods, S4 classes and methods.
|
||||
##' @param fallback_env environment to assign objects which don't exist in the
|
||||
##' package namespace
|
||||
.ess.ns_source <- function(file, visibly, output, expr,
|
||||
package = "", verbose = FALSE,
|
||||
fake.source = FALSE,
|
||||
fallback_env = NULL,
|
||||
local_env = NULL) {
|
||||
pname <- paste("package:", package, sep = "")
|
||||
envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
|
||||
|
||||
if (is.null(envpkg)) {
|
||||
if (suppressWarnings(require(package, quietly = TRUE, character.only = TRUE))) {
|
||||
envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
|
||||
} else {
|
||||
## no such package; source in current (local) user environment
|
||||
return(.ess.source(file, visibly = visibly,
|
||||
output = output, local = local_env,
|
||||
fake.source = fake.source))
|
||||
}
|
||||
}
|
||||
|
||||
envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
|
||||
if (is.null(envns))
|
||||
stop(gettextf("Can't find a namespace environment corresponding to package name '%s\"",
|
||||
package), domain = NA)
|
||||
|
||||
## Here we know that both envns and envpkg exists and are environments
|
||||
if (is.null(fallback_env))
|
||||
fallback_env <- .ess.ns_insert_essenv(envns)
|
||||
|
||||
## Get all Imports envs where we propagate objects
|
||||
pkgEnvNames <- Filter(.ess.is_package, search())
|
||||
packages <- lapply(pkgEnvNames, function(envName) substring(envName, 9))
|
||||
importsEnvs <- lapply(packages, function(pkgName) parent.env(asNamespace(pkgName)))
|
||||
|
||||
## Evaluate the FILE into new ENV
|
||||
env <- .ess.ns_evalSource(file, visibly, output, substitute(expr), package, fake.source)
|
||||
envPackage <- getPackageName(env, FALSE)
|
||||
if (nzchar(envPackage) && envPackage != package)
|
||||
warning(gettextf("Supplied package, %s, differs from package inferred from source, %s",
|
||||
sQuote(package), sQuote(envPackage)), domain = NA)
|
||||
|
||||
## Get all sourced objects, methods and classes
|
||||
allObjects <- objects(envir = env, all.names = TRUE)
|
||||
allObjects <- allObjects[!(allObjects %in% c(".cacheOnAssign", ".packageName"))]
|
||||
MetaPattern <- methods:::.TableMetaPattern()
|
||||
ClassPattern <- methods:::.ClassMetaPattern()
|
||||
allPlainObjects <- allObjects[!(grepl(MetaPattern, allObjects) |
|
||||
grepl(ClassPattern, allObjects))]
|
||||
allMethodTables <- allObjects[grepl(MetaPattern, allObjects)]
|
||||
allClassDefs <- allObjects[grepl(ClassPattern, allObjects)]
|
||||
|
||||
## PLAIN OBJECTS and FUNCTIONS:
|
||||
funcNs <- funcPkg <- newFunc <- newNs <- newObjects <- newPkg <- objectsNs <- objectsPkg <- character()
|
||||
dependentPkgs <- list()
|
||||
|
||||
for (this in allPlainObjects) {
|
||||
thisEnv <- get(this, envir = env)
|
||||
thisNs <- NULL
|
||||
|
||||
## NS
|
||||
if (exists(this, envir = envns, inherits = FALSE)){
|
||||
thisNs <- get(this, envir = envns)
|
||||
if(is.function(thisNs) || is.function(thisEnv)){
|
||||
if(is.function(thisNs) && is.function(thisEnv)){
|
||||
if(.ess.differs(thisEnv, thisNs)){
|
||||
environment(thisEnv) <- environment(thisNs)
|
||||
.ess.assign(this, thisEnv, envns)
|
||||
funcNs <- c(funcNs, this)
|
||||
if(exists(".__S3MethodsTable__.", envir = envns, inherits = FALSE)){
|
||||
S3_table <- get(".__S3MethodsTable__.", envir = envns)
|
||||
if(exists(this, envir = S3_table, inherits = FALSE))
|
||||
.ess.assign(this, thisEnv, S3_table)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
newNs <- c(newNs, this)
|
||||
}
|
||||
}else{
|
||||
if(!identical(thisEnv, thisNs)){
|
||||
.ess.assign(this, thisEnv, envns)
|
||||
objectsNs <- c(objectsNs, this)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
newNs <- c(newNs, this)
|
||||
}
|
||||
|
||||
## PKG
|
||||
if (exists(this, envir = envpkg, inherits = FALSE)){
|
||||
thisPkg <- get(this, envir = envpkg)
|
||||
if(is.function(thisPkg) || is.function(thisEnv)){
|
||||
if(is.function(thisPkg) && is.function(thisEnv)){
|
||||
if(.ess.differs(thisPkg, thisEnv)){
|
||||
environment(thisEnv) <- environment(thisPkg)
|
||||
.ess.assign(this, thisEnv, envpkg)
|
||||
funcPkg <- c(funcPkg, this)
|
||||
}
|
||||
}else{
|
||||
newPkg <- c(newPkg, this)
|
||||
}
|
||||
}else{
|
||||
if(!identical(thisPkg, thisEnv)){
|
||||
.ess.assign(this, thisEnv, envpkg)
|
||||
objectsPkg <- c(objectsPkg, this)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
newPkg <- c(newPkg, this)
|
||||
}
|
||||
|
||||
if (!is.null(thisNs)) {
|
||||
isDependent <- .ess.ns_propagate(thisEnv, this, importsEnvs)
|
||||
newDeps <- stats::setNames(list(packages[isDependent]), this)
|
||||
dependentPkgs <- c(dependentPkgs, newDeps)
|
||||
}
|
||||
}
|
||||
|
||||
## deal with new plain objects and functions
|
||||
for (this in intersect(newPkg, newNs)) {
|
||||
thisEnv <- get(this, envir = env, inherits = FALSE)
|
||||
if (exists(this, envir = fallback_env, inherits = FALSE)){
|
||||
thisGl <- get(this, envir = fallback_env)
|
||||
if (.ess.differs(thisEnv, thisGl)) {
|
||||
if (is.function(thisEnv)) {
|
||||
environment(thisEnv) <- envns
|
||||
newFunc <- c(newFunc, this)
|
||||
} else {
|
||||
newObjects <- c(newObjects, this)
|
||||
}
|
||||
.ess.assign(this, thisEnv, fallback_env)
|
||||
if (.is.essenv(fallback_env))
|
||||
.ess.assign(this, thisEnv, .GlobalEnv)
|
||||
}
|
||||
} else {
|
||||
if (is.function(thisEnv)) {
|
||||
environment(thisEnv) <- envns
|
||||
newFunc <- c(newFunc, this)
|
||||
} else {
|
||||
newObjects <- c(newObjects, this)
|
||||
}
|
||||
.ess.assign(this, thisEnv, fallback_env)
|
||||
if (.is.essenv(fallback_env))
|
||||
.ess.assign(this, thisEnv, .GlobalEnv)
|
||||
}
|
||||
}
|
||||
|
||||
if(length(funcNs))
|
||||
objectsNs <- c(objectsNs, sprintf("FUN[%s]", paste(funcNs, collapse = ", ")))
|
||||
if(length(funcPkg))
|
||||
objectsPkg <- c(objectsPkg, sprintf("FUN[%s]", paste(funcPkg, collapse = ", ")))
|
||||
if(length(newFunc))
|
||||
newObjects <- c(newObjects, sprintf("FUN[%s]", paste(newFunc, collapse = ", ")))
|
||||
|
||||
## CLASSES
|
||||
classesPkg <- classesNs <- newClasses <- character()
|
||||
for(this in allClassDefs){
|
||||
newPkg <- newNs <- FALSE
|
||||
thisEnv <- get(this, envir = env)
|
||||
if(exists(this, envir = envpkg, inherits = FALSE)){
|
||||
if(!.ess.identicalClass(thisEnv, get(this, envir = envpkg))){
|
||||
.ess.assign(this, thisEnv, envir = envpkg)
|
||||
classesPkg <- c(classesPkg, this)
|
||||
}
|
||||
}else{
|
||||
newPkg <- TRUE
|
||||
}
|
||||
if(exists(this, envir = envns, inherits = FALSE)){
|
||||
if(!.ess.identicalClass(thisEnv, get(this, envir = envns))){
|
||||
.ess.assign(this, thisEnv, envir = envns)
|
||||
classesNs <- c(classesNs, this)
|
||||
}
|
||||
}else{
|
||||
newNs <- TRUE
|
||||
}
|
||||
if(newNs && newPkg){
|
||||
if(exists(this, envir = fallback_env, inherits = FALSE)){
|
||||
if(!.ess.identicalClass(thisEnv, get(this, envir = fallback_env))){
|
||||
.ess.assign(this, thisEnv, envir = fallback_env)
|
||||
newClasses <- c(newClasses, this)
|
||||
}
|
||||
}else{
|
||||
.ess.assign(this, thisEnv, envir = fallback_env)
|
||||
newClasses <- c(newClasses, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(length(classesPkg))
|
||||
objectsPkg <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesPkg, collapse = ", ")))
|
||||
if(length(classesNs))
|
||||
objectsNs <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesNs, collapse = ", ")))
|
||||
if(length(newClasses))
|
||||
newObjects <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(newClasses, collapse = ", ")))
|
||||
|
||||
## METHODS:
|
||||
## Method internals: For efficiency reasons setMethod() caches
|
||||
## method definition into a global table which you can get with
|
||||
## 'getMethodsForDispatch' function, and when a method is dispatched that
|
||||
## table is used. When ess-developer is used to source method definitions the
|
||||
## two copies of the functions are identical up to the environment. The
|
||||
## environment of the cached object has namespace:foo as it's parent but the
|
||||
## environment of the object in local table is precisely namspace:foo. This
|
||||
## does not cause any difference in evaluation.
|
||||
methodNames <- allMethodTables
|
||||
methods <- sub(methods:::.TableMetaPrefix(), "", methodNames)
|
||||
methods <- sub(":.*", "", methods)
|
||||
methodsNs <- newMethods <- character()
|
||||
for (i in seq_along(methods)){
|
||||
table <- methodNames[[i]]
|
||||
tableEnv <- get(table, envir = env)
|
||||
if(exists(table, envir = envns, inherits = FALSE)){
|
||||
inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = envns), envns)
|
||||
if(length(inserted))
|
||||
methodsNs <- c(methodsNs, gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
|
||||
}else if(exists(table, envir = fallback_env, inherits = FALSE)){
|
||||
inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = fallback_env), envns)
|
||||
if(length(inserted))
|
||||
newMethods <- c(newMethods, gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
|
||||
}else{
|
||||
.ess.assign(table, tableEnv, envir = fallback_env)
|
||||
newMethods <- c(newMethods, gettextf("%s{%s}", methods[[i]], paste(objects(envir = tableEnv, all.names = T), collapse = ", ")))
|
||||
}
|
||||
}
|
||||
if(length(methodsNs))
|
||||
objectsNs <- c(objectsNs, gettextf("METH[%s]", paste(methodsNs, collapse = ", ")))
|
||||
if(length(newMethods))
|
||||
newObjects <- c(newObjects, gettextf("METH[%s]", paste(newMethods, collapse = ", ")))
|
||||
|
||||
if (verbose) {
|
||||
msgs <- unlist(list(
|
||||
if(length(objectsPkg))
|
||||
sprintf("PKG: %s", paste(objectsPkg, collapse = ", ")),
|
||||
if(length(objectsNs))
|
||||
sprintf("NS: %s", paste(objectsNs, collapse = ", ")),
|
||||
if(length(dependentPkgs))
|
||||
.ess.ns_format_deps(dependentPkgs),
|
||||
if(length(newObjects)) {
|
||||
env_name <- .ess.ns_env_name(fallback_env)
|
||||
sprintf("%s: %s", env_name, paste(newObjects, collapse = ", "))
|
||||
}))
|
||||
if(length(msgs))
|
||||
.ess_mpi_message(paste(msgs, collapse = " "))
|
||||
|
||||
}
|
||||
|
||||
invisible(env)
|
||||
}
|
||||
|
||||
|
||||
.ess.ns_insertMethods <- function(tableEnv, tablePkg, envns) {
|
||||
inserted <- character()
|
||||
for(m in ls(envir = tableEnv, all.names = T)){
|
||||
if(exists(m, envir = tablePkg, inherits = FALSE)){
|
||||
thisEnv <- get(m, envir = tableEnv)
|
||||
thisPkg <- get(m, envir = tablePkg)
|
||||
if(is(thisEnv, "MethodDefinition") && is(thisPkg, "MethodDefinition") &&
|
||||
.ess.differs(thisEnv@.Data, thisPkg@.Data)){
|
||||
environment(thisEnv@.Data) <- envns
|
||||
## environment of cached method in getMethodsForDispatch table is still env
|
||||
## not a problem as such, but might confuse users
|
||||
.ess.assign(m, thisEnv, tablePkg)
|
||||
inserted <- c(inserted, m)
|
||||
}}}
|
||||
inserted
|
||||
}
|
||||
|
||||
## our version of R's evalSource
|
||||
.ess.ns_evalSource <- function(file, visibly, output, expr, package = "",
|
||||
fake.source = FALSE) {
|
||||
envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
|
||||
if(is.null(envns))
|
||||
stop(gettextf("Package \"%s\" is not attached and no namespace found for it",
|
||||
package), domain = NA)
|
||||
env <- new.env(parent = envns)
|
||||
env[[".packageName"]] <- package
|
||||
methods:::setCacheOnAssign(env, TRUE)
|
||||
if (missing(file))
|
||||
eval(expr, envir = env)
|
||||
else if (is(file, "character"))
|
||||
for (f in file) {
|
||||
.ess.source(f, local = env, visibly = visibly,
|
||||
output = output, keep.source = TRUE,
|
||||
max.deparse.length = 300,
|
||||
fake.source = fake.source,
|
||||
message.prefix = sprintf("[%s] ", package))
|
||||
}
|
||||
else stop(gettextf("Invalid file argument: got an object of class \"%s\"",
|
||||
class(file)[[1]]), domain = NA)
|
||||
env
|
||||
}
|
||||
|
||||
|
||||
.ess.assign <- function(x, value, envir) {
|
||||
## Cannot add bindings to locked environments
|
||||
exists <- exists(x, envir = envir, inherits = FALSE)
|
||||
if (exists && bindingIsLocked(x, envir)) {
|
||||
unlockBinding(x, envir)
|
||||
assign(x, value, envir = envir, inherits = FALSE)
|
||||
op <- options(warn = -1)
|
||||
on.exit(options(op))
|
||||
lockBinding(x, envir)
|
||||
} else if (exists || !environmentIsLocked(envir)) {
|
||||
assign(x, value, envir = envir, inherits = FALSE)
|
||||
} else {
|
||||
warning(sprintf("Cannot assign `%s` in locked environment", x),
|
||||
call. = FALSE)
|
||||
}
|
||||
invisible(NULL)
|
||||
}
|
||||
|
||||
.ess.identicalClass <- function(cls1, cls2, printInfo = FALSE) {
|
||||
slots1 <- slotNames(class(cls1))
|
||||
slots2 <- slotNames(class(cls2))
|
||||
if(identical(slots1, slots2)){
|
||||
vK <- grep("versionKey", slots1)
|
||||
if(length(vK))
|
||||
slots1 <- slots2 <- slots1[-vK]
|
||||
out <- sapply(slots1, function(nm) identical(slot(cls1, nm), slot(cls2, nm)))
|
||||
if(printInfo) print(out)
|
||||
all(out)
|
||||
}
|
||||
}
|
||||
|
||||
.ess.differs <- function(f1, f2) {
|
||||
if (is.function(f1) && is.function(f2)){
|
||||
!(identical(body(f1), body(f2)) && identical(args(f1), args(f2)))
|
||||
}else
|
||||
!identical(f1, f2)
|
||||
}
|
||||
|
||||
|
||||
.ess.is_package <- function(envName) {
|
||||
isPkg <- identical(substring(envName, 0, 8), "package:")
|
||||
isPkg && (envName != "package:base")
|
||||
}
|
||||
|
||||
.ess.ns_propagate <- function(obj, name, importsEnvs) {
|
||||
containsObj <- vapply(importsEnvs, logical(1), FUN = function(envs) {
|
||||
name %in% names(envs)
|
||||
})
|
||||
|
||||
lapply(importsEnvs[containsObj], .ess.assign,
|
||||
x = name, value = obj)
|
||||
|
||||
containsObj
|
||||
}
|
||||
|
||||
|
||||
.ess.ns_format_deps <- function(dependentPkgs) {
|
||||
pkgs <- unique(unlist(dependentPkgs, use.names = FALSE))
|
||||
|
||||
lapply(pkgs, function(pkg) {
|
||||
isDep <- vapply(dependentPkgs, function(deps) pkg %in% deps, logical(1))
|
||||
pkgDependentObjs <- names(dependentPkgs[isDep])
|
||||
sprintf("DEP:%s [%s] ", pkg, paste(pkgDependentObjs, collapse = ", "))
|
||||
})
|
||||
}
|
||||
|
||||
.ess.ns_env_name <- function(env) {
|
||||
name <- environmentName(env)
|
||||
name <-
|
||||
if (name == "") "Local"
|
||||
else if (grepl("^essenv:", name)) "NEW"
|
||||
else name
|
||||
name
|
||||
}
|
||||
|
||||
|
||||
.ess.ns_insert_essenv <- function(nsenv) {
|
||||
if (is.character(nsenv))
|
||||
nsenv <- asNamespace(nsenv)
|
||||
stopifnot(isNamespace(nsenv))
|
||||
if (identical(nsenv, .BaseNamespaceEnv))
|
||||
return(.GlobalEnv)
|
||||
essenv_name <- sprintf("essenv:%s", environmentName(nsenv))
|
||||
nsenv_parent <- parent.env(nsenv)
|
||||
if (environmentName(nsenv_parent) == essenv_name) {
|
||||
return(nsenv_parent)
|
||||
}
|
||||
essenv <- new.env(parent = nsenv_parent)
|
||||
essenv[[".__ESSENV__."]] <- TRUE
|
||||
attr(essenv, "name") <- essenv_name
|
||||
nssym <- ".__NAMESPACE__."
|
||||
nssym_val <- get(nssym, envir = nsenv, inherits = FALSE)
|
||||
unlockBinding(nssym, nsenv)
|
||||
nsenv[[nssym]] <- NULL
|
||||
on.exit({
|
||||
nsenv[[nssym]] <- nssym_val
|
||||
lockBinding(nssym, nsenv)
|
||||
})
|
||||
parent.env(nsenv) <- essenv
|
||||
essenv
|
||||
}
|
||||
|
||||
.is.essenv <- function(env) {
|
||||
exists(".__ESSENV__.", envir = env, inherits = FALSE)
|
||||
}
|
||||
26
lisp/ess/etc/ESSR/R/pkg.R
Normal file
26
lisp/ess/etc/ESSR/R/pkg.R
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
.ess_keep <- function(.x, .f, ...) {
|
||||
is_true <- vapply(.x, .f, logical(1), ...)
|
||||
.x[is_true]
|
||||
}
|
||||
|
||||
.ess_devtools_functions <- function() {
|
||||
if (!requireNamespace("devtools")) {
|
||||
.ess_mpi_error("devtools is not installed")
|
||||
stop("internal error")
|
||||
}
|
||||
devtools_env <- asNamespace("devtools")
|
||||
exports <- getNamespaceExports("devtools")
|
||||
funs_exported <- as.list(devtools_env)[exports]
|
||||
|
||||
is_first_arg <- function(f, arg) {
|
||||
args <- names(formals(f))
|
||||
length(args) && args[[1]] == arg
|
||||
}
|
||||
|
||||
funs_pkg <- .ess_keep(funs_exported, is.function)
|
||||
funs_pkg <- .ess_keep(funs_pkg, is_first_arg, "pkg")
|
||||
funs_names <- sort(names(funs_pkg))
|
||||
|
||||
funs_names
|
||||
}
|
||||
52
lisp/ess/etc/Makefile
Normal file
52
lisp/ess/etc/Makefile
Normal file
@@ -0,0 +1,52 @@
|
||||
### Makefile - for scripts and icons (./etc) of ESS distribution.
|
||||
###
|
||||
|
||||
## Before making changes here, please take a look at Makeconf
|
||||
include ../Makeconf
|
||||
|
||||
#ETCFILES = $(wildcard BACKBUG[S5].BAT backbug[s5] *.S sas-keys.*)
|
||||
#ETCFILES = ESSR.R ess-developer.R SVN-REVISION *.S sas-keys.* ess-sas-sh-command
|
||||
# ETCFILES_1 = *.S sas-keys.* ess-sas-sh-command *.jl
|
||||
ETCFILES_1 = ess-sas-sh-command *.jl
|
||||
isRELEASE=$(shell test -f .IS.RELEASE && echo 'yes')
|
||||
ifeq ($(isRELEASE),yes)
|
||||
ETCFILES = .IS.RELEASE git-ref $(ETCFILES_1)
|
||||
else
|
||||
ETCFILES = $(ETCFILES_1)
|
||||
endif
|
||||
|
||||
#ICONS = $(wildcard icons/*.xpm)
|
||||
ICONS = icons/*.xpm
|
||||
|
||||
ESSR_UTIL_FILES = ESSR/LOADREMOTE
|
||||
ESSR_CODE_FILES = ESSR/R/*.R ESSR/R/.*.R
|
||||
|
||||
all:
|
||||
|
||||
show-etc:
|
||||
@echo $(ETCFILES)
|
||||
ls -l $(ETCFILES)
|
||||
|
||||
install :
|
||||
$(INSTALLDIR) $(ETCDIR)/icons
|
||||
$(INSTALLDIR) $(ETCDIR)/ESSR/R
|
||||
$(INSTALL) $(ETCFILES) $(ETCDIR)
|
||||
$(INSTALL) $(ICONS) $(ETCDIR)/icons
|
||||
$(INSTALL) $(ESSR_UTIL_FILES) $(ETCDIR)/ESSR
|
||||
$(INSTALL) $(ESSR_CODE_FILES) $(ETCDIR)/ESSR/R
|
||||
chmod +x $(ETCDIR)/ess-sas-sh-command
|
||||
|
||||
uninstall :
|
||||
-cd $(ETCDIR) && $(UNINSTALL) $(ETCFILES)
|
||||
-cd $(ETCDIR) && $(UNINSTALL) $(ICONS)
|
||||
-cd $(ETCDIR) && $(UNINSTALL) $(ESSR_UTIL_FILES)
|
||||
-cd $(ETCDIR) && $(UNINSTALL) $(ESSR_CODE_FILES)
|
||||
|
||||
|
||||
|
||||
## 'clean' shall remove *exactly* those things that are *not* in version control
|
||||
clean distclean:
|
||||
rm -rf SVN-REVISION
|
||||
## 'distclean' removes also things in VC (svn, when they are remade by "make"):
|
||||
# distclean: clean
|
||||
# rm -rf ESSR_*.tar.gz
|
||||
126
lisp/ess/etc/ess-julia.jl
Normal file
126
lisp/ess/etc/ess-julia.jl
Normal file
@@ -0,0 +1,126 @@
|
||||
module ESS
|
||||
|
||||
# These methods have been deprecated / moved
|
||||
macro current_module()
|
||||
return VERSION >= v"0.7-" ? :(@__MODULE__) : :(current_module())
|
||||
end
|
||||
|
||||
parse = VERSION >= v"0.7-" ? Base.Meta.parse : Base.parse
|
||||
function_module = VERSION >= v"0.7-" ? Base.parentmodule : Base.function_module
|
||||
|
||||
function all_help_topics()
|
||||
## There are not clear topics anymore. Approximate those with a very general
|
||||
## apropos(" ")
|
||||
Base.Docs.apropos(" ")
|
||||
end
|
||||
|
||||
function help(topic::AbstractString)
|
||||
if (VERSION >= v"1.0-")
|
||||
Core.eval(parentmodule(ESS), parse("@doc $topic"))
|
||||
elseif (VERSION >= v"0.4-")
|
||||
Core.eval(@current_module(), parse("@doc $topic"))
|
||||
else
|
||||
Base.Help.help(topic)
|
||||
end
|
||||
end
|
||||
|
||||
## modified version of function show(io::IO, m::Method)
|
||||
function fun_args(m::Method)
|
||||
tv, decls, file, line = Base.arg_decl_parts(m)
|
||||
io = VERSION >= v"0.7-" ? Base.stdout : STDOUT::IO # STDOUT is no longer in 1.0
|
||||
if !isempty(tv)
|
||||
Base.show_delim_array(io, tv, '{', ',', '}', false)
|
||||
end
|
||||
print(io, "(")
|
||||
join(io, [escape_string(isempty(d[2]) ? d[1] : d[1]*"::"*d[2]) for d in decls],
|
||||
",", ",")
|
||||
Base.print(io, ")")
|
||||
end
|
||||
|
||||
## modified versionof show(io::IO, mt::MethodTable)
|
||||
function fun_args(f::Function)
|
||||
mt = Base.MethodList(methods(f).mt)
|
||||
mod = function_module(f) # Base.function_module deprecated in 0.7
|
||||
if mod == Main
|
||||
mod = "nil"
|
||||
end
|
||||
print("(list \"$mod\" nil '(")
|
||||
for d in mt
|
||||
print("\"")
|
||||
## method
|
||||
fun_args(d)
|
||||
print("\" ")
|
||||
end
|
||||
print("))")
|
||||
end
|
||||
|
||||
function fun_args(s::AbstractString)
|
||||
try
|
||||
mod = VERSION >= v"1.0-" ? parentmodule(ESS) : @current_module()
|
||||
m = Core.eval(mod, parse(s))
|
||||
if ! isa(m, String)
|
||||
fun_args(m)
|
||||
end
|
||||
catch
|
||||
print("(list nil nil nil)")
|
||||
end
|
||||
end
|
||||
|
||||
function fun_args(t::DataType)
|
||||
print("(list nil nil '(")
|
||||
for d = fieldnames(t)
|
||||
print("\"$d\" ")
|
||||
end
|
||||
print("))")
|
||||
end
|
||||
|
||||
|
||||
### OBJECT COMPLETION
|
||||
# Must print an output of the form:
|
||||
#
|
||||
# Cache Module
|
||||
# Write Module
|
||||
# add Function
|
||||
# free Function
|
||||
function components(m::Module)
|
||||
for v in sort(names(m, all=true, imported=true))
|
||||
s = string(v)
|
||||
if !startswith(s, "#") && isdefined(m,v)
|
||||
println(rpad(s, 30), summary(Core.eval(m,v)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function components(t::DataType)
|
||||
for v in sort(fieldnames(t))
|
||||
println(rpad(string(v), 30), "field")
|
||||
end
|
||||
end
|
||||
|
||||
function components(v)
|
||||
t = typeof(v)
|
||||
if isa(t, DataType)
|
||||
return components(t)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
### MISC
|
||||
function main_modules(m::Module)
|
||||
for nm in names(m)
|
||||
if isdefined(m, nm)
|
||||
mod = Core.eval(m, nm)
|
||||
if isa(mod, Module)
|
||||
print("\"$nm\" ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if VERSION >= v"0.7-"
|
||||
main_modules() = main_modules(Base.parentmodule(@current_module()))
|
||||
else
|
||||
main_modules() = main_modules(@current_module())
|
||||
end
|
||||
|
||||
end
|
||||
76
lisp/ess/etc/ess-sas-sh-command
Executable file
76
lisp/ess/etc/ess-sas-sh-command
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
|
||||
### (C) 1997, Richard M. Heiberger.
|
||||
### This file is part of ESS.
|
||||
|
||||
## This file is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2, or (at your option)
|
||||
## any later version.
|
||||
|
||||
## This file is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
|
||||
## A copy of the GNU General Public License is available at
|
||||
## https://www.r-project.org/Licenses/
|
||||
|
||||
|
||||
# For executing SAS, and running it in the proper manner for ESS
|
||||
# (feeding output back into appropriate ESS buffers).
|
||||
|
||||
#echo $0 $@
|
||||
#sas </dev/tty 1>$1 2>$2 $3
|
||||
|
||||
set -x
|
||||
stdout=$1
|
||||
stderr=$2
|
||||
shift 2
|
||||
set +x
|
||||
echo sas \</dev/tty 1\>$stdout 2\>$stderr $@
|
||||
sas </dev/tty 1>$stdout 2>$stderr $@
|
||||
|
||||
## From the SAS online tech support:
|
||||
##
|
||||
## Redirecting the SAS Log and Output under UNIX.
|
||||
##
|
||||
## There are several ways of redirecting the SAS Log and Output under
|
||||
## UNIX.
|
||||
##
|
||||
## To redirect the SAS Log, follow one of these steps:
|
||||
##
|
||||
## 1.
|
||||
## In the source code, place the following line:
|
||||
##
|
||||
## proc printto log=stdout;
|
||||
##
|
||||
## to make a duplicate copy of the log in a file in addition
|
||||
## to redirecting it to stdout, use this command to invoke
|
||||
## SAS:
|
||||
##
|
||||
## sas -altlog doit.log doit.sas
|
||||
##
|
||||
## 2.Execute SAS in the background and use the UNIX 'tail' command
|
||||
## to copy lines to stdout as they are added to the log. Use the
|
||||
## command:
|
||||
##
|
||||
## sas doit.sas &; tail -f doit.log
|
||||
##
|
||||
## To redirect the SAS Log and Output under the Korn shell, use the
|
||||
## following command:
|
||||
##
|
||||
## sas -stdio < doit.sas > doit.lst 2> doit.log
|
||||
##
|
||||
## To redirect the SAS Log and Output under the C-Shell, use the
|
||||
## following command:
|
||||
##
|
||||
## (sas -stdio < doit.sas > doit.lst) >& doit.log
|
||||
|
||||
## From WWW.SAS.COM:
|
||||
## How can I make SAS in batch mode behave like interactive SAS,
|
||||
## continue running my SAS job, and not enter syntax check mode when
|
||||
## it encounters an error?
|
||||
##
|
||||
## You can specify the NOSYNTAXCHECK option when you invoke your SAS
|
||||
## program.
|
||||
31
lisp/ess/etc/icons/README
Normal file
31
lisp/ess/etc/icons/README
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Creating pixmaps:
|
||||
|
||||
* spluslogo.xpm was dontated by David Smith at Insightful.
|
||||
|
||||
* Other icons were created by SJE, using mostly `kiconedit' and
|
||||
hand-editing.
|
||||
|
||||
* Transparency
|
||||
Need to add backgrounToolBarColor for XEmacs to show okay.
|
||||
e.g. /usr/share/xemacs-21.4.12/etc/toolbar/folder-cap-up.xpm
|
||||
has header:
|
||||
"X c Gray75 s backgroundToolBarColor",
|
||||
whereas I have set "c None" to indicate the background pixel; this line
|
||||
seems to work for both toolbars:
|
||||
". c None s backgroundToolBarColor",
|
||||
|
||||
* splus_letters_small.xpm
|
||||
|
||||
2010-05-18 & -21: SJE made this new Splus icon from the
|
||||
splus_letters_large.xpm (then image001.png from Louis Bajuk-Yorgan
|
||||
@tibco.com) file that Rich provided. I had to move the
|
||||
cross over to the left by one pixel, to then allow the image to be
|
||||
cropped to 48x48 (cropping performed in gimp). kiconedit was then
|
||||
used to rescale the icon to 24x24. Finally, background transparency
|
||||
added manually to the file, as noted above.
|
||||
|
||||
2010-05-21: updated file based on new image from TIBCO. Original
|
||||
51x38 cropped to 50x38 in xv, then shrunk to 25x19 in kiconedit.
|
||||
Transparency added, and removed a lot of the extra white pixels into
|
||||
background colours manually in kiconedit.
|
||||
30
lisp/ess/etc/icons/rbuffer.xpm
Normal file
30
lisp/ess/etc/icons/rbuffer.xpm
Normal file
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char *rbuffer[]={
|
||||
"24 24 3 1",
|
||||
". c None s backgroundToolBarColor",
|
||||
"a c #000000",
|
||||
"# c #1532ed",
|
||||
"........................",
|
||||
"...............#........",
|
||||
"...............##.......",
|
||||
".....#############......",
|
||||
".....##############.....",
|
||||
".....#############......",
|
||||
"...............##.......",
|
||||
"...............#........",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa..."};
|
||||
45
lisp/ess/etc/icons/rfunction.xpm
Normal file
45
lisp/ess/etc/icons/rfunction.xpm
Normal file
@@ -0,0 +1,45 @@
|
||||
/* XPM */
|
||||
static char *rfunction[]={
|
||||
"24 24 18 1",
|
||||
"B c #000000",
|
||||
"k c #181818",
|
||||
"Q c #1f1f1f",
|
||||
"z c #232323",
|
||||
"L c #313131",
|
||||
"Z c #3c3c3c",
|
||||
"O c #404040",
|
||||
"a c #5e5e5e",
|
||||
"W c #676767",
|
||||
"U c #757575",
|
||||
"N c #848484",
|
||||
"P c #969696",
|
||||
"0 c #a0a0a0",
|
||||
". c None s backgroundToolBarColor",
|
||||
"G c #b9b9b9",
|
||||
"I c #c6c6c6",
|
||||
"T c #d5d5d5",
|
||||
"# c #1532ed",
|
||||
"........................",
|
||||
"...............#........",
|
||||
"...............##.......",
|
||||
".....#############......",
|
||||
".....##############.....",
|
||||
".....#############......",
|
||||
"...............##.......",
|
||||
"...............#........",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"..............az..zU....",
|
||||
"....ILBBz...GkP....aO...",
|
||||
"....zU......BG......LP..",
|
||||
"....BG.....UO.......0z..",
|
||||
"..BBBBBBP..zP.......GB..",
|
||||
"....BG.....BG........BI.",
|
||||
"....BG.....BG........BI.",
|
||||
"....BG.....LP.......GB..",
|
||||
"....BG.....NO.......PL..",
|
||||
"....BG......Q0......z0..",
|
||||
"....BG......TQU0..0ZW...",
|
||||
"..............NL..Z0....",
|
||||
"........................"};
|
||||
30
lisp/ess/etc/icons/rline.xpm
Normal file
30
lisp/ess/etc/icons/rline.xpm
Normal file
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char *rline[]={
|
||||
"24 24 3 1",
|
||||
". c None s backgroundToolBarColor",
|
||||
"a c #000000",
|
||||
"# c #1532ed",
|
||||
"........................",
|
||||
"...............#........",
|
||||
"...............##.......",
|
||||
".....#############......",
|
||||
".....##############.....",
|
||||
".....#############......",
|
||||
"...............##.......",
|
||||
"...............#........",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................"};
|
||||
30
lisp/ess/etc/icons/rregion.xpm
Normal file
30
lisp/ess/etc/icons/rregion.xpm
Normal file
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char *rregion[]={
|
||||
"24 24 3 1",
|
||||
". c None s backgroundToolBarColor",
|
||||
"a c #000000",
|
||||
"# c #1532ed",
|
||||
"........................",
|
||||
"...............#........",
|
||||
"...............##.......",
|
||||
".....#############......",
|
||||
".....##############.....",
|
||||
".....#############......",
|
||||
"...............##.......",
|
||||
"...............#........",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"...aaaaaaaaaaaaaaaaaa...",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................"};
|
||||
173
lisp/ess/etc/icons/splus_letter_small.xpm
Normal file
173
lisp/ess/etc/icons/splus_letter_small.xpm
Normal file
@@ -0,0 +1,173 @@
|
||||
/* XPM */
|
||||
static char *dummy[]={
|
||||
"25 19 151 2",
|
||||
"Qt c None s backgroundToolBarColor",
|
||||
"#M c #044b83",
|
||||
"#R c #044c86",
|
||||
"#t c #044c87",
|
||||
"ae c #044d87",
|
||||
"an c #044e7f",
|
||||
".o c #044e81",
|
||||
"#l c #044e8d",
|
||||
"ak c #044f84",
|
||||
".B c #044f88",
|
||||
"#m c #044f8e",
|
||||
"am c #045188",
|
||||
".j c #04518b",
|
||||
".O c #045191",
|
||||
"#6 c #04528f",
|
||||
"#O c #045388",
|
||||
".k c #04538c",
|
||||
"#U c #04538e",
|
||||
"#Y c #045392",
|
||||
".l c #045489",
|
||||
"## c #04548c",
|
||||
"#i c #045490",
|
||||
"#v c #045492",
|
||||
"#. c #04558e",
|
||||
"#C c #045593",
|
||||
"#k c #04568d",
|
||||
"#B c #045695",
|
||||
"#G c #045698",
|
||||
".Y c #045795",
|
||||
".R c #045890",
|
||||
"#j c #04598f",
|
||||
".4 c #045995",
|
||||
"aj c #054e7b",
|
||||
"al c #054e89",
|
||||
"#h c #054e8d",
|
||||
"#S c #055188",
|
||||
"#V c #05518d",
|
||||
".m c #055282",
|
||||
".K c #055284",
|
||||
".5 c #055583",
|
||||
".t c #055791",
|
||||
"#u c #055894",
|
||||
".n c #064e86",
|
||||
"#s c #074d76",
|
||||
".p c #074e83",
|
||||
"a. c #074f89",
|
||||
"#a c #074f8a",
|
||||
"af c #075389",
|
||||
"#9 c #07548e",
|
||||
".A c #075592",
|
||||
".F c #075594",
|
||||
"#1 c #075a99",
|
||||
".c c #094d79",
|
||||
".9 c #094f89",
|
||||
".J c #095681",
|
||||
"#A c #0b568d",
|
||||
".s c #0c4f85",
|
||||
"#5 c #0c5188",
|
||||
"#w c #0d5486",
|
||||
".b c #0e4e7d",
|
||||
".N c #105287",
|
||||
".X c #105685",
|
||||
"#H c #115789",
|
||||
"#Z c #13508a",
|
||||
"#2 c #135287",
|
||||
"#F c #195c8a",
|
||||
".i c #1a5c8b",
|
||||
"#8 c #1b5684",
|
||||
"ai c #1b5a81",
|
||||
"ad c #1c5d87",
|
||||
"#P c #1d5c8c",
|
||||
"#r c #1d5f8a",
|
||||
"#N c #1f5b7d",
|
||||
"ao c #1f5c85",
|
||||
"#0 c #205a86",
|
||||
"#n c #206292",
|
||||
".u c #216794",
|
||||
".d c #245b81",
|
||||
".G c #256390",
|
||||
".3 c #265f85",
|
||||
"a# c #266287",
|
||||
"#x c #296286",
|
||||
"#b c #2a5f96",
|
||||
"#g c #2b6395",
|
||||
".a c #2c658f",
|
||||
".Q c #307195",
|
||||
".E c #326897",
|
||||
".S c #356f98",
|
||||
".Z c #35789b",
|
||||
"ag c #396c94",
|
||||
"#I c #3a6a78",
|
||||
"#z c #3f7497",
|
||||
".1 c #3f7c9e",
|
||||
"#J c #427585",
|
||||
"aa c #42768f",
|
||||
"#X c #447ca1",
|
||||
".C c #457b9a",
|
||||
".z c #457ba8",
|
||||
"ac c #48778f",
|
||||
".q c #4e86b0",
|
||||
"#7 c #4f86b5",
|
||||
".6 c #50829b",
|
||||
"#q c #538db5",
|
||||
"#D c #538eb3",
|
||||
".e c #547f91",
|
||||
"ab c #5487a1",
|
||||
"#T c #58859c",
|
||||
"ah c #5983a7",
|
||||
"#c c #5a7d99",
|
||||
".2 c #5b809c",
|
||||
".P c #5d94bb",
|
||||
"#K c #6c91a0",
|
||||
"#4 c #6c99ba",
|
||||
"#L c #6c9cb7",
|
||||
"#o c #7097a7",
|
||||
"ap c #739eb3",
|
||||
".v c #73a7c0",
|
||||
".0 c #7cacc3",
|
||||
"#y c #7faac6",
|
||||
".# c #82a0a8",
|
||||
"#Q c #84aec8",
|
||||
".I c #86a8bd",
|
||||
".L c #89b3cd",
|
||||
"#d c #8aa7b6",
|
||||
"as c #8db2cc",
|
||||
".y c #8db9cd",
|
||||
".h c #8eb5c9",
|
||||
".8 c #8eb9d3",
|
||||
"#W c #8fb2c9",
|
||||
"at c #91b7c8",
|
||||
"#3 c #94b4cb",
|
||||
"ar c #95b7cb",
|
||||
".T c #979798",
|
||||
".U c #99999a",
|
||||
"#f c #99b9cd",
|
||||
".g c #9b9b9b",
|
||||
".V c #9c9c9c",
|
||||
".r c #9cc2d4",
|
||||
".w c #a7c8d0",
|
||||
".x c #a9c8d1",
|
||||
"#p c #a9cbda",
|
||||
".f c #abc5cd",
|
||||
"#E c #abcad6",
|
||||
"aq c #b1d0e0",
|
||||
"au c #b3d2e2",
|
||||
".7 c #b8cfd6",
|
||||
"#e c #baced7",
|
||||
".W c #d4e0e4",
|
||||
".H c #d7e7ed",
|
||||
".M c #dae6ef",
|
||||
".D c #eef8f8",
|
||||
"QtQtQtQt.#.a.b.c.d.e.fQtQtQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"QtQt.h.i.j.k.l.m.n.o.p.qQtQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"Qt.r.s.t.u.v.w.x.y.z.A.B.CQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
".D.E.F.G.HQtQtQtQtQt.I.J.K.LQtQtQtQtQt.g.gQtQtQtQt",
|
||||
".M.N.O.PQtQtQtQtQtQtQt.Q.R.SQt.g.T.U.g.g.g.V.V.g.g",
|
||||
".W.X.Y.ZQtQtQtQtQtQtQt.0.1.2Qt.g.g.g.g.g.g.g.g.g.g",
|
||||
"Qt.3.4.5.6.7QtQtQtQtQtQtQtQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"Qt.8.9#.###a#b#c#d#eQtQtQtQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"QtQt#f#g#h#i#j#k#l#m#n#oQtQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"QtQtQtQt#p#q#r#s#t#u#v#w#xQtQtQtQtQtQt.g.gQtQtQtQt",
|
||||
"QtQtQtQtQtQtQtQt#y#z#A#B#C#DQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQtQtQtQtQtQtQtQtQt#E#F#G#HQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"#I#J#KQtQtQtQtQtQtQtQt#L.B#MQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"#N#O#PQtQtQtQtQtQtQtQt#Q#R#SQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"#T#U#V#WQtQtQtQtQtQtQt#X#Y#ZQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"Qt#0#1#2#3QtQtQtQtQt#4#5#6#7QtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQt#8#9a.a#aaabacadaeafagQtQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQtQtahaiajakalamanaoapQtQtQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQtQtQtQtaqarasatauQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt"};
|
||||
BIN
lisp/ess/etc/icons/splus_letters_large.png
Normal file
BIN
lisp/ess/etc/icons/splus_letters_large.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
281
lisp/ess/etc/icons/splus_letters_large.xpm
Normal file
281
lisp/ess/etc/icons/splus_letters_large.xpm
Normal file
@@ -0,0 +1,281 @@
|
||||
/* XPM */
|
||||
static char *splus_letters_large[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 51 38 236 2",
|
||||
/* colors */
|
||||
".. c #043e74",
|
||||
".# c #74a29c",
|
||||
".a c #547a74",
|
||||
".b c #bcb2b9",
|
||||
".c c #0c6a9c",
|
||||
".d c #045282",
|
||||
".e c #bcdae8",
|
||||
".f c #94c2cc",
|
||||
".g c #245678",
|
||||
".h c #e4e2e3",
|
||||
".i c #94a2a4",
|
||||
".j c #04528f",
|
||||
".k c #5c8aa4",
|
||||
".l c #346688",
|
||||
".m c #848a8c",
|
||||
".n c #04427c",
|
||||
".o c #e4f4fc",
|
||||
".p c #94b4b4",
|
||||
".q c #cceef4",
|
||||
".r c #045e99",
|
||||
".s c #4c7a88",
|
||||
".t c #a4d6f0",
|
||||
".u c #6c8e94",
|
||||
".v c #f4f2e4",
|
||||
".w c #7cb2d4",
|
||||
".x c #b4b2b4",
|
||||
".y c #145274",
|
||||
".z c #044c74",
|
||||
".A c #acc2d4",
|
||||
".B c #dcdddc",
|
||||
".C c #34729c",
|
||||
".D c #c4c6c4",
|
||||
".E c #144e84",
|
||||
".F c #94b4cc",
|
||||
".G c #fcfaeb",
|
||||
".H c #245a88",
|
||||
".I c #5496b9",
|
||||
".J c #044a80",
|
||||
".K c #c4e6f1",
|
||||
".L c #9cc6ec",
|
||||
".M c #347aac",
|
||||
".N c #6c96a8",
|
||||
".O c #145a80",
|
||||
".P c #6ca2c8",
|
||||
".Q c #045a91",
|
||||
".R c #d4fafc",
|
||||
".S c #145e8c",
|
||||
".T c #144264",
|
||||
".U c #446e89",
|
||||
".V c #949594",
|
||||
".W c #5c7e84",
|
||||
".X c #548ec4",
|
||||
".Y c #e4fdfc",
|
||||
".Z c #044a8c",
|
||||
".0 c #e4eef2",
|
||||
".1 c #a4a3a4",
|
||||
".2 c #346aa0",
|
||||
".3 c #dceef4",
|
||||
".4 c #bcd2d4",
|
||||
".5 c #f4faf9",
|
||||
".6 c #74aacc",
|
||||
".7 c #044669",
|
||||
".8 c #246696",
|
||||
".9 c #045a84",
|
||||
"#. c #ccdedc",
|
||||
"## c #9ccad8",
|
||||
"#a c #a4b6b7",
|
||||
"#b c #144a6e",
|
||||
"#c c #94bacc",
|
||||
"#d c #346288",
|
||||
"#e c #6c9bbc",
|
||||
"#f c #bcbebc",
|
||||
"#g c #c4e2ec",
|
||||
"#h c #0c548c",
|
||||
"#i c #7c9e9c",
|
||||
"#j c #f4f2f4",
|
||||
"#k c #14527c",
|
||||
"#l c #0c4c7f",
|
||||
"#m c #0c5379",
|
||||
"#n c #c4dae4",
|
||||
"#o c #245e7c",
|
||||
"#p c #6492a4",
|
||||
"#q c #346e94",
|
||||
"#r c #ecf4f2",
|
||||
"#s c #44829c",
|
||||
"#t c #b4cad0",
|
||||
"#u c #145a8e",
|
||||
"#v c #447490",
|
||||
"#w c #246294",
|
||||
"#x c #448abc",
|
||||
"#y c #fcfefb",
|
||||
"#z c #2c6f9a",
|
||||
"#A c #a4bacc",
|
||||
"#B c #bcbaba",
|
||||
"#C c #94a6c0",
|
||||
"#D c #04569c",
|
||||
"#E c #648aa0",
|
||||
"#F c #d4f6fc",
|
||||
"#G c #8cb2c4",
|
||||
"#H c #acbabc",
|
||||
"#I c #d4e8f0",
|
||||
"#J c #84aabc",
|
||||
"#K c #1c5b82",
|
||||
"#L c #7ca2c1",
|
||||
"#M c #5486a4",
|
||||
"#N c #ecebe9",
|
||||
"#O c #0c5fa4",
|
||||
"#P c #9cbdce",
|
||||
"#Q c #accee4",
|
||||
"#R c #0c4270",
|
||||
"#S c #6c6e6c",
|
||||
"#T c #a4c4cc",
|
||||
"#U c #0c467c",
|
||||
"#V c #9cb6b4",
|
||||
"#W c #d4eef8",
|
||||
"#X c #447c98",
|
||||
"#Y c #b4d4e8",
|
||||
"#Z c #6c92a4",
|
||||
"#0 c #0c4b6f",
|
||||
"#1 c #cccccc",
|
||||
"#2 c #2c5e8c",
|
||||
"#3 c #649cc0",
|
||||
"#4 c #cce7f1",
|
||||
"#5 c #a4cee8",
|
||||
"#6 c #4482ac",
|
||||
"#7 c #d4d6d4",
|
||||
"#8 c #648abc",
|
||||
"#9 c #9c9b9c",
|
||||
"a. c #acadac",
|
||||
"a# c #547a98",
|
||||
"aa c #34627c",
|
||||
"ab c #1c669c",
|
||||
"ac c #84badc",
|
||||
"ad c #bcced4",
|
||||
"ae c #6c8ea4",
|
||||
"af c #bcd4e8",
|
||||
"ag c #dcf6fc",
|
||||
"ah c #8cbad4",
|
||||
"ai c #7c9bb1",
|
||||
"aj c #9cc6dc",
|
||||
"ak c #3c6a84",
|
||||
"al c #7496a7",
|
||||
"am c #1c5e94",
|
||||
"an c #5c90b8",
|
||||
"ao c #b4dee4",
|
||||
"ap c #4c728c",
|
||||
"aq c #4c86ac",
|
||||
"ar c #dce6e9",
|
||||
"as c #8caebc",
|
||||
"at c #94aec0",
|
||||
"au c #7ca2a8",
|
||||
"av c #5c96c4",
|
||||
"aw c #0c5a90",
|
||||
"ax c #2c668c",
|
||||
"ay c #2c5e70",
|
||||
"az c #5c86a4",
|
||||
"aA c #ece6dc",
|
||||
"aB c #8c8d8f",
|
||||
"aC c #748c8c",
|
||||
"aD c #fcf6ec",
|
||||
"aE c #84b6cc",
|
||||
"aF c #1c5470",
|
||||
"aG c #3c7aa4",
|
||||
"aH c #74a6c4",
|
||||
"aI c #7cacc8",
|
||||
"aJ c #a4cbd7",
|
||||
"aK c #1c4e6c",
|
||||
"aL c #749bc1",
|
||||
"aM c #c4c2c4",
|
||||
"aN c #fcf6f5",
|
||||
"aO c #1c5682",
|
||||
"aP c #b4cbe1",
|
||||
"aQ c #747274",
|
||||
"aR c #4c7a9c",
|
||||
"aS c #04468c",
|
||||
"aT c #94b2c4",
|
||||
"aU c #0462a4",
|
||||
"aV c #84a6b4",
|
||||
"aW c #9ccaf4",
|
||||
"aX c #6c9ab4",
|
||||
"aY c #dcfbfc",
|
||||
"aZ c #14629c",
|
||||
"a0 c #14466c",
|
||||
"a1 c #ecfdfc",
|
||||
"a2 c #dcf2fc",
|
||||
"a3 c #0c5384",
|
||||
"a4 c #c4dcf4",
|
||||
"a5 c #ecf5fc",
|
||||
"a6 c #44749c",
|
||||
"a7 c #2c6ea4",
|
||||
"a8 c #648eac",
|
||||
"a9 c #8cb6d4",
|
||||
"b. c #7ca6cc",
|
||||
"b# c #eceef4",
|
||||
"ba c #a4c6dc",
|
||||
"bb c #9cb2c4",
|
||||
"bc c #b4daf4",
|
||||
"bd c #9ca29c",
|
||||
"be c #c4d2dc",
|
||||
"bf c #3c6e90",
|
||||
"bg c #b4babb",
|
||||
"bh c #4c82a4",
|
||||
"bi c #045a9c",
|
||||
"bj c #044674",
|
||||
"bk c #0c5a84",
|
||||
"bl c #4c829c",
|
||||
"bm c #5486b4",
|
||||
"bn c #044272",
|
||||
"bo c #bcb6b8",
|
||||
"bp c #045684",
|
||||
"bq c #bcdee7",
|
||||
"br c #245a7c",
|
||||
"bs c #e4e6e4",
|
||||
"bt c #045691",
|
||||
"bu c #5c8ea9",
|
||||
"bv c #04467e",
|
||||
"bw c #ccf2f9",
|
||||
"bx c #04629c",
|
||||
"by c #f4f6ec",
|
||||
"bz c #b4b6b5",
|
||||
"bA c #fcfeec",
|
||||
"bB c #245e88",
|
||||
"bC c #044e81",
|
||||
"bD c #9ccae4",
|
||||
"bE c #347ea4",
|
||||
"bF c #5c828c",
|
||||
"bG c #044e8d",
|
||||
"bH c #346e9c",
|
||||
"bI c #dcf2ec",
|
||||
"bJ c #0c6298",
|
||||
"bK c #f4fefc",
|
||||
"bL c #74aec4",
|
||||
"bM c #a4babc",
|
||||
"bN c #94bed4",
|
||||
"bO c #f4f6f4",
|
||||
"bP c #145680",
|
||||
/* pixels */
|
||||
".mbgbobo.bbo#Bbg#aaVa8.l#ba0.7a0br.U.N.p#abg#Bbobobo#B#Bbo.b.bbz#B#Bbg#Bbz#B.V#SaQ#SaB.x#B#B#B#Bbg#B#B",
|
||||
".x.5#yaN#y#yar#a.Way#l#h#hbtaw.d#l#K.gay.uada5#ybO#j#y#yaN#yaN#y#y#y#y#y#y#y#1.V#9.V#BbO#y#y#y#y#y#y#y",
|
||||
"#B#y#ybKagbDaq#u.JbGbtbtbt.QbpbC#h.d.JbC.JbP.X.ta1bK#y#y#y#y#y#y#y#y#y#y#y#y.D#9#9#9#BbO#y#y#y#y#y#y#y",
|
||||
"bo.G#y.oas.lbj.Jbt.Qbt.J.J.9bk.JbvbG.d.dbtbvbvbf#Ta1#y#y#yaN#y#y#y#y#y#y#y#y.D.V#9.V#BbO#y#y#y#y#y#y#y",
|
||||
"#B#y.Yah.8bv.QbJ.j#m#K#X#palal.Na8#qaO#l#Dbt.j.J#zaja1#yaN#y#y#y#y#y#y#y#y#y.D#9#9#9#faN#y#y#y#y#y#y#y",
|
||||
"bg#ybqa6...jbi.J.S#3.tbw.Y.Ya1aY.Rbw.Lbm#ubGbtbC.7ap#n#y#y#yaN#y#y#y#y#y#y#y.D#9.V#9#B#y#y#y#y#y#y#y#y",
|
||||
"bza1b..J.ZbibC.g.F.0#y#y.G#y#y#ybK#y#yb##CaF.d.c.da3.Pa2#yaN.G#y#y#y#y#y#y#y.D#9#9.V#BbO#y#y#y#y#y#y#y",
|
||||
"bz#Ia6..aZ.jbG#ea1#y#y#y#y#y#y#y#y#y#y#y.oaE.y.z.rbjax#Y#yaD.v#N.h.hbsbs.hbs.x#9#9#9.x.h#Nbs.hbs.hbs#j",
|
||||
"#Ha4aObG#DbG#ubabK#y.G#y#y#y#y.5#yaNaNaN#y#W#s.JbxbtbC.6a1#yaAa.#9.1#9.1.1#9#9#9#9#9bd#9.1.1.1#9#9.1.B",
|
||||
"#H.AaObGbGbtab#5bK#y#y.G#y#y#y#y#y#yaN.G#ya1bL.zbt.dbnaz.3#y.h.1aB.V#9aB.V#9#9#9#9#9#9#9.V.V#9.V.V#9.B",
|
||||
"#H#AaO.Q#DbtbkaEa1#y#y.G#y#y#yaN#yaN#yaNaN#y##.O.z#m#Rap#n#ybs.1.V.1#9#9#9.1#9.Vbd#9#9#9#9#9#9.1.V.1.B",
|
||||
"bg#t#KbC.rbt.d#s#WbK#y#y#y#yaN#yaN#y#yaNaNbK#gaIaHaIaibb#I#y#r#1#1#1.D#1#1#1.x#9#9#9a..D#1#1#1#1#1#1b#",
|
||||
"bgaraabjbi.Qbp#mbuaJbI#y#y#y#y#yaNaN#y#y#y#ybK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#1#9.V#9#fbO#y#y#y#y#y#y#y",
|
||||
"bga5.kbCbt.rbx.z.7ak#Z#Pa4.0#y#y#y#y#y#y#y#j#y#y.5#y#y#y#yaN#y#y#y#y#y#y#y#y#f#9#9.V#B#y#y#y#y#y#y#y#y",
|
||||
"bo#y#Qa7.Zbt.r.Q.QbC.Z#h.2#8#C#A.4ar#r#y#y#yaNaN#y#y#y#y#y#yaN#y#y#y#y#y#y#yaM.V#9.V#fbO#y#y#y#y#y#y#y",
|
||||
"bo#y.YaIam..bv.Qbtbtbt#laS#Ra0aKaka#ae#c.ea2bK#y#y#yaN.G#y#y.5#y#y#y#y#y#y#y.D#9bd#9#faN#y#y#y#y#y#y#y",
|
||||
"bo.G#ya5at#d#UaS#D#Dbi.r.r.QbtbtbG.Z.Z.jaban.f#.bO#y#y#y#y#y.5#y#y#y#y#y#y#y.D.V#9.VbobO#y#y#y#y#y#y#y",
|
||||
"boaN#y#ya1bcaLax#U.JbCbGbp.Q.9bt.j.j.j.j.J.zaK.U#Pa2bK#y#y#y#y#y#yaN#y#y#y#y.D.VaBaBbzbO#y#y#y#y#y#y#y",
|
||||
"#B#y#y#yaNbK.oaf#Jan.C.ObCbC.d.d.j.jbi.rbi.j#l#0#KaX#I#y.5.G.G#y#y#y#y#y#y#y#1.xa..1.D#y#y#y#y#y#y#y#y",
|
||||
"bo#y#yaN.5#y#y#ybK#FaW.Paq#o#b.7bv.J#hbt.j.jaZawbnaFaEa1.5aN#y#y#y#y#y#y#y#y.h#7.h.B.h#y#y#y#y#y#y#y#y",
|
||||
"#B#y.G.G#y.G#y.G#y#y.Y#IaoaJ#GaXaq#w#0.Jbtbi#Dbibi.J.MaobK.G.G#y#y#y#y#y#y#yaN#y#yaN#y#yaN#y#y#y#y#y#y",
|
||||
"bg#y#y#y#y#yaN#y#y#ybKbKbKbKbKa1.3#Y.F.kbBbC.dbiaU.jbv#3.o#yaD#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#HbK#y.5#y#y.G.G.G#y#y#y#y#y#y#y#y#y#y.0#Tbha3.j#Dbibv#zaf#y.G#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#Ha1a1a1a1#y.GaN#y#y#y#y#y#y.GaN#y.G#y#y#y.K#Mbj.jbi.jbP#c#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
".a.##i.#au#t#y#yaN#y#y#y#y#y.GaN.G.G.GbA#y#y#P.O.jbt.jbv#LbK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
".T#0#0#0aK#EbK#y#y.G#y#y#y#y#y#y#y#y.G#y#y#y#gaG.JbC.jbn#ebK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"br#m.QbC.JaR.3#yaNaN#y#y#y#y#y#y#y#yaN.GaD.G#Wbhbv.j.Q.JaXbK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#v#0.d.j.J.8#Q#y#y.G#y#y#y#ybK#y#yaN#y#ybObK.ebHbvbtbt#l#LbK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
".NbP.j.r.d#h#LbK#y#y#y#y#ybK#ybKbK#y#y#y#y#y#P.ObGbt.Z.Ea9#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"at.s.Jbt#D.ZaxbabO#y#y#ybK#y#y#y#y#y#y#y#y#4an.Jbt#D.n.2#Y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"bMaT#k.Z#D#O.n.UbeaN#y#y#y#y#y#y#y#y#y#y.0ai.gbC#DbibGav#F#y.G#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#B.0#Ebnbp#ObGbG.8.PbcaYa1a1.YbKbKbKaYaW#x#h.Zbibtbj.2#Q#y#yaN#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"bo#y.e#X.J.j.r#DaS#hbHbFaCau.p#V.iaC.sam.JbG.r#Dbv.HbN.5.5aNaN#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#B#ybKaPa#a0.EbC#h.d.zbC#mawaw#u.S.d.J.d.jbCbC#b#d#G.o#y#j#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"bzbObKa1.KaL#2#la3bCbC.d.j.jbGbvbGbtbt.jbCbj.yblaJ.YbKbKbK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#B#yaN#y#ya5aPaiak#o#mbj.zbC#h.j.d.d.z.7br#M#P#I#y#yaN#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"#B#y#y#yaN#y.5ag.K.t.w.I#6.Ca7a7#zbE.Iacbc.q.Y#y#y#y#y.G#y.5bK#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y",
|
||||
"bo#y#y#y#y.5#y#y#y#y#y#ybO#r#r.5by.5#y#y#y#y#y#y#y#y#y#y#y#ybO#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y#y"
|
||||
};
|
||||
37
lisp/ess/etc/icons/spluslogo.xpm
Normal file
37
lisp/ess/etc/icons/spluslogo.xpm
Normal file
@@ -0,0 +1,37 @@
|
||||
/* XPM */
|
||||
static char *spluslogo[]={
|
||||
"24 24 10 1",
|
||||
"a c None s backgroundToolBarColor",
|
||||
"g c #000000",
|
||||
"h c #838383",
|
||||
"# c #ce3000",
|
||||
"f c #ce3062",
|
||||
"e c #ce6262",
|
||||
". c #ce629b",
|
||||
"b c #cecece",
|
||||
"d c #ffcece",
|
||||
"c c #ffceff",
|
||||
".##aaaa###aa#aab#a#ba.##",
|
||||
"#a#caaa#db#a#aab#a#bd#a#",
|
||||
"##caaaa#b#.a#aad#a#ba##c",
|
||||
"a.#a##a##.ca#aab#a#daa.#",
|
||||
"ea#aaaa#daaa#aab#a#bbea#",
|
||||
"##.aaaa#daaa###a.f#ac##.",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"aaaaaggga###ahhhaaaaaaaa",
|
||||
"aaaaaggga###ahhhaaaaaaaa",
|
||||
"aaaaaggga###ahhhaaaaaaaa",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"aaaaa###ahhhaaaahhhaaaaa",
|
||||
"aaaaa###ahhhaaaahhhaaaaa",
|
||||
"aaaaa###ahhhaaaahhhaaaaa",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"aaaaahhhaaaahhha###aaaaa",
|
||||
"aaaaahhhaaaahhha###aaaaa",
|
||||
"aaaaahhhaaaahhha###aaaaa",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"aaaaaaaahhha###agggaaaaa",
|
||||
"aaaaaaaahhha###agggaaaaa",
|
||||
"aaaaaaaahhha###agggaaaaa",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaa"};
|
||||
44
lisp/ess/etc/icons/spluslogo.xpm.safe
Normal file
44
lisp/ess/etc/icons/spluslogo.xpm.safe
Normal file
@@ -0,0 +1,44 @@
|
||||
/* XPM */
|
||||
static char *spluslogo[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 24 24 13 1",
|
||||
/* colors */
|
||||
". c #000000",
|
||||
"# c #303062",
|
||||
"a c #494949",
|
||||
"b c #626262",
|
||||
"c c #838383",
|
||||
"d c #ce3000",
|
||||
"e c #ce3062",
|
||||
"f c #ce6262",
|
||||
"g c #ce629b",
|
||||
"h c #cecece",
|
||||
"i c #ffcece",
|
||||
"j c #ffceff",
|
||||
"k c None",
|
||||
/* pixels */
|
||||
"gddkkkkdddiidkkhdkdhkgdd",
|
||||
"dkdjkkkdihdidkkhdkdhidkd",
|
||||
"ddjkkkkdhdgidkkidkdhkddj",
|
||||
"kgdkddkddgjidkkhdkdikkgd",
|
||||
"fkdiiikdikkidkkhdkdhhfkd",
|
||||
"ddgkkkkdikkidddkgedkjddg",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk",
|
||||
"kkkkk...kdddkccckkkkkkkk",
|
||||
"kkkkk...kdddkccckkkkkkkk",
|
||||
"kkkkk...kdddkccckkkkkkkk",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk",
|
||||
"kkkkkdddkccckkkkccckkkkk",
|
||||
"kkkkkdddkccckkkkccckkkkk",
|
||||
"kkkkkdddkccckkkkccckkkkk",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk",
|
||||
"kkkkkccckkkkccckdddkkkkk",
|
||||
"kkkkkccckkkkccckdddkkkkk",
|
||||
"kkkkkccckkkkccckdddkkkkk",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk",
|
||||
"kkkkkkkkccckdddk...kkkkk",
|
||||
"kkkkkkkkccckdddk...kkkkk",
|
||||
"kkkkkkkkccckdddk...kkkkk",
|
||||
"kkkkkkkkkkkkkkkkkkkkkkkk"
|
||||
};
|
||||
161
lisp/ess/etc/icons/startr.xpm
Normal file
161
lisp/ess/etc/icons/startr.xpm
Normal file
@@ -0,0 +1,161 @@
|
||||
/* XPM */
|
||||
static char *rlogo3[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 24 24 130 2",
|
||||
/* colors */
|
||||
".. c None s backgroundToolBarColor",
|
||||
".# c #747684",
|
||||
".a c #acaeac",
|
||||
".b c #8492bc",
|
||||
".c c #94a2c4",
|
||||
".d c #c4cacc",
|
||||
".e c #84868c",
|
||||
".f c #3c424c",
|
||||
".g c #949aac",
|
||||
".h c #bcbec4",
|
||||
".i c #545e74",
|
||||
".j c #d4dae4",
|
||||
".k c #94a2d4",
|
||||
".l c #8492c4",
|
||||
".m c #7486ac",
|
||||
".n c #a4b2d4",
|
||||
".o c #ccd2e4",
|
||||
".p c #9caacc",
|
||||
".q c #8c9ac4",
|
||||
".r c #848eac",
|
||||
".s c #444e64",
|
||||
".t c #949acc",
|
||||
".u c #bcc2ec",
|
||||
".v c #dce2e4",
|
||||
".w c #b4bad4",
|
||||
".x c #5c6674",
|
||||
".y c #d4daec",
|
||||
".z c #9ca2d4",
|
||||
".A c #acbae4",
|
||||
".B c #7c82a4",
|
||||
".C c #6c769c",
|
||||
".D c #d4d2d4",
|
||||
".E c #8c92c4",
|
||||
".F c #7c8eac",
|
||||
".G c #a4b2dc",
|
||||
".H c #545664",
|
||||
".I c #8c92ac",
|
||||
".J c #8c8e94",
|
||||
".K c #949abc",
|
||||
".L c #5c5e74",
|
||||
".M c #7c86ac",
|
||||
".N c #747ea4",
|
||||
".O c #242a34",
|
||||
".P c #9ca2bc",
|
||||
".Q c #8c8a8c",
|
||||
".R c #6c6e7c",
|
||||
".S c #7482b4",
|
||||
".T c #9c9aa4",
|
||||
".U c #b4bedc",
|
||||
".V c #dcdedc",
|
||||
".W c #94a6d4",
|
||||
".X c #8496c4",
|
||||
".Y c #acb2cc",
|
||||
".Z c #ccd2f4",
|
||||
".0 c #8c9ad4",
|
||||
".1 c #848ebc",
|
||||
".2 c #949ed4",
|
||||
".3 c #9ca6dc",
|
||||
".4 c #7c8abc",
|
||||
".5 c #7482a4",
|
||||
".6 c #3c3a3c",
|
||||
".7 c #9ca6bc",
|
||||
".8 c #747a8c",
|
||||
".9 c #acaebc",
|
||||
"#. c #8496b4",
|
||||
"## c #c4cadc",
|
||||
"#a c #545e84",
|
||||
"#b c #747aa4",
|
||||
"#c c #64728c",
|
||||
"#d c #ccd6ec",
|
||||
"#e c #9caadc",
|
||||
"#f c #8c9ecc",
|
||||
"#g c #949ec4",
|
||||
"#h c #bcc6f4",
|
||||
"#i c #9ca6cc",
|
||||
"#j c #8c96c4",
|
||||
"#k c #8c96bc",
|
||||
"#l c #5c6274",
|
||||
"#m c #7c8ab4",
|
||||
"#n c #4c4e6c",
|
||||
"#o c #9c9ea4",
|
||||
"#p c #acb6d4",
|
||||
"#q c #acaeb4",
|
||||
"#r c #848694",
|
||||
"#s c #3c465c",
|
||||
"#t c #bcbecc",
|
||||
"#u c #545e7c",
|
||||
"#v c #d4dee4",
|
||||
"#w c #6c7aa4",
|
||||
"#x c #94a2dc",
|
||||
"#y c #8492cc",
|
||||
"#z c #7486b4",
|
||||
"#A c #646a84",
|
||||
"#B c #9caad4",
|
||||
"#C c #8c9acc",
|
||||
"#D c #848eb4",
|
||||
"#E c #4c4e54",
|
||||
"#F c #bcc6e4",
|
||||
"#G c #5c668c",
|
||||
"#H c #d4deec",
|
||||
"#I c #7c82ac",
|
||||
"#J c #6c7a9c",
|
||||
"#K c #a4aac4",
|
||||
"#L c #d4d6dc",
|
||||
"#M c #a4b2e4",
|
||||
"#N c #545674",
|
||||
"#O c #b4bac4",
|
||||
"#P c #8c96b4",
|
||||
"#Q c #c4c6cc",
|
||||
"#R c #7c86b4",
|
||||
"#S c #2c2e3c",
|
||||
"#T c #bcc2d4",
|
||||
"#U c #ccced4",
|
||||
"#V c #6c727c",
|
||||
"#W c #c4cedc",
|
||||
"#X c #4c526c",
|
||||
"#Y c #747eac",
|
||||
"#Z c #9ca2c4",
|
||||
"#0 c #8c8a94",
|
||||
"#1 c #dcdee4",
|
||||
"#2 c #94a6dc",
|
||||
"#3 c #8496cc",
|
||||
"#4 c #acb2d4",
|
||||
"#5 c #848ec4",
|
||||
"#6 c #dcdef4",
|
||||
"#7 c #7482ac",
|
||||
"#8 c #949ecc",
|
||||
"#9 c #9ca6d4",
|
||||
"a. c #8c96cc",
|
||||
"a# c #5c627c",
|
||||
/* pixels */
|
||||
"................................................",
|
||||
"................................................",
|
||||
".....d.y#H#v.j#v.j#v.y#v#v.j.j#W#F#p............",
|
||||
"....#4.b#J#w#I.P#i#g#Z#8#Z#j#R#Y#ma.#P.j........",
|
||||
".....Y.l.5.X.u.P.i#n.s#n#u#b#8.X.4.4.M#r........",
|
||||
".....Y#y#z.3.G#X.Q.Q.Q#0.J#r#a.b#ja..E.C........",
|
||||
".....Y#y.m.k#8.x.............Y#m.4.2.z.H.T......",
|
||||
".....Y.E.S.k#8#l...............q#z.0.3#N.g......",
|
||||
".....Y.l#z#9.ta#..............#B#Y.k.G.L#Q......",
|
||||
".....Y.E.m.2.t.C............#6.I.F#d.I#s........",
|
||||
".....Y.l#za..l.g#L#1.v#1.o#U#K#P###T#S#o........",
|
||||
".....Y.X#7a.#j.b#C.p.c#..N.C.K#W#r.O.6.D........",
|
||||
".....Y#y#7.2.Z.o.I.B.I#9#f#x#h#s#E#q............",
|
||||
".....Y#j#7.W.u.i.6.f#X#A#j#2#e#X#T..............",
|
||||
".....Y#y.m.k#8#l......#O#G#j#f.F.w..............",
|
||||
".....Y#y#I#x#8#l.........9.N.l#R.1#J#Q..........",
|
||||
".....Y#5#z.k#8#l........#O#c#D#5#5.b.I.V........",
|
||||
"....#4.l#R.k.t#l...........9.N.l#3.E.C.g........",
|
||||
".....Y#y.m#x#8.x.............g.b#3#C.1.C#U......",
|
||||
"....#4.E#k.A#i#l.............7#Y.X#M.p.B.g......",
|
||||
".....Y.1.c.U.K.i..............#G#m.n#p.r.i......",
|
||||
"....#t.8#V#A.R.e...............h.8.R.R.R.#.a....",
|
||||
"................................................",
|
||||
"................................................"
|
||||
};
|
||||
40
lisp/ess/etc/icons/switch_ess.xpm
Normal file
40
lisp/ess/etc/icons/switch_ess.xpm
Normal file
@@ -0,0 +1,40 @@
|
||||
/* XPM */
|
||||
static char *switch_ess[]={
|
||||
"24 24 13 1",
|
||||
". c None s backgroundToolBarColor",
|
||||
"a c #000000",
|
||||
"e c #131313",
|
||||
"# c #1532ed",
|
||||
"d c #313131",
|
||||
"k c #434343",
|
||||
"j c #535353",
|
||||
"h c #707070",
|
||||
"b c #878787",
|
||||
"i c #949494",
|
||||
"g c #a0a0a0",
|
||||
"f c #bfbfbf",
|
||||
"c c #c3c3c3",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"........................",
|
||||
"..###...................",
|
||||
"..###...................",
|
||||
"..###...................",
|
||||
"..###.aaaab.cdedc.cdedc.",
|
||||
"..###.af....ag....ag....",
|
||||
"..###.af....ba....ba....",
|
||||
"..###.aaad...fah...fah..",
|
||||
"..###.af.......ga....ga.",
|
||||
"..###.af....i..jk.i..jk.",
|
||||
"..###.aaaak.jeej..jeej..",
|
||||
"..###...................",
|
||||
"..###...................",
|
||||
"..###...................",
|
||||
"..###...........#.......",
|
||||
"..###...........##......",
|
||||
"..#################.....",
|
||||
"..##################....",
|
||||
"...################.....",
|
||||
"................##......",
|
||||
"................#......."};
|
||||
112
lisp/ess/etc/icons/switchr.xpm
Normal file
112
lisp/ess/etc/icons/switchr.xpm
Normal file
@@ -0,0 +1,112 @@
|
||||
/* XPM */
|
||||
static char *rt4[]={
|
||||
"24 24 85 2",
|
||||
"Qt c None s backgroundToolBarColor",
|
||||
".V c #14162c",
|
||||
".A c #1c263c",
|
||||
"#d c #24263c",
|
||||
".K c #242e44",
|
||||
".H c #2c3244",
|
||||
"#o c #2c3644",
|
||||
".Q c #34364c",
|
||||
".Z c #3c3e54",
|
||||
".N c #3c4264",
|
||||
".q c #444664",
|
||||
".p c #444a64",
|
||||
"#. c #444e64",
|
||||
".r c #4c4e6c",
|
||||
".w c #4c566c",
|
||||
"#m c #545e74",
|
||||
"#j c #546284",
|
||||
".B c #54628c",
|
||||
"#e c #5c6284",
|
||||
".4 c #5c6a9c",
|
||||
"#k c #646a8c",
|
||||
"#p c #646e8c",
|
||||
".5 c #646e9c",
|
||||
".S c #647294",
|
||||
".b c #647a94",
|
||||
".c c #6c769c",
|
||||
".h c #6c7aa4",
|
||||
".3 c #6c7ea4",
|
||||
".k c #747ea4",
|
||||
".O c #7482b4",
|
||||
".u c #7482bc",
|
||||
".i c #7486b4",
|
||||
".X c #7c82a4",
|
||||
".d c #7c86a4",
|
||||
".g c #7c86ac",
|
||||
"#b c #7c86b4",
|
||||
".E c #7c86bc",
|
||||
"#h c #7c8abc",
|
||||
".L c #7c8ac4",
|
||||
".a c #7c8eb4",
|
||||
"## c #848eac",
|
||||
".# c #848ebc",
|
||||
".2 c #8492b4",
|
||||
".m c #8492bc",
|
||||
".l c #8492c4",
|
||||
".I c #8492cc",
|
||||
".t c #8496c4",
|
||||
".f c #8c92b4",
|
||||
".v c #8c92c4",
|
||||
".W c #8c92cc",
|
||||
".7 c #8c96a4",
|
||||
".e c #8c96bc",
|
||||
".F c #8c96c4",
|
||||
"#l c #8c96cc",
|
||||
".y c #8c9ac4",
|
||||
".C c #8c9ad4",
|
||||
"#f c #8c9ed4",
|
||||
".1 c #949ac4",
|
||||
".0 c #949ad4",
|
||||
".D c #949ecc",
|
||||
"#g c #94a2d4",
|
||||
".Y c #9ca6c4",
|
||||
".j c #9caadc",
|
||||
"#a c #9caae4",
|
||||
".J c #a4aae4",
|
||||
".T c #a4aed4",
|
||||
".P c #a4aee4",
|
||||
"#i c #a4b2ec",
|
||||
".9 c #acaebc",
|
||||
".s c #acb2e4",
|
||||
"#n c #acb2ec",
|
||||
".G c #acb6e4",
|
||||
".M c #b4baf4",
|
||||
".o c #b4bedc",
|
||||
"#c c #b4bef4",
|
||||
"#s c #b4c6ec",
|
||||
".n c #bcc2ec",
|
||||
".z c #bcc2fc",
|
||||
".U c #c4cef4",
|
||||
".6 c #ccd2ec",
|
||||
".8 c #ccd2fc",
|
||||
".R c #ccd6ec",
|
||||
"#r c #d4defc",
|
||||
"#q c #d4e2fc",
|
||||
".x c #1532ed",
|
||||
"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
|
||||
"QtQtQtQtQtQtQt.#.a.b.c.d.e.e.e.f.g.h.i.j.kQtQtQt",
|
||||
"QtQtQtQtQtQtQt.l.i.m.n.o.p.q.q.r.g.s.t.u.v.wQtQt",
|
||||
"QtQt.x.x.xQtQt.m.i.y.z.AQtQtQtQtQt.B.#.C.D.rQtQt",
|
||||
"QtQt.x.x.xQtQt.m.E.F.G.HQtQtQtQtQtQt.m.I.J.rQtQt",
|
||||
"QtQt.x.x.xQtQt.#.i.t.s.KQtQtQtQtQtQt.D.L.M.NQtQt",
|
||||
"QtQt.x.x.xQtQt.#.O.y.P.QQtQtQtQtQt.R.S.T.U.VQtQt",
|
||||
"QtQt.x.x.xQtQt.#.i.t.W.FQtQtQtQtQt.X.Y.U.ZQtQtQt",
|
||||
"QtQt.x.x.xQtQt.#.i.m.0.1.t.2.3.4.5.6.7.VQtQtQtQt",
|
||||
"QtQt.x.x.xQtQt.#.i.l.8.9.Q#.##.P#a.GQtQtQtQtQtQt",
|
||||
"QtQt.x.x.xQtQt.##b.t#c#dQtQtQt#e#f#g.SQtQtQtQtQt",
|
||||
"QtQt.x.x.xQtQt.##h.t#i.KQtQtQtQt#b.m#h.aQtQtQtQt",
|
||||
"QtQt.x.x.xQtQt.#.O.t#i.KQtQtQtQt#j.#.l.l#kQtQtQt",
|
||||
"QtQt.x.x.xQtQt.F.O.y.s.HQtQtQtQtQt#b.l#l.##mQtQt",
|
||||
"QtQt.x.x.xQtQt.##b.F#n#oQtQtQtQtQt#j.F#f.m#pQtQt",
|
||||
"QtQt.x.x.xQtQt.#.t#q#r.KQtQtQtQtQtQt.i#s#q.YQtQt",
|
||||
"QtQt.x.x.xQtQtQtQtQtQtQtQtQtQtQt.xQtQtQtQtQtQtQt",
|
||||
"QtQt.x.x.xQtQtQtQtQtQtQtQtQtQtQt.x.xQtQtQtQtQtQt",
|
||||
"QtQt.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.xQtQtQtQtQt",
|
||||
"QtQt.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.xQtQtQtQt",
|
||||
"QtQtQt.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.xQtQtQtQtQt",
|
||||
"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.x.xQtQtQtQtQtQt",
|
||||
"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt.xQtQtQtQtQtQtQt"};
|
||||
32
lisp/ess/etc/icons/switchs.xpm
Normal file
32
lisp/ess/etc/icons/switchs.xpm
Normal file
@@ -0,0 +1,32 @@
|
||||
/* XPM */
|
||||
static char *switchs[]={
|
||||
"24 24 5 1",
|
||||
". c None",
|
||||
"# c #000000",
|
||||
"c c #1532ed",
|
||||
"b c #838383",
|
||||
"a c #ce3000",
|
||||
"........................",
|
||||
"........###.aaa.bbb.....",
|
||||
"........###.aaa.bbb.....",
|
||||
"........###.aaa.bbb.....",
|
||||
"..ccc...................",
|
||||
"..ccc...aaa.bbb....bbb..",
|
||||
"..ccc...aaa.bbb....bbb..",
|
||||
"..ccc...aaa.bbb....bbb..",
|
||||
"..ccc...................",
|
||||
"..ccc...bbb....bbb.aaa..",
|
||||
"..ccc...bbb....bbb.aaa..",
|
||||
"..ccc...bbb....bbb.aaa..",
|
||||
"..ccc...................",
|
||||
"..ccc......bbb.aaa.###..",
|
||||
"..ccc......bbb.aaa.###..",
|
||||
"..ccc......bbb.aaa.###..",
|
||||
"..ccc...................",
|
||||
"..ccc...........c.......",
|
||||
"..ccc...........cc......",
|
||||
"..ccccccccccccccccc.....",
|
||||
"..cccccccccccccccccc....",
|
||||
"...cccccccccccccccc.....",
|
||||
"................cc......",
|
||||
"................c......."};
|
||||
17
lisp/ess/license.info
Normal file
17
lisp/ess/license.info
Normal file
@@ -0,0 +1,17 @@
|
||||
This is license.info, produced by makeinfo version 6.5 from
|
||||
license.texi.
|
||||
|
||||
The source and documentation of ESS is free software. You can
|
||||
redistribute it and/or modify it under the terms of the GNU General
|
||||
Public License as published by the Free Software Foundation; either
|
||||
version 2, or (at your option) any later version.
|
||||
|
||||
ESS is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License in
|
||||
the file COPYING in the same directory as this file for more details.
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
21
lisp/ess/mailing.info
Normal file
21
lisp/ess/mailing.info
Normal file
@@ -0,0 +1,21 @@
|
||||
This is mailing.info, produced by makeinfo version 6.5 from
|
||||
mailing.texi.
|
||||
|
||||
There is a mailing list for discussions and announcements relating to
|
||||
ESS. Join the list by sending an e-mail with "subscribe ess-help" (or
|
||||
"help") in the body to <ess-help-request@r-project.org>; contributions
|
||||
to the list may be mailed to <ess-help@r-project.org>. Rest assured,
|
||||
this is a fairly low-volume mailing list.
|
||||
|
||||
The purposes of the mailing list include
|
||||
|
||||
* helping users of ESS to get along with it.
|
||||
* discussing aspects of using ESS.
|
||||
* suggestions for improvements.
|
||||
* announcements of new releases of ESS.
|
||||
* posting small patches to ESS.
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
449
lisp/ess/news.info
Normal file
449
lisp/ess/news.info
Normal file
@@ -0,0 +1,449 @@
|
||||
This is news.info, produced by makeinfo version 6.5 from news.texi.
|
||||
|
||||
Changes and New Features in 19.04 (unreleased):
|
||||
|
||||
* ESS[R]: Automatic offsetting of R process output is now disabled by
|
||||
default because it produces undesirable output in some situations.
|
||||
To re-enable, set 'inferior-ess-fix-misaligned-output' to t.
|
||||
|
||||
* ESS[R]: Improved 'xref' lookup ('M-.'). Function locations are now
|
||||
always detected for package libraries listed in
|
||||
'ess-r-package-library-paths'.
|
||||
|
||||
* ESS[R]: Evaluated lines starting with the Roxygen prefix are now
|
||||
always stripped from the prefix, so they can be sent to the process
|
||||
easily. Previously, this was only the case inside the 'examples'
|
||||
field. Since roxygen is switching to R markdown, it becomes useful
|
||||
to evaluate chunks of R outside examples.
|
||||
|
||||
* stata support is now obsolete since we were unable to elicit FSF
|
||||
paperwork from some of the original authors: see the lisp/obsolete
|
||||
sub-directory on the ESS github repo
|
||||
|
||||
* 'ess-set-working-directory' no longer changes the active directory
|
||||
(as defined by the buffer-local variable 'default-directory') of
|
||||
the buffer where the command is called. Instead, the active
|
||||
directory of the inferior buffer is updated to the new working
|
||||
directory.
|
||||
|
||||
* The default of ess-eval-visibly is now ''nowait'. With this change
|
||||
you should no longer experience freezes while evaluating code.
|
||||
|
||||
* ESS[R]: There is a new menu entry for reloading the R process. It
|
||||
is otherwise bound to 'C-c C-e C-r'. Reloading now reuses the same
|
||||
process name and start arguments that were used to start the
|
||||
process.
|
||||
|
||||
* iESS: Process runners now return the inferior buffer. Note that
|
||||
callers of inferior runners should not assume that the current
|
||||
buffer has been set to the inferior buffer. Instead, use
|
||||
'with-current-buffer' with the return value of the inferior.
|
||||
|
||||
* iESS[SAS]: The SAS keymap was only set in iESS buffers called
|
||||
'*SAS*'. This is now fixed.
|
||||
|
||||
* ESS[R]: Fixed longstanding indentation issues involving '::' and
|
||||
':::' operators.
|
||||
|
||||
* Implement a more reliable check for the process busy state.
|
||||
Background actions such as completion and directory synchronization
|
||||
should not block the process and should not cause printing of the
|
||||
extraneous output to the interpreter.
|
||||
|
||||
* Activate 'goto-address-mode' for url and email highlighting in
|
||||
inferior buffers.
|
||||
|
||||
* 'smart-underscore' and 'ess-smart-S-assign-key' have been removed.
|
||||
Users who liked the previous behavior (i.e. underscore inserting
|
||||
"<-") should bind 'ess-insert-assign' to the underscore in their
|
||||
Emacs initialization file. For example, '(define-key
|
||||
ess-r-mode-map "_" #'ess-insert-assign)' and '(define-key
|
||||
inferior-ess-r-mode-map "_" #'ess-insert-assign)' will activate it
|
||||
in all ESS R buffers.
|
||||
|
||||
* ESS major modes are now defined using 'define-derived-mode'. This
|
||||
makes ESS major modes respect modern conventions such as having
|
||||
<language>-mode-hook and <language>-mode-map. Users are encouraged
|
||||
to place customizations under the appropriate mode.
|
||||
|
||||
* New option ess-auto-width controls setting the width option on
|
||||
window changes. Users can change it to 'frame, 'window, or an
|
||||
integer. See the documentation for details.
|
||||
'ess-auto-width-visible' controls visibility.
|
||||
|
||||
* ESS now respects 'display-buffer-alist'. Users can now use
|
||||
'display-buffer-alist' to manage how and where windows appear. For
|
||||
more information and examples, see *Note (ess)Controlling buffer
|
||||
display::.
|
||||
|
||||
* 'ess-roxy-mode' can now be enabled in non-R buffers. This is
|
||||
primarily intended to support roxygen documentation for cpp
|
||||
buffers. Preview functionality is not supported outside R buffers.
|
||||
|
||||
* ESS[R]: DESCRIPTION files now open in 'conf-colon-mode'.
|
||||
|
||||
* 'ess-style' now has effects when set as a file or directory local
|
||||
variable.
|
||||
|
||||
* 'ess-default-style' is now obsolete, use 'ess-style' instead.
|
||||
|
||||
* Options for 'ess-gen-proc-buffer-name-function' have been renamed.
|
||||
ess-gen-proc-buffer-name:projectile-or-simple was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-simple and
|
||||
ess-gen-proc-buffer-name:projectile-or-directory was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-directory. As the name
|
||||
suggests, these now rely on project.el (included with Emacs) rather
|
||||
than projectile.el, which is a third-party package.
|
||||
|
||||
* Eldoc fully honors 'eldoc-echo-area-use-multiline-p'
|
||||
|
||||
* ESS[R]: 'ess-r-rhub-check-package' gained new 'RECOMMENDED'.
|
||||
|
||||
* ESS[R]: devtools commands ask about saving modified buffers before
|
||||
running. Users can disable the questioning with
|
||||
'ess-save-silently'.
|
||||
|
||||
* ESS[R] help pages now provide links to other help topics. This is
|
||||
similar with what you would see with, for example
|
||||
'options(help_type = ``html'')' but works with the plain-text
|
||||
version as well. This only works with 'options(useFancyQuotes =
|
||||
TRUE)' (the default).
|
||||
|
||||
* 'ess-rdired' buffers now derive from tabulated-list-mode. They
|
||||
should look better and be a bit faster overall. The size column
|
||||
now displays object sizes in bytes.
|
||||
|
||||
* 'ess-rdired' buffers now auto-update. The frequency is governed by
|
||||
the new option 'ess-rdired-auto-update-interval'.
|
||||
|
||||
* ESS[R]: 'electric-layout-mode' is now supported. This
|
||||
automatically inserts a newline after an opening curly brace in R
|
||||
buffers. To enable it, customize 'ess-r-mode-hook'.
|
||||
|
||||
* ESS[R]: imenu now supports assignment with the equals sign.
|
||||
|
||||
* ESS[Rd]: Rd no longer writes abbrevs to user's abbrev file.
|
||||
|
||||
* ESS removed support for many unused languages. This includes old
|
||||
versions of S+, ARC, OMG, VST, and XLS.
|
||||
|
||||
* ess-r-runner-prefixes was modified to find R-4 and later.
|
||||
|
||||
The following have been made obsolete or removed, see their
|
||||
documentation for more detail:
|
||||
|
||||
* Libraries for literate data analysis are obsolete and not loaded by
|
||||
default. This includes 'ess-noweb', 'ess-swv', and related
|
||||
functionality like 'Rnw-mode'. Users are encouraged to switch to
|
||||
one of several other packages that deal with these modes. For
|
||||
example, polymode <https://github.com/polymode/poly-R/>,
|
||||
<https://polymode.github.io/>, or markdown-mode with edit-indirect
|
||||
<https://jblevins.org/projects/markdown-mode>.
|
||||
|
||||
* Support for 'auto-complete' is obsolete. The 'auto-complete'
|
||||
package is unmaintained and so ESS support is now obsolete. Users
|
||||
are encouraged to switch to 'company-mode' instead.
|
||||
|
||||
* User options for controlling display of buffers. This includes
|
||||
'ess-show-buffer-action', 'inferior-ess-same-window',
|
||||
'inferior-ess-own-frame', and 'inferior-ess-frame-alist'. See
|
||||
above about ESS respecting 'display-buffer-alist'.
|
||||
|
||||
* Variables 'ess-tab-always-indent' and 'ess-tab-complete-in-script'.
|
||||
Use the Emacs-wide setting of 'tab-always-indent' instead.
|
||||
|
||||
* 'inferior-ess-*-start-file' variables. All modes except Stata did
|
||||
not respect customization of this variable. In order to load a
|
||||
file on startup, you should put a function on
|
||||
'ess-*-post-run-hook'.
|
||||
|
||||
Bug Fixes in 18.10.3:
|
||||
* More 'Makefile' fixes, notably installing '*.el's.
|
||||
|
||||
Bug Fixes in 18.10.2:
|
||||
* ESS[R] Fix namespace evaluation in non-installed packages.
|
||||
Evaluation is directed into GlobalEnv as originally intended.
|
||||
* 'Makefile' fixes, notably for 'make install' and including full
|
||||
docs in the tarballs.
|
||||
|
||||
Bug Fixes in 18.10-1:
|
||||
* New functions 'ess-eval-line-visibly-and-step' ('C-c C-n' and
|
||||
'ess-eval-region-or-line-visibly-and-step' ('C-RET') which behave
|
||||
as the old versions of 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step'.
|
||||
|
||||
Changes and New Features in 18.10:
|
||||
|
||||
* This is the last release to support Emacs older than 25.1. Going
|
||||
forward, only GNU Emacs 25.1 and newer will be supported. Soon
|
||||
after this release, support for older Emacs versions will be
|
||||
dropped from the git master branch. Note that MELPA uses the git
|
||||
master branch to produce ESS snapshots, so if you are using Emacs <
|
||||
25.1 from MELPA and are unable to upgrade, you should switch to
|
||||
MELPA-stable.
|
||||
|
||||
* ESS now displays the language dialect in the mode-line. So, for
|
||||
example, R buffers will now show ESS[R] rather than ESS[S].
|
||||
|
||||
* The ESS manual has been updated and revised.
|
||||
|
||||
* The ESS initialization process has been further streamlined. If
|
||||
you update the autoloads (which installation from 'package-install'
|
||||
does), you should not need to '(require 'ess-site)' at all, as
|
||||
autoloads should automatically load ESS when it is needed (e.g.
|
||||
the first time an R buffer is opened). In order to defer loading
|
||||
your ESS config, you may want to do something like
|
||||
'(with-require-after-load "ess" <ess-config-here>)' in your Emacs
|
||||
init file. Users of the popular 'use-package' Emacs package can
|
||||
now do '(use-package ess :defer t)' to take advantage of this
|
||||
behavior. For more information on this feature, see *Note
|
||||
(ess)Activating and Loading ESS::.
|
||||
|
||||
* ESS now respects Emacs conventions for keybindings. This means
|
||||
that The 'C-c [letter]' bindings have been removed. This affects
|
||||
'C-c h', which was bound to 'ess-eval-line-and-step-invisibly' in
|
||||
'sas-mode-local-map'; 'C-c f', which was bound to
|
||||
'ess-insert-function-outline' in 'ess-add-MM-keys'; and 'C-c h',
|
||||
which was bound to 'ess-handy-commands' in 'Rd-mode-map',
|
||||
'ess-noweb-minor-mode-map', and 'ess-help-mode-map'
|
||||
|
||||
* Functions 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step' now behave consistently with
|
||||
other evaluation function inside a package.
|
||||
|
||||
* ESS[R]: 'ess-r-package-use-dir' now works with any mode. This sets
|
||||
the working directory to the root of the current package including
|
||||
for example C or C++ files within '/src').
|
||||
|
||||
* ESS[R]: Long + + prompts in the inferior no longer offset output.
|
||||
|
||||
* ESS[R]: New option 'strip' for 'inferior-ess-replace-long+'. This
|
||||
strips the entire + + sequence.
|
||||
|
||||
* ESS modes now inherit from 'prog-mode'. In the next release, ESS
|
||||
modes will use 'define-derived-mode' so that each mode will have
|
||||
(for example) its own hooks and keymaps.
|
||||
|
||||
* ESS[R]: Supports flymake in R buffers for Emacs 26 and newer.
|
||||
Users need to install the 'lintr' package to use it. Customizable
|
||||
options include 'ess-use-flymake', 'ess-r-flymake-linters', and
|
||||
'ess-r-flymake-lintr-cache'.
|
||||
|
||||
* ESS[R]: Gained support for xref in Emacs 25+ *Note (emacs)Xref::.
|
||||
|
||||
* ESS[R]: The startup screen is cleaner. It also displays the
|
||||
startup directory with an explicit 'setwd()'.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[R]: 'Makevars' files open with 'makefile-mode'.
|
||||
|
||||
* New variable 'ess-write-to-dribble'. This allows users to disable
|
||||
the dribble ('*ESS*') buffer if they wish.
|
||||
|
||||
* All of the '*-program-name' variables have been renamed to
|
||||
'*-program'. Users who previously customized e.g.
|
||||
'inferior-ess-R-program-name' will need to update their
|
||||
customization to 'inferior-ess-R-program'. These variables are
|
||||
treated as risky variables.
|
||||
|
||||
* 'ess-smart-S-assign' was renamed to 'ess-insert-assign'. It
|
||||
provides similar functionality but for any keybinding, not just
|
||||
'_'. For instance if you bind it to ';', repeated invocations
|
||||
cycle through between assignment and inserting ';'.
|
||||
|
||||
* 'C-c C-=' is now bound to 'ess-cycle-assign' by default. See the
|
||||
documentation for details. New user customization option
|
||||
'ess-assign-list' controls which assignment operators are cycled.
|
||||
|
||||
* ESS[R] In remote sessions, the ESSR package is now fetched from
|
||||
GitHub.
|
||||
|
||||
* Commands that send the region to the inferior process now deal with
|
||||
rectangular regions. See the documentation of 'ess-eval-region'
|
||||
for details. This only works on Emacs 25.1 and newer.
|
||||
|
||||
* ESS[R]: Improvements to interacting with iESS in non-R files.
|
||||
Interaction with inferior process in non-R files within packages
|
||||
(for instance C or C++ files) has been improved. This is a work in
|
||||
progress.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[JAGS]: *.jog and *.jmd files no longer automatically open in
|
||||
JAGS mode.
|
||||
|
||||
Many improvements to fontification:
|
||||
|
||||
* Improved customization for faces. ESS now provides custom faces
|
||||
for (nearly) all faces used and places face customization options
|
||||
into their own group. Users can customize these options using 'M-x
|
||||
customize-group RET ess-faces'.
|
||||
|
||||
* Many new keywords were added to 'ess-R-keywords' and
|
||||
'ess-R-modifiers'. See the documentation for details.
|
||||
|
||||
* ESS[R]: 'in' is now only fontified when inside a 'for' construct.
|
||||
This avoids spurious fontification, especially in the output buffer
|
||||
where 'in' is a common English word.
|
||||
|
||||
* ESS: Font-lock keywords are now generated lazily. That means you
|
||||
can now add or remove keywords from variables like 'ess-R-keywords'
|
||||
in your Emacs configuration file after loading ESS (i.e. in the
|
||||
':config' section for 'use-package' users).
|
||||
|
||||
* ESS[R]: Fontification of roxygen '@param' keywords now supports
|
||||
comma-separated parameters.
|
||||
|
||||
* ESS[R]: Certain keywords are only fontified if followed by a
|
||||
parenthesis. Function-like keywords such as 'if ()' or 'stop()'
|
||||
are no longer fontified as keyword if not followed by an opening
|
||||
parenthesis. The same holds for search path modifiers like
|
||||
'library()' or 'require()'.
|
||||
|
||||
* ESS[R]: Fixed fontification toggling. Especially certain syntactic
|
||||
elements such as '%op%' operators and backquoted function
|
||||
definitions.
|
||||
|
||||
* ESS[R]: 'ess-font-lock-toggle-keyword' can be called interactively.
|
||||
This command asks with completion for a font-lock group to toggle.
|
||||
This functionality is equivalent to the font-lock menu.
|
||||
|
||||
Notable bug fixes:
|
||||
|
||||
* 'prettify-symbols-mode' no longer breaks indentation. This is
|
||||
accomplished by having the pretty symbols occupy the same number of
|
||||
characters as their non-pretty cousins. You may customize the new
|
||||
variable 'ess-r-prettify-symbols' to control this behavior.
|
||||
|
||||
* ESS: Inferior process buffers are now always displayed on startup.
|
||||
Additionally, they don't hang Emacs on failures.
|
||||
|
||||
Obsolete libraries, functions, and variables:
|
||||
|
||||
* The 'ess-r-args.el' library has been obsoleted and will be removed
|
||||
in the next release. Use 'eldoc-mode' instead, which is on by
|
||||
default.
|
||||
|
||||
* Functions and options dealing with the smart assign key are
|
||||
obsolete. The following functions have been made obsolete and will
|
||||
be removed in the next release of ESS: 'ess-smart-S-assign',
|
||||
'ess-toggle-S-assign', 'ess-toggle-S-assign-key',
|
||||
'ess-disable-smart-S-assign'.
|
||||
|
||||
The variable 'ess-smart-S-assign-key' is now deprecated and will be
|
||||
removed in the next release. If you would like to continue using
|
||||
'_' for inserting assign in future releases, please bind
|
||||
'ess-insert-assign' in 'ess-mode-map' the normal way.
|
||||
|
||||
* ESS[S]: Variable 'ess-s-versions-list' is obsolete and ignored.
|
||||
Use 'ess-s-versions' instead. You may pass arguments by starting
|
||||
the inferior process with the universal argument.
|
||||
|
||||
Changes and New Features in 17.11:
|
||||
|
||||
* The ESS initialization process has been streamlined. You can now
|
||||
load the R and Stata modes independently from the rest of ESS. Just
|
||||
put '(require 'ess-r-mode)' or '(require 'ess-stata-mode)' in your
|
||||
init file. This is for experienced Emacs users as this requires
|
||||
setting up autoloads for '.R' files manually. We will keep
|
||||
maintaining 'ess-site' for easy loading of all ESS features.
|
||||
|
||||
* Reloading and quitting the process is now more robust. If no
|
||||
process is attached, ESS now switches automatically to one
|
||||
(prompting you for selection if there are several running).
|
||||
Reloading and quitting will now work during a debug session or when
|
||||
R is prompting for input (for instance after a crash). Finally,
|
||||
the window configuration is saved and restored after reloading to
|
||||
prevent the buffer of the new process from capturing the cursor.
|
||||
|
||||
* ESS[R]: New command 'ess-r-package-use-dir'. It sets the working
|
||||
directory of the current process to the current package directory.
|
||||
|
||||
* ESS[R] Lookup for references in inferior buffers has been improved.
|
||||
New variable 'ess-r-package-source-roots' contains package
|
||||
sub-directories which are searched recursively during the file
|
||||
lookup point. Directories in 'ess-tracebug-search-path' are now
|
||||
also searched recursively.
|
||||
|
||||
* ESS[R] Namespaced evaluation is now automatically enabled only in
|
||||
the 'R/' directory. This way ESS will not attempt to update
|
||||
function definitions from a package if you are working from e.g. a
|
||||
test file.
|
||||
|
||||
Changes and New Features in 16.10:
|
||||
|
||||
* ESS[R]: Syntax highlighting is now more consistent. Backquoted
|
||||
names are not fontified as strings (since they really are
|
||||
identifiers). Furthermore they are now correctly recognized when
|
||||
they are function definitions or function calls.
|
||||
* ESS[R]: Backquoted names and '%op%' operators are recognized as
|
||||
sexp. This is useful for code navigation, e.g. with 'C-M-f' and
|
||||
'C-M-b'.
|
||||
* ESS[R]: Integration of outline mode with roxygen examples fields.
|
||||
You can use outline mode's code folding commands to fold the
|
||||
examples field. This is especially nice to use with well
|
||||
documented packages with long examples set. Set
|
||||
'ess-roxy-fold-examples' to non-nil to automatically fold the
|
||||
examples field when you open a buffer.
|
||||
* ESS[R]: New experimental feature: syntax highlighting in roxygen
|
||||
examples fields. This is turned off by default. Set
|
||||
'ess-roxy-fontify-examples' to non-nil to try it out.
|
||||
* ESS[R]: New package development command 'ess-r-devtools-ask' bound
|
||||
to 'C-c C-w C-a'. It asks with completion for any devtools command
|
||||
that takes 'pkg' as argument.
|
||||
* ESS[R]: New command 'C-c C-e C-r' to reload the inferior process.
|
||||
Currently only implemented for R. The R method runs
|
||||
'inferior-ess-r-reload-hook' on reloading.
|
||||
* ESS[R]: 'ess-r-package-mode' is now activated in non-file buffers
|
||||
as well.
|
||||
|
||||
Bug fixes in 16.10:
|
||||
* ESS[R]: Fix broken (un)flagging for debugging inside packages
|
||||
* ESS[R]: Fixes (and improvements) in Package development
|
||||
* ESS[R]: Completion no longer produces '...=' inside 'list( )'.
|
||||
* ESS[R]: Better debugging and tracing in packages.
|
||||
* ESS[R]: Better detection of symbols at point.
|
||||
* ESS[R]: No more spurious warnings on deletion of temporary files.
|
||||
* ESS[julia]: help and completion work (better)
|
||||
* ESS[julia]: available via 'ess-remote'
|
||||
|
||||
Changes and New Features in 16.04:
|
||||
|
||||
* ESS[R]: 'developer' functionality has been refactored. The new
|
||||
user interface consists of a single command
|
||||
'ess-r-set-evaluation-env' bound by default to 'C-c C-t C-s'. Once
|
||||
an evaluation environment has been set with, all subsequent ESS
|
||||
evaluation will source the code into that environment. By default,
|
||||
for file within R packages the evaluation environment is set to the
|
||||
package environment. Set 'ess-r-package-auto-set-evaluation-env'
|
||||
to 'nil' to disable this.
|
||||
* ESS[R]: New 'ess-r-package-mode' This development mode provides
|
||||
features to make package development easier. Currently, most of
|
||||
the commands are based on the 'devtools' packages and are
|
||||
accessible with 'C-c C-w' prefix. See the documentation of
|
||||
'ess-r-package-mode' function for all available commands. With
|
||||
'C-u' prefix each command asks for extra arguments to the
|
||||
underlying devtools function. This mode is automatically enabled
|
||||
in all files within R packages and is indicated with '[pkg:NAME]'
|
||||
in the mode-line.
|
||||
* ESS[R]: Help lookup has been improved. It is now possible to get
|
||||
help for namespaced objects such as pkg::foobar. Furthermore, ESS
|
||||
recognizes more reliably when you change 'options('html_type')'.
|
||||
* ESS[R]: New specialized breakpoints for debugging magrittr pipes
|
||||
* ESS: ESS now implements a simple message passing interface to
|
||||
communicate between ESS and inferior process.
|
||||
|
||||
Bug fixes in 16.04:
|
||||
* ESS[R]: Roxygen blocks with backtics are now correctly filled
|
||||
* ESS[R]: Don't skip breakpoints in magrittr's 'debug_pipe'
|
||||
* ESS[R]: Error highlighting now understands 'testthat' type errors
|
||||
* ESS[Julia]: Added getwd and setwd generic commands
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
173
lisp/ess/obsolete/ess-eldoc.el
Normal file
173
lisp/ess/obsolete/ess-eldoc.el
Normal file
@@ -0,0 +1,173 @@
|
||||
;;; ess-eldoc.el --- Use eldoc to report R function names.
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
;; Author: Stephen Eglen
|
||||
;; Created: 2007-06-30
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;;;; eldoc funcitonality has been moved into the core ;;;;;
|
||||
;;;;; this file has no effect and is left in ESS in order not to break
|
||||
;;;;; users configuration
|
||||
|
||||
;; This is an initial attempt to use the emacs facility ELDOC in R
|
||||
;; buffers. Eldoc is used in Emacs lisp buffers to show the function
|
||||
;; arglist and docstrings for variables. To try it, view an emacs
|
||||
;; lisp buffer, and then do M-x turn-on-eldoc-mode, and move over
|
||||
;; function and variable names.
|
||||
|
||||
;; This file extends eldoc to work in R buffers. It currently uses
|
||||
;; Sven's ess-r-args.el file to retrieve args for a given R function
|
||||
;; (via ess-r-args-get). Note that it works slightly different to
|
||||
;; Sven's code, in that you just need to have the point over the name
|
||||
;; of an R function, or inside its arguments list, for eldoc to show
|
||||
;; the arg list.
|
||||
|
||||
;; To use this functionality, simply add
|
||||
;;
|
||||
;; (require 'ess-eldoc)
|
||||
;;
|
||||
;; to your .emacs file. When you visit a R mode, eldoc will be turned
|
||||
;; on. However, you will first need to associate the R buffer with an
|
||||
;; *R* process so that args can be looked up -- otherwise, eldoc will
|
||||
;; silently not report anything. So, e.g. try:
|
||||
;; C-x C-f somefile.R
|
||||
;; M-x R (so that somefile.R is associated with *R*)
|
||||
;; eldoc should then work.
|
||||
|
||||
;; e.g. put the following rnorm() command in an R buffer. The line
|
||||
;; underneath shows a key of what arg list will be shown as you move
|
||||
;; across the rnorm line.
|
||||
|
||||
;; rnorm(n=100, mean=sqrt(20), sd=10)
|
||||
;; 1111111111111222223333333311444111
|
||||
;; 1: rnorm
|
||||
;; 2: mean
|
||||
;; 3: sqrt
|
||||
;; 4: sd
|
||||
;;
|
||||
|
||||
;; Note that the arg list for rnorm() should be shown either when you
|
||||
;; are on the function name, or in the arg list. However, since the
|
||||
;; 2nd and 3rd arguments are also function names, the arg lists of
|
||||
;; those function names are reported instead. This might be seen as
|
||||
;; undesirable behaviour, in which case a solution would be to only
|
||||
;; look up the function name if it is followed by (.
|
||||
|
||||
;; If you want to use this feature in *R* buffers, add the following
|
||||
;; to .emacs:
|
||||
;; (add-hook 'inferior-ess-mode-hook 'ess-use-eldoc)
|
||||
|
||||
|
||||
;; In the current version, I do not cache the arg list, but that was
|
||||
;; done in an earlier version, to save repeated calls to
|
||||
;; ess-r-args-get.
|
||||
|
||||
;; This code has been tested only in Emacs 22.1. It will not work on
|
||||
;; Emacs 21, because it needs the variable
|
||||
;; eldoc-documentation-function.
|
||||
|
||||
;;;; VS [25-02-2012]: all these issues were at least partially addresed in the
|
||||
;;;; new implementation:
|
||||
|
||||
;; Bug (in eldoc?): the arg list for legend() is too long to fit in
|
||||
;; minibuffer, and it seems that we see the last N lines of the arg
|
||||
;; list, rather than the first N lines. It would be better to see the
|
||||
;; first N lines since the more important args come first.
|
||||
|
||||
;; Doc issue: the eldoc vars (e.g. eldoc-echo-area-use-multiline-p)
|
||||
;; work only for elisp mode.
|
||||
|
||||
;; Issue: You will probably see the message "Using process 'R'" flash;
|
||||
;; this is generated by `ess-request-a-process', and I'd like to avoid
|
||||
;; that appearing, non-interactively.
|
||||
|
||||
;; If *R* is currently busy (e.g. processing Sys.sleep(999)), then the
|
||||
;; eldoc commands won't work; ess-command could be silenced in this
|
||||
;; regard perhaps with a new SILENT arg for example to prevent the
|
||||
;; call to (ess-error).
|
||||
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; ;; This could be done on buffer local basis.
|
||||
;; (setq ess-r-args-noargsmsg "")
|
||||
|
||||
;; ;; following two defvars are not currently used.
|
||||
;; (defvar ess-eldoc-last-name nil
|
||||
;; "Name of the last function looked up in eldoc.
|
||||
;; We remember this to see whether we need to look up documentation, or used
|
||||
;; the cached value in `ess-eldoc-last-args'.")
|
||||
|
||||
;; (defvar ess-eldoc-last-args nil
|
||||
;; "Args list last looked up for eldoc. Used as cache.")
|
||||
|
||||
;; (defun ess-eldoc-2 ()
|
||||
;; ;; simple, old version.
|
||||
;; (interactive)
|
||||
;; (ess-r-args-get (ess-read-object-name-default)))
|
||||
|
||||
;; (defun ess-eldoc-1 ()
|
||||
;; "Return the doc string, or nil.
|
||||
;; This is the first version; works only on function name, not within arg list."
|
||||
;; (interactive)
|
||||
|
||||
;; ;; Possible ways to get the function at point.
|
||||
;; ;;(setq name (thing-at-point 'sexp))
|
||||
;; ;;(setq name (ess-read-object-name-default))
|
||||
;; ;;(setq name (find-tag-default))
|
||||
|
||||
;; (if ess-current-process-name
|
||||
;; (progn
|
||||
;; (setq name (ess-guess-fun)) ;guess the word at point.
|
||||
;; (if (equal (length name) 0)
|
||||
;; nil
|
||||
;; ;; else
|
||||
;; (unless (equal name ess-eldoc-last-name)
|
||||
;; ;; name is different to the last name we lookedup, so get
|
||||
;; ;; new args from R and store them.
|
||||
;; (setq ess-eldoc-last-args (ess-r-args-get name)
|
||||
;; ess-eldoc-last-name name))
|
||||
;; ess-eldoc-last-args))
|
||||
;; ;; no ESS process current.
|
||||
;; nil)
|
||||
;; )
|
||||
|
||||
|
||||
;; (defsubst ess-guess-fun ()
|
||||
;; "Guess what the function at point is."
|
||||
;; ;; Derived from Man-default-man-entry in man.el
|
||||
;; (let (word)
|
||||
;; (save-excursion
|
||||
;; (skip-chars-backward "-a-zA-Z0-9._+:")
|
||||
;; (let ((start (point)))
|
||||
;; (skip-chars-forward "-a-zA-Z0-9._+:")
|
||||
;; (setq word (buffer-substring-no-properties start (point)))))
|
||||
;; word))
|
||||
|
||||
(defun ess-use-eldoc ()
|
||||
"Does nothing. Defined not to break old users' code."
|
||||
(interactive))
|
||||
|
||||
(provide 'ess-eldoc)
|
||||
|
||||
;;; ess-eldoc.el ends here
|
||||
222
lisp/ess/obsolete/ess-mouse.el
Normal file
222
lisp/ess/obsolete/ess-mouse.el
Normal file
@@ -0,0 +1,222 @@
|
||||
;;; ess-mouse.el --- Support for mouse- or cursor-sensitive actions
|
||||
|
||||
;; Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
;; Author: Richard M. Heiberger <rmh@temple.edu>
|
||||
;; Created: 25 Mar 2001
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Support for mouse- or cursor-sensitive actions. This is based on
|
||||
;; and uses mouseme.el. mouseme.el only does mouse sensititivity.
|
||||
;; The new functions ess-mouse-me and ess-mouse-me-helper do similar
|
||||
;; things based on the cursor, not the mouse, and can be bound to a
|
||||
;; keystroke.
|
||||
|
||||
;;; Code:
|
||||
|
||||
; Requires and autoloads
|
||||
|
||||
;;*;; Requires
|
||||
(require 'mouseme)
|
||||
(require 'ess-trns)
|
||||
;;(if (or (equal window-system 'w32)
|
||||
;; (equal window-system 'win32)
|
||||
;; (equal window-system 'mswindows))
|
||||
;; (require 'essiw32b))
|
||||
|
||||
(defun ess-mouse-me ()
|
||||
"Popup a menu of functions to run on selected string or region."
|
||||
(interactive)
|
||||
(ess-mouse-me-helper
|
||||
(lambda (name)
|
||||
(or (x-popup-menu (list '(0 0)
|
||||
(get-buffer-window (get-buffer (buffer-name))))
|
||||
(funcall mouse-me-build-menu-function name))
|
||||
(error "No command to run")))))
|
||||
|
||||
|
||||
|
||||
(defun ess-mouse-me-helper (func)
|
||||
"Determine the string to use to process EVENT and call FUNC to get cmd."
|
||||
(let (name sp sm mouse beg end cmd mmtype)
|
||||
;; temporarily goto where the event occurred, get the name clicked
|
||||
;; on and enough info to figure out what to do with it
|
||||
(save-match-data
|
||||
(save-excursion
|
||||
(setq sp (point)) ; saved point
|
||||
(setq sm (mark t)) ; saved mark
|
||||
;;; (set-buffer (window-buffer (posn-window (event-start event))))
|
||||
;;; (setq mouse (goto-char (posn-point (event-start event))))
|
||||
(setq mouse (point)) ;; ess-mouse-me-helper
|
||||
;; if there is a region and point is inside it
|
||||
;; check for sm first incase (null (mark t))
|
||||
;; set name to either the thing they clicked on or region
|
||||
(if (and sm
|
||||
(or (and transient-mark-mode mark-active)
|
||||
(eq last-command 'mouse-drag-region))
|
||||
(>= mouse (setq beg (min sp sm)))
|
||||
(<= mouse (setq end (max sp sm))))
|
||||
(setq name (buffer-substring beg end))
|
||||
(setq name (funcall mouse-me-get-string-function))
|
||||
(if (listp name)
|
||||
(setq beg (nth 1 name)
|
||||
end (nth 2 name)
|
||||
name (car name))
|
||||
(goto-char mouse)
|
||||
(while (not (looking-at (regexp-quote name)))
|
||||
(backward-char 1))
|
||||
(setq beg (point))
|
||||
(setq end (search-forward name))))))
|
||||
;; check if name is null, meaning they clicked on no word
|
||||
(if (or (null name)
|
||||
(and (stringp name) (string= name "" )))
|
||||
(error "No string to pass to function"))
|
||||
;; popup a menu to get a command to run
|
||||
(setq cmd (funcall func name))
|
||||
;; run the command, eval'ing if it was a list
|
||||
(if (listp cmd)
|
||||
(setq cmd (eval cmd)))
|
||||
(setq mmtype (get cmd 'mouse-me-type))
|
||||
(cond ((eq mmtype 'region)
|
||||
(funcall cmd beg end))
|
||||
((eq mmtype 'string)
|
||||
(funcall cmd name))
|
||||
(t
|
||||
(funcall cmd name)))))
|
||||
|
||||
(defcustom ess-S-mouse-me-menu-commands-alist
|
||||
'("S-Plus 4 and 6 GUI under Windows"
|
||||
("Edit.data" . ess-mouse-me-Edit.data)
|
||||
"----"
|
||||
("print" . ess-mouse-me-print)
|
||||
("summary" . ess-mouse-me-summary)
|
||||
("plot" . ess-mouse-me-plot)
|
||||
("show" . ess-mouse-me-show)
|
||||
("help" . ess-display-help-on-object)
|
||||
("args" . ess-mouse-me-args)
|
||||
"----"
|
||||
("Browser on" . ess-mouse-me-browser-on)
|
||||
("Browser off" . ess-mouse-me-browser-off))
|
||||
"Command menu used by `mouse-me-build-menu'.
|
||||
A alist of elements where each element is either a cons cell or a string.
|
||||
If a cons cell the car is a string to be displayed in the menu and the
|
||||
cdr is either a function to call passing a string to, or a list which evals
|
||||
to a function to call passing a string to. If the element is a string
|
||||
it makes a non-selectable element in the menu. To make a separator line
|
||||
use a string consisting solely of hyphens.
|
||||
|
||||
The function returned from this menu will be called with one string
|
||||
argument. Or if the function has the symbol property `mouse-me-type'
|
||||
and if its value is the symbol `region' it will be called with the
|
||||
beginning and ending points of the selected string. If the value is
|
||||
the symbol `string' it will be called with one string argument."
|
||||
:type '(repeat sexp)
|
||||
:group 'mouseme)
|
||||
|
||||
|
||||
(defun ess-mouse-me-Edit.data (string)
|
||||
(ess-mouse-me-eval-expanded string "Edit.data(" ")" nil nil nil))
|
||||
|
||||
(defun ess-mouse-me-print (string)
|
||||
(ess-mouse-me-eval-expanded string "" "" nil nil t))
|
||||
(defun ess-mouse-me-summary (string)
|
||||
(ess-mouse-me-eval-expanded string "summary(" ")" nil nil t))
|
||||
(defun ess-mouse-me-plot (string)
|
||||
(ess-mouse-me-eval-expanded string "plot(" ")") nil nil nil)
|
||||
(defun ess-mouse-me-show (string)
|
||||
(ess-mouse-me-eval-expanded string "show(" ")") nil nil nil)
|
||||
(defun ess-mouse-me-args (string)
|
||||
(ess-mouse-me-eval-expanded string "args(" ")" nil nil t))
|
||||
|
||||
(defun ess-mouse-me-browser-on (string)
|
||||
(if (equal (substring ess-dialect 0 1) "R")
|
||||
(ess-eval-linewise (concat "debug(" string ")"))
|
||||
(ess-mouse-me-eval-expanded string "trace(" ", exit=browser)") nil nil nil))
|
||||
|
||||
(defun ess-mouse-me-browser-off (string)
|
||||
(if (equal (substring ess-dialect 0 1) "R")
|
||||
(ess-eval-linewise (concat "undebug(" string ")"))
|
||||
(ess-mouse-me-eval-expanded string "untrace(" ")") nil nil nil))
|
||||
|
||||
|
||||
|
||||
(defun ess-mouse-me-eval-expanded (string &optional head tail commands-buffer
|
||||
page value-returned)
|
||||
"Send the expanded STRING to the inferior-ess process using `ess-command'
|
||||
after first concating the HEAD and TAIL. Put answer in COMMANDS-BUFFER if
|
||||
specified, otherwise in \"tmp-buffer\". In either
|
||||
case the buffer containing the answer is renamed to the value of the
|
||||
constructed command. If PAGE is non-nil, expand
|
||||
the string one more time by embedding it in a \"page()\" command."
|
||||
(interactive)
|
||||
(let* (scommand
|
||||
page-scommand
|
||||
(lproc-name ess-local-process-name)
|
||||
(ess-mouse-customize-alist ess-local-customize-alist))
|
||||
(if (not head) (setq head "summary("))
|
||||
(if (not tail) (setq tail ")"))
|
||||
(if (not commands-buffer) (setq commands-buffer
|
||||
(get-buffer-create "tmp-buffer")))
|
||||
(setq scommand (concat head string tail))
|
||||
|
||||
(ess-make-buffer-current)
|
||||
(pop-to-buffer-same-window commands-buffer)
|
||||
(ess-setq-vars-local (eval ess-mouse-customize-alist) (current-buffer))
|
||||
(setq ess-local-process-name lproc-name)
|
||||
(ess-command (concat scommand "\n") commands-buffer)
|
||||
(if (not value-returned) (pop-to-buffer-same-window (nth 1 (buffer-list))))
|
||||
(if (not value-returned)
|
||||
nil
|
||||
(if ess-microsoft-p ;; there ought to be a filter
|
||||
(while (search-forward "\r" nil t) ;; function to keep the ^M
|
||||
(replace-match "" nil t))) ;; from showing up at all
|
||||
(ess-transcript-mode)
|
||||
(setq ess-local-process-name lproc-name)
|
||||
(rename-buffer scommand))))
|
||||
|
||||
|
||||
; Provide package
|
||||
|
||||
(provide 'ess-mouse)
|
||||
|
||||
|
||||
|
||||
;;;;;;;; STARTUP STUFF ;;;;;;;;;;;;
|
||||
|
||||
(make-variable-buffer-local 'mouse-me-menu-commands)
|
||||
|
||||
(defun ess-S-mouse-me-menu-commands ()
|
||||
(if (equal ess-language "S")
|
||||
(setq mouse-me-menu-commands ess-S-mouse-me-menu-commands-alist)))
|
||||
|
||||
;; (define-key ess-mode-map [S-mouse-3] 'ess-mouse-me)
|
||||
;; (define-key inferior-ess-mode-map [S-mouse-3] 'ess-mouse-me)
|
||||
;; (defun ess-S-mouse-me-ess-transcript-mode ()
|
||||
;; (define-key ess-transcript-mode-map [S-mouse-3] 'ess-mouse-me))
|
||||
;;
|
||||
(add-hook 'ess-mode-hook 'ess-S-mouse-me-menu-commands)
|
||||
(add-hook 'inferior-ess-mode-hook 'ess-S-mouse-me-menu-commands)
|
||||
(add-hook 'ess-transcript-mode-hook 'ess-S-mouse-me-menu-commands)
|
||||
;; (add-hook 'ess-transcript-mode-hook 'ess-S-mouse-me-ess-transcript-mode)
|
||||
|
||||
|
||||
;;; ess-mouse.el ends here
|
||||
153
lisp/ess/obsolete/ess-r-a.el
Normal file
153
lisp/ess/obsolete/ess-r-a.el
Normal file
@@ -0,0 +1,153 @@
|
||||
;;; ess-r-a.el -- Possible local customizations for R with ESS. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
;; Author: A.J. Rossini <blindglobe@gmail.com>
|
||||
;; Created: 17 November 1999
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; The purpose of this file is to demonstrate some of the extras that
|
||||
;; have been constructed for the ESS R mode; if they prove
|
||||
;; interesting, then they might be migrated to ess-r-mode, the primary
|
||||
;; ESS R mode tools.
|
||||
|
||||
;;; Code:
|
||||
(require 'ess-inf)
|
||||
(require 'ess-r-mode)
|
||||
|
||||
;; you can invoke ESS/R from emacs by typing
|
||||
;; C-u M-x essr
|
||||
;; with vsize set to (for example) 40M, and nsize set to 600000.
|
||||
|
||||
;; Undefined on non-apple devices
|
||||
(declare-function ns-do-applescript "nsfns.m" (script))
|
||||
(declare-function do-applescript "ess-r-a" (script))
|
||||
(unless (fboundp 'do-applescript)
|
||||
(defalias 'do-applescript 'ns-do-applescript))
|
||||
|
||||
(defalias 'essr
|
||||
(read-kbd-macro
|
||||
"C-u M-x R RET - - vsize = 40M SPC - - nsize = 600000 2*RET"))
|
||||
|
||||
(defun ess-r-do-region (start end)
|
||||
"Send from START to END to R via AppleScript."
|
||||
(interactive "r\nP")
|
||||
(message "Starting evaluation...")
|
||||
(do-applescript (concat
|
||||
"try\n"
|
||||
"tell application \"R\"\n"
|
||||
"activate\n"
|
||||
"with timeout of 0 seconds\n"
|
||||
"cmd \"" (buffer-substring start end)
|
||||
"\"\n"
|
||||
"end timeout\n"
|
||||
"end tell\n"
|
||||
"end try\n"))
|
||||
(message "Finished evaluation"))
|
||||
|
||||
(defun ess-r-do-line ()
|
||||
"Send the current line to R via AppleScript."
|
||||
(interactive) ;; "r\nP")
|
||||
(message "Starting evaluation...")
|
||||
(save-excursion
|
||||
(let ((end (point)))
|
||||
(move-to-column 0)
|
||||
(do-applescript (concat
|
||||
"try\n"
|
||||
"tell application \"R\"\n"
|
||||
"activate\n"
|
||||
"with timeout of 0 seconds\n"
|
||||
"cmd \"" (buffer-substring (point) end)
|
||||
"\"\n"
|
||||
"end timeout\n"
|
||||
"end tell\n"
|
||||
"end try\n"))))
|
||||
(message "Finished evaluation"))
|
||||
|
||||
(defun ess-r-var (beg end)
|
||||
"Load the current region of numbers into an R variable.
|
||||
Prompts for a variable name. If none is given, it uses a default
|
||||
variable name, e. BEG and END denote the region in the current
|
||||
buffer to be sent."
|
||||
(interactive "r")
|
||||
(save-window-excursion
|
||||
(let ((tmp-file (make-temp-file "ess-r-var"))
|
||||
cmd
|
||||
var)
|
||||
(write-region beg end tmp-file)
|
||||
|
||||
;; Decide on the variable name to use in R; could use completion.
|
||||
(setq var (read-string "R Variable name (default e): "))
|
||||
(if (equal var "")
|
||||
(setq var "e"))
|
||||
|
||||
;; Command to send to the R process. Get R to delete the file
|
||||
;; rather than Emacs in case it takes R a long time to run the
|
||||
;; scan command.
|
||||
(setq cmd (concat var " <- scan(\"" tmp-file "\"); "
|
||||
"unlink(\"" tmp-file "\")" ))
|
||||
|
||||
;; Put the output from the scan command into the process buffer so
|
||||
;; the user has a record of it.
|
||||
(ess-execute cmd 'buffer))))
|
||||
|
||||
|
||||
;;; Peter Dalgaard's code.
|
||||
;;; This needs to be cleaned and validated!
|
||||
|
||||
(defun pd::set-up-demo ()
|
||||
(run-ess-r)
|
||||
(split-window-vertically 6)
|
||||
(find-file "demos.R")
|
||||
|
||||
;; Don't need to run this as a function -- ought to be fine if set
|
||||
;; just once.
|
||||
|
||||
(defun ajr::scroll-to-end::peterD (emacs)
|
||||
"Goal: map prompt to bottom of the screen after every command.
|
||||
Alternatively, use the scroll-in-place package, not sure where that
|
||||
is)."
|
||||
(interactive)
|
||||
(other-buffer 1)
|
||||
(if (= emacs "emacs")
|
||||
(setq scroll-up-aggressively t)
|
||||
(setq scroll-conservatively -4)) ;; <- change this
|
||||
(other-buffer -1))
|
||||
|
||||
(defun show-max-other-window ()
|
||||
(interactive)
|
||||
(other-window 1)
|
||||
(comint-show-maximum-output)
|
||||
(other-window -1))
|
||||
|
||||
;; call this once
|
||||
;; (ajr::scroll-to-end::peterD "emacs")
|
||||
|
||||
(global-set-key [f11] 'show-max-other-window)
|
||||
(global-set-key [f12] 'ess-eval-line-visibly-and-step))
|
||||
|
||||
|
||||
; Provide package
|
||||
|
||||
(provide 'ess-r-a)
|
||||
|
||||
;;; ess-r-a.el ends here
|
||||
233
lisp/ess/obsolete/make-regexp.el
Normal file
233
lisp/ess/obsolete/make-regexp.el
Normal file
@@ -0,0 +1,233 @@
|
||||
;;; make-regexp.el --- generate efficient regexps to match strings.
|
||||
|
||||
;; Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
;; Author: Simon Marshall <simon@gnu.ai.mit.edu>
|
||||
;; Keywords: lisp, matching
|
||||
;; Version: 1.02
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Purpose:
|
||||
;;
|
||||
;; To make efficient regexps from lists of strings.
|
||||
|
||||
;; For example:
|
||||
;;
|
||||
;; (let ((strings '("cond" "if" "while" "let\\*?" "prog1" "prog2" "progn"
|
||||
;; "catch" "throw" "save-restriction" "save-excursion"
|
||||
;; "save-window-excursion" "save-match-data"
|
||||
;; "unwind-protect" "condition-case" "track-mouse")))
|
||||
;; (concat "(" (make-regexp strings t)))
|
||||
;;
|
||||
;; => "(\\(c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|if\\|let\\*?\\|prog[12n]\\|save-\\(excursion\\|match-data\\|restriction\\|window-excursion\\)\\|t\\(hrow\\|rack-mouse\\)\\|unwind-protect\\|while\\)"
|
||||
;;
|
||||
;; To search for the above regexp takes about 70% of the time as for the simple
|
||||
;; (concat "(\\(" (mapconcat 'identity strings "\\|") "\\)") regexp.
|
||||
;;
|
||||
;; Obviously, the more the similarity between strings, the faster the regexp:
|
||||
;;
|
||||
;; (make-regexp '("abort" "abs" "accept" "access" "array" "begin" "body" "case"
|
||||
;; "constant" "declare" "delay" "delta" "digits" "else" "elsif"
|
||||
;; "entry" "exception" "exit" "function" "generic" "goto" "if"
|
||||
;; "others" "limited" "loop" "mod" "new" "null" "out" "subtype"
|
||||
;; "package" "pragma" "private" "procedure" "raise" "range"
|
||||
;; "record" "rem" "renames" "return" "reverse" "select"
|
||||
;; "separate" "task" "terminate" "then" "type" "when" "while"
|
||||
;; "with" "xor"))
|
||||
;;
|
||||
;; => "a\\(b\\(ort\\|s\\)\\|cce\\(pt\\|ss\\)\\|rray\\)\\|b\\(egin\\|ody\\)\\|c\\(ase\\|onstant\\)\\|d\\(e\\(clare\\|l\\(ay\\|ta\\)\\)\\|igits\\)\\|e\\(ls\\(e\\|if\\)\\|ntry\\|x\\(ception\\|it\\)\\)\\|function\\|g\\(eneric\\|oto\\)\\|if\\|l\\(imited\\|oop\\)\\|mod\\|n\\(ew\\|ull\\)\\|o\\(thers\\|ut\\)\\|p\\(ackage\\|r\\(agma\\|ivate\\|ocedure\\)\\)\\|r\\(a\\(ise\\|nge\\)\\|e\\(cord\\|m\\|names\\|turn\\|verse\\)\\)\\|s\\(e\\(lect\\|parate\\)\\|ubtype\\)\\|t\\(ask\\|erminate\\|hen\\|ype\\)\\|w\\(h\\(en\\|ile\\)\\|ith\\)\\|xor"
|
||||
;;
|
||||
;; To search for the above regexp takes less than 60% of the time of the simple
|
||||
;; mapconcat equivalent.
|
||||
;;
|
||||
;; But even small regexps may be worth it:
|
||||
;;
|
||||
;; (make-regexp '("and" "at" "do" "end" "for" "in" "is" "not" "of" "or" "use"))
|
||||
;; => "a\\(nd\\|t\\)\\|do\\|end\\|for\\|i[ns]\\|not\\|o[fr]\\|use"
|
||||
;;
|
||||
;; as this is 10% faster than the mapconcat equivalent.
|
||||
|
||||
;; Installation:
|
||||
;;
|
||||
;; (autoload 'make-regexp "make-regexp"
|
||||
;; "Return a regexp to match a string item in STRINGS.")
|
||||
;;
|
||||
;; (autoload 'make-regexps "make-regexp"
|
||||
;; "Return a regexp to REGEXPS.")
|
||||
;;
|
||||
;; Since these functions were written to produce efficient regexps, not regexps
|
||||
;; efficiently, it is probably not a good idea to in-line too many calls in
|
||||
;; your code, unless you use the following neat trick with `eval-when-compile':
|
||||
;;
|
||||
;; (defvar definition-regexp
|
||||
;; (let ((regexp (eval-when-compile
|
||||
;; (make-regexp '("defun" "defsubst" "defmacro" "defalias"
|
||||
;; "defvar" "defconst" "defadvice") t))))
|
||||
;; (concat "^(" regexp)))
|
||||
;;
|
||||
;; The `byte-compile' code will be as if you had defined the variable thus:
|
||||
;;
|
||||
;; (defvar definition-regexp
|
||||
;; "^(\\(def\\(a\\(dvice\\|lias\\)\\|const\\|macro\\|subst\\|un\\|var\\)\\)")
|
||||
|
||||
;; Feedback:
|
||||
;;
|
||||
;; Originally written for font-lock, from an idea from Stig's hl319.
|
||||
;; Please don't tell me that it doesn't produce optimal regexps; I know that
|
||||
;; already. But (ideas or) code to improve things (are) is welcome. Please
|
||||
;; test your code and tell me the speed up in searching an appropriate buffer.
|
||||
;;
|
||||
;; Please send me bug reports, bug fixes, and extensions, etc.
|
||||
;; Simon Marshall <simon@gnu.ai.mit.edu>
|
||||
|
||||
;; History:
|
||||
;;
|
||||
;; 1.00--1.01:
|
||||
;; - Made `make-regexp' take `lax' to force top-level parentheses.
|
||||
;; - Fixed `make-regexps' for MATCH bug and new `font-lock-keywords'.
|
||||
;; - Added `unfontify' to user timing functions.
|
||||
;; 1.01--1.02:
|
||||
;; - Made `make-regexp' `let' a big `max-lisp-eval-depth'.
|
||||
|
||||
;; The basic idea is to find the shortest common non-"" prefix each time, and
|
||||
;; squirrel it out. If there is no such prefix, we divide the list into two so
|
||||
;; that (at least) one half will have at least a one-character common prefix.
|
||||
|
||||
;; In addition, we (a) delay the addition of () parenthesis as long as possible
|
||||
;; (until we're sure we need them), and (b) try to squirrel out one-character
|
||||
;; sequences (so we can use [] rather than ()).
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defun make-regexp (strings &optional paren lax)
|
||||
"Return a regexp to match a string item in STRINGS.
|
||||
If optional PAREN non-nil, output regexp parentheses around returned regexp.
|
||||
If optional LAX non-nil, don't output parentheses if it doesn't require them.
|
||||
Merges keywords to avoid backtracking in Emacs' regexp matcher."
|
||||
(let* ((max-lisp-eval-depth (* 1024 1024))
|
||||
(strings (let ((l strings)) ; Paranoia---make strings unique!
|
||||
(while l (setq l (setcdr l (delete (car l) (cdr l)))))
|
||||
(sort strings 'string-lessp)))
|
||||
(open-paren (if paren "\\(" "")) (close-paren (if paren "\\)" ""))
|
||||
(open-lax (if lax "" open-paren)) (close-lax (if lax "" close-paren))
|
||||
(completion-ignore-case nil))
|
||||
(cond
|
||||
;; If there's only one string, just return it.
|
||||
((= (length strings) 1)
|
||||
(concat open-lax (car strings) close-lax))
|
||||
;; If there's an empty string, pull it out.
|
||||
((string= (car strings) "")
|
||||
(if (and (= (length strings) 2) (= (length (nth 1 strings)) 1))
|
||||
(concat open-lax (nth 1 strings) "?" close-lax)
|
||||
(concat open-paren "\\|" (make-regexp (cdr strings)) close-paren)))
|
||||
;; If there are only one-character strings, make a [] list instead.
|
||||
((= (length strings) (apply '+ (mapcar 'length strings)))
|
||||
(concat open-lax "[" (mapconcat 'identity strings "") "]" close-lax))
|
||||
(t
|
||||
;; We have a list of strings. Is there a common prefix?
|
||||
(let ((prefix (try-completion "" (mapcar 'list strings))))
|
||||
(if (> (length prefix) 0)
|
||||
;; Common prefix! Squirrel it out and recurse with the suffixes.
|
||||
(let* ((len (length prefix))
|
||||
(sufs (mapcar (lambda (str) (substring str len)) strings)))
|
||||
(concat open-paren prefix (make-regexp sufs t t) close-paren))
|
||||
;; No common prefix. Is there a one-character sequence?
|
||||
(let ((letters (let ((completion-regexp-list '("^.$")))
|
||||
(all-completions "" (mapcar 'list strings)))))
|
||||
(if (> (length letters) 1)
|
||||
;; Do the one-character sequences, then recurse on the rest.
|
||||
(let ((rest (let ((completion-regexp-list '("^..+$")))
|
||||
(all-completions "" (mapcar 'list strings)))))
|
||||
(concat open-paren
|
||||
(make-regexp letters) "\\|" (make-regexp rest)
|
||||
close-paren))
|
||||
;; No one-character sequence, so divide the list into two by
|
||||
;; dividing into those that start with a particular letter, and
|
||||
;; those that do not.
|
||||
(let* ((char (substring (car strings) 0 1))
|
||||
(half1 (all-completions char (mapcar 'list strings)))
|
||||
(half2 (nthcdr (length half1) strings)))
|
||||
(concat open-paren
|
||||
(make-regexp half1) "\\|" (make-regexp half2)
|
||||
close-paren))))))))))
|
||||
|
||||
;; This stuff is realy for font-lock...
|
||||
|
||||
;; Ahhh, the wonders of lisp...
|
||||
(defun regexp-span (regexp &optional start)
|
||||
"Return the span or depth of REGEXP.
|
||||
This means the number of \"\\\\(...\\\\)\" pairs in REGEXP, optionally from START."
|
||||
(let ((match (string-match (regexp-quote "\\(") regexp (or start 0))))
|
||||
(if (not match) 0 (1+ (regexp-span regexp (match-end 0))))))
|
||||
|
||||
;; The basic idea is to concat the regexps together, keeping count of the span
|
||||
;; of the regexps so that we can get the correct match for hilighting.
|
||||
(defun make-regexps (&rest regexps)
|
||||
"Return a regexp to match REGEXPS
|
||||
Each item of REGEXPS should be of the form:
|
||||
|
||||
STRING ; A STRING to be used literally.
|
||||
(STRING MATCH FACE DATA) ; Match STRING at depth MATCH with FACE
|
||||
; and highlight according to DATA.
|
||||
(STRINGS FACE DATA) ; STRINGS is a list of strings FACE is
|
||||
; to highlight according to DATA.
|
||||
|
||||
Returns a list of the form:
|
||||
|
||||
(REGEXP (MATCH FACE DATA) ...)
|
||||
|
||||
For example:
|
||||
|
||||
(make-regexps \"^(\"
|
||||
'((\"defun\" \"defalias\" \"defsubst\" \"defadvice\") keyword)
|
||||
\"[ \t]*\"
|
||||
'(\"\\\\([a-zA-Z-]+\\\\)?\" 1 function-name nil t))
|
||||
|
||||
=>
|
||||
|
||||
(\"^(\\\\(def\\\\(a\\\\(dvice\\\\|lias\\\\)\\\\|subst\\\\|un\\\\)\\\\)[ ]*\\\\([a-zA-Z-]+\\\\)?\"
|
||||
(1 keyword) (4 function-name nil t))
|
||||
|
||||
Uses `make-regexp' to make efficient regexps."
|
||||
(let ((regexp "") (data ()))
|
||||
(while regexps
|
||||
(cond ((stringp (car regexps))
|
||||
(setq regexp (concat regexp (car regexps))))
|
||||
((stringp (nth 0 (car regexps)))
|
||||
(setq data (cons (cons (+ (regexp-span regexp)
|
||||
(nth 1 (car regexps)))
|
||||
(nthcdr 2 (car regexps)))
|
||||
data)
|
||||
regexp (concat regexp (nth 0 (car regexps)))))
|
||||
(t
|
||||
(setq data (cons (cons (1+ (regexp-span regexp))
|
||||
(cdr (car regexps)))
|
||||
data)
|
||||
regexp (concat regexp (make-regexp (nth 0 (car regexps))
|
||||
t)))))
|
||||
(setq regexps (cdr regexps)))
|
||||
(cons regexp (nreverse data))))
|
||||
|
||||
;; timing functions removed due to name collisions with Gnus
|
||||
|
||||
(provide 'make-regexp)
|
||||
|
||||
;;; make-regexp.el ends here
|
||||
358
lisp/ess/obsolete/mouseme.el
Normal file
358
lisp/ess/obsolete/mouseme.el
Normal file
@@ -0,0 +1,358 @@
|
||||
;;; mouseme.el --- mouse menu with commands that operate on strings
|
||||
|
||||
;; Copyright (C) 1997-2020 by Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Howard Melman <howard@silverstream.com>
|
||||
;; Keywords: mouse, menu
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package provides a command `mouse-me' to be bound to a mouse
|
||||
;; button. It pops up a menu of commands that operate on strings or a
|
||||
;; region. The string passed to the selected command is the word or
|
||||
;; symbol clicked on (with surrounding quotes or other punctuation
|
||||
;; removed), or the region (if either it was just selected with the
|
||||
;; mouse or if it was active with `transient-mark-mode' on). If the
|
||||
;; command accepts a region, the selected region (or the region of the
|
||||
;; word or symbol clicked on) will be passed to the command.
|
||||
|
||||
;; The idea is that for any given string in a buffer you may want to
|
||||
;; do different things regardless of the mode of the buffer. URLs
|
||||
;; now appear in email, news articles, comments in code, and in plain
|
||||
;; text. You may want to visit that URL in a browser or you may just
|
||||
;; want to copy it to the kill-ring. For an email address you might
|
||||
;; want to compose mail to it, finger it, look it up in bbdb, copy it to
|
||||
;; the kill ring. For a word you may want to spell check it, copy it,
|
||||
;; change its case, grep for it, etc. Mouse-me provides a menu to
|
||||
;; make this easy.
|
||||
|
||||
;; The menu popped up is generated by calling the function in the
|
||||
;; variable `mouse-me-build-menu-function' which defaults to calling
|
||||
;; `mouse-me-build-menu' which builds the menu from the variable
|
||||
;; `mouse-me-menu-commands'. See the documentation for these
|
||||
;; functions and variables for details.
|
||||
|
||||
;; To install, add something like the following to your ~/.emacs:
|
||||
;; (require 'mouseme)
|
||||
;; (global-set-key [S-mouse-2] 'mouse-me)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'browse-url)
|
||||
(require 'thingatpt)
|
||||
|
||||
(eval-when-compile (require 'compile))
|
||||
|
||||
;;;; Variables
|
||||
|
||||
(defgroup mouseme nil
|
||||
"Popup menu of commands that work on strings."
|
||||
:prefix "mouse-me-"
|
||||
:group 'hypermedia)
|
||||
|
||||
(defcustom mouse-me-get-string-function 'mouse-me-get-string
|
||||
"Function used by `mouse-me' to get string when no region selected.
|
||||
The default is `mouse-me-get-string' but this variable may commonly
|
||||
be made buffer local and set to something more appropriate for
|
||||
a specific mode (e.g., `word-at-point'). The function will be called
|
||||
with no arguments and with point at where the mouse was clicked.
|
||||
It can return either the string or to be most efficient, a list of
|
||||
three elements: the string and the beginning and ending points of the
|
||||
string in the buffer."
|
||||
:type 'function
|
||||
:options '(mouse-me-get-string)
|
||||
:group 'mouseme)
|
||||
|
||||
(defcustom mouse-me-build-menu-function 'mouse-me-build-menu
|
||||
"Function used by `mouse-me' to build the popup menu.
|
||||
The default is `mouse-me-build-menu' but this variable may commonly
|
||||
be made buffer local and set to something more appropriate for
|
||||
a specific mode. The function will be called with one argument,
|
||||
the string selected, as returned by `mouse-me-get-string-function'."
|
||||
:type 'function
|
||||
:options '(mouse-me-build-menu)
|
||||
:group 'mouseme)
|
||||
|
||||
(defvar mouse-me-grep-use-extension 't
|
||||
"If non-nil `mouse-me-grep' grep's in files with current file's extension.")
|
||||
|
||||
(defcustom mouse-me-menu-commands
|
||||
'(("Copy" . kill-new)
|
||||
("Kill" . kill-region)
|
||||
("Capitalize" . capitalize-region)
|
||||
("Lowercase" . downcase-region)
|
||||
("Uppercase" . upcase-region)
|
||||
("ISpell" . ispell-region)
|
||||
"----"
|
||||
("Browse URL" . browse-url)
|
||||
("Dired" . dired)
|
||||
("Execute File" . mouse-me-execute)
|
||||
("Mail to" . compose-mail)
|
||||
("Finger" . mouse-me-finger)
|
||||
("BBDB Lookup" . mouse-me-bbdb)
|
||||
"----"
|
||||
("Imenu" . imenu)
|
||||
("Find Tag" . find-tag)
|
||||
("Grep" . mouse-me-grep)
|
||||
("Find-Grep" . mouse-me-find-grep)
|
||||
"----"
|
||||
("Apropos" . apropos)
|
||||
("Describe Function" . mouse-me-describe-function)
|
||||
("Describe Variable" . mouse-me-describe-variable)
|
||||
("Command Info" . mouse-me-emacs-command-info)
|
||||
("Man Page" . (if (fboundp 'woman) 'woman 'man))
|
||||
("Profile Function" . mouse-me-elp-instrument-function))
|
||||
"Command menu used by `mouse-me-build-menu'.
|
||||
A list of elements where each element is either a cons cell or a string.
|
||||
If a cons cell the car is a string to be displayed in the menu and the
|
||||
cdr is either a function to call passing a string to, or a list which evals
|
||||
to a function to call passing a string to. If the element is a string
|
||||
it makes a non-selectable element in the menu. To make a separator line
|
||||
use a string consisting solely of hyphens.
|
||||
|
||||
The function returned from this menu will be called with one string
|
||||
argument. Or if the function has the symbol property `mouse-me-type'
|
||||
and if its value is the symbol `region' it will be called with the
|
||||
beginning and ending points of the selected string. If the value is
|
||||
the symbol `string' it will be called with one string argument."
|
||||
:type '(repeat sexp)
|
||||
:group 'mouseme)
|
||||
|
||||
(put 'kill-region 'mouse-me-type 'region)
|
||||
(put 'ispell-region 'mouse-me-type 'region)
|
||||
(put 'capitalize-region 'mouse-me-type 'region)
|
||||
(put 'downcase-region 'mouse-me-type 'region)
|
||||
(put 'upcase-region 'mouse-me-type 'region)
|
||||
|
||||
;;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun mouse-me (event)
|
||||
"Popup a menu of functions to run on selected string or region."
|
||||
(interactive "e")
|
||||
(mouse-me-helper event (lambda (name)
|
||||
(or (x-popup-menu event (funcall mouse-me-build-menu-function name))
|
||||
(error "No command to run")))))
|
||||
|
||||
;;;; Exposed Functions
|
||||
|
||||
;; Some tests:
|
||||
;; <URL:http://foo.bar.com/sss/ss.html>
|
||||
;; <http://foo.bar.com/sss/ss.html>
|
||||
;; http://foo.bar.com/sss/ss.html
|
||||
;; http://www.ditherdog.com/howard/
|
||||
;; mailto:howard@silverstream.com
|
||||
;; howard@silverstream.com
|
||||
;; <howard@silverstream.com>
|
||||
;; import com.sssw.srv.agents.AgentsRsrc;
|
||||
;; public AgoHttpRequestEvent(Object o, String db, Request r)
|
||||
;; <DIV><A href=3D"http://www.amazon.com/exec/obidos/ASIN/156592391X"><IMG =
|
||||
;; <A HREF="http://www.suntimes.com/ebert/ebert.html">
|
||||
;; d:\howard\elisp\spoon
|
||||
;; \howard\elisp\spoon
|
||||
;; \\absolut\howard\elisp\spoon
|
||||
;; //absolut/d/Howard/Specs/servlet-2.1.pdf
|
||||
;; \\absolut\d\Howard\Specs\servlet-2.1.pdf
|
||||
;; gnuserv-frame.
|
||||
|
||||
(defun mouse-me-get-string ()
|
||||
"Return a string from the buffer of text surrounding point.
|
||||
Returns a list of three elements, the string and the beginning and
|
||||
ending positions of the string in the buffer in that order."
|
||||
(save-match-data
|
||||
(save-excursion
|
||||
(let ((start (point)) beg end str p)
|
||||
(skip-syntax-forward "^ >()\"")
|
||||
(setq end (point))
|
||||
(goto-char start)
|
||||
(skip-syntax-backward "^ >()\"")
|
||||
(setq beg (point))
|
||||
(setq str (buffer-substring-no-properties beg end))
|
||||
;; remove junk from the beginning
|
||||
(if (string-match "^\\([][\"'`.,?:;!@#$%^&*()_+={}|<>-]+\\)" str)
|
||||
(setq str (substring str (match-end 1))
|
||||
beg (+ beg (match-end 1))))
|
||||
;; remove URL: from the front, it's common in email
|
||||
(if (string-match "^\\(URL:\\)" str)
|
||||
(setq str (substring str (match-end 1))
|
||||
beg (+ beg (match-end 1))))
|
||||
;; remove junk from the end
|
||||
(if (string-match "\\([][\"'.,?:;!@#$%^&*()_+={}|<>-]+\\)$" str)
|
||||
(setq end (- end (length (match-string 1 str))) ; must set end first
|
||||
str (substring str 0 (match-beginning 1))))
|
||||
(list str beg end)))))
|
||||
|
||||
(defun mouse-me-build-menu (name)
|
||||
"Return a menu tailored for NAME for `mouse-me' from `mouse-me-menu-commands'."
|
||||
(list "Mouse Me" (cons "Mouse Me"
|
||||
(append (list (cons
|
||||
(if (< (length name) 65)
|
||||
name
|
||||
"...Long String...")
|
||||
'kill-new)
|
||||
"---")
|
||||
mouse-me-menu-commands))))
|
||||
|
||||
;;;; Commands for the menu
|
||||
|
||||
(defun mouse-me-emacs-command-info (string)
|
||||
"Look in Emacs info for command named STRING."
|
||||
(interactive "sCommand: ")
|
||||
(let ((s (intern-soft string)))
|
||||
(if (and s (commandp s))
|
||||
(Info-goto-emacs-command-node s)
|
||||
(error "No command named `%s'" string))))
|
||||
|
||||
(defun mouse-me-describe-function (string)
|
||||
"Describe function named STRING."
|
||||
(interactive "sFunction: ")
|
||||
(let ((s (intern-soft string)))
|
||||
(if (and s (fboundp s))
|
||||
(describe-function s)
|
||||
(error "No function named `%s'" string))))
|
||||
|
||||
(defun mouse-me-describe-variable (string)
|
||||
"Desribe variable named STRING."
|
||||
(interactive "sVariable: ")
|
||||
(let ((s (intern-soft string)))
|
||||
(if (and s (boundp s))
|
||||
(describe-variable s)
|
||||
(error "No variable named `%s'" string))))
|
||||
|
||||
(defun mouse-me-elp-instrument-function (string)
|
||||
"Instrument Lisp function named STRING."
|
||||
(interactive "sFunction: ")
|
||||
(let ((s (intern-soft string)))
|
||||
(if (and s (fboundp s))
|
||||
(elp-instrument-function s)
|
||||
(error "Must be the name of an existing Lisp function"))))
|
||||
|
||||
(defun mouse-me-execute (string)
|
||||
"Execute STRING as a filename."
|
||||
(interactive "sFile: ")
|
||||
(if (fboundp 'w32-shell-execute)
|
||||
(w32-shell-execute "open" (convert-standard-filename string))
|
||||
(message "This function currently working only in W32.")))
|
||||
|
||||
|
||||
(defun mouse-me-bbdb (string)
|
||||
"Lookup STRING in bbdb."
|
||||
(interactive "sBBDB Lookup: ")
|
||||
(if (fboundp 'bbdb)
|
||||
(bbdb string nil)
|
||||
(error "BBDB not loaded")))
|
||||
|
||||
(defun mouse-me-finger (string)
|
||||
"Finger a STRING mail address."
|
||||
(interactive "sFinger: ")
|
||||
(save-match-data
|
||||
(if (string-match "\\(.*\\)@\\([-.a-zA-Z0-9]+\\)$" string)
|
||||
(finger (match-string 1 string) (match-string 2 string))
|
||||
(error "Not in user@host form: %s" string))))
|
||||
|
||||
(defun mouse-me-grep (string)
|
||||
"Grep for a STRING."
|
||||
(interactive "sGrep: ")
|
||||
(require 'compile)
|
||||
(grep-compute-defaults)
|
||||
(let ((ext (mouse-me-buffer-file-extension)))
|
||||
(grep (concat grep-command string
|
||||
(if mouse-me-grep-use-extension
|
||||
(if ext
|
||||
(concat " *" ext)
|
||||
" *"))))))
|
||||
|
||||
(defun mouse-me-find-grep (string)
|
||||
"Grep for a STRING."
|
||||
(interactive "sGrep: ")
|
||||
(grep-compute-defaults)
|
||||
(let ((reg grep-find-command)
|
||||
(ext (mouse-me-buffer-file-extension))
|
||||
beg end)
|
||||
(if (string-match "\\(^.+-type f \\)\\(.+$\\)" reg)
|
||||
(setq reg (concat (match-string 1 reg)
|
||||
(if mouse-me-grep-use-extension
|
||||
(concat "-name \"*" ext "\" "))
|
||||
(match-string 2 reg))))
|
||||
(grep-find (concat reg string))))
|
||||
|
||||
;;;; Internal Functions
|
||||
|
||||
(defun mouse-me-buffer-file-extension ()
|
||||
"Return the extension of the current buffer's filename or nil.
|
||||
Returned extension is a string begining with a period."
|
||||
(let* ((bfn (buffer-file-name))
|
||||
(filename (and bfn (file-name-sans-versions bfn)))
|
||||
(index (and filename (string-match "\\.[^.]*$" filename))))
|
||||
(if index
|
||||
(substring filename index)
|
||||
"")))
|
||||
|
||||
(defun mouse-me-helper (event func)
|
||||
"Determine the string to use to process EVENT and call FUNC to get cmd."
|
||||
(let (name sp sm mouse beg end cmd mmtype)
|
||||
;; temporarily goto where the event occurred, get the name clicked
|
||||
;; on and enough info to figure out what to do with it
|
||||
(save-match-data
|
||||
(save-excursion
|
||||
(setq sp (point)) ; saved point
|
||||
(setq sm (mark t)) ; saved mark
|
||||
(set-buffer (window-buffer (posn-window (event-start event))))
|
||||
(setq mouse (goto-char (posn-point (event-start event))))
|
||||
;; if there is a region and point is inside it
|
||||
;; check for sm first incase (null (mark t))
|
||||
;; set name to either the thing they clicked on or region
|
||||
(if (and sm
|
||||
(or (and transient-mark-mode mark-active)
|
||||
(eq last-command 'mouse-drag-region))
|
||||
(>= mouse (setq beg (min sp sm)))
|
||||
(<= mouse (setq end (max sp sm))))
|
||||
(setq name (buffer-substring beg end))
|
||||
(setq name (funcall mouse-me-get-string-function))
|
||||
(if (listp name)
|
||||
(setq beg (nth 1 name)
|
||||
end (nth 2 name)
|
||||
name (car name))
|
||||
(goto-char mouse)
|
||||
(while (not (looking-at (regexp-quote name)))
|
||||
(backward-char 1))
|
||||
(setq beg (point))
|
||||
(setq end (search-forward name))))))
|
||||
;; check if name is null, meaning they clicked on no word
|
||||
(if (or (null name)
|
||||
(and (stringp name) (string= name "" )))
|
||||
(error "No string to pass to function"))
|
||||
;; popup a menu to get a command to run
|
||||
(setq cmd (funcall func))
|
||||
;; run the command, eval'ing if it was a list
|
||||
(if (listp cmd)
|
||||
(setq cmd (eval cmd)))
|
||||
(setq mmtype (get cmd 'mouse-me-type))
|
||||
(cond ((eq mmtype 'region)
|
||||
(funcall cmd beg end))
|
||||
((eq mmtype 'string)
|
||||
(funcall cmd name))
|
||||
(t
|
||||
(funcall cmd name)))))
|
||||
|
||||
(provide 'mouseme)
|
||||
|
||||
;;; mouseme.el ends here
|
||||
163
lisp/ess/obsolete/msdos.el
Normal file
163
lisp/ess/obsolete/msdos.el
Normal file
@@ -0,0 +1,163 @@
|
||||
;;; msdos.el --- Run an MS-DOS shell in an NTemacs buffer with bash as the shell
|
||||
|
||||
;; Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
;; Author: Richard M. Heiberger <rmh@temple.edu>
|
||||
;; Created: February 1999
|
||||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;;; License:
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see
|
||||
;; <http://www.gnu.org/licenses/>
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; The file msdos.el in the next mail message opens an *msdos* buffer
|
||||
;; in shell-mode and msdos-minor-mode. When cmdproxy.exe/command.com
|
||||
;; is the Emacs shell, then this gets various setting right that M-x
|
||||
;; shell currently misses. The function M-x msdos-minor-mode could be
|
||||
;; automatically run by Emacs in shell-mode in that case.
|
||||
|
||||
;; When bash is the Emacs shell, msdos.el still opens a
|
||||
;; cmdproxy.exe/command.com shell in the buffer *msdos*. There are
|
||||
;; occasions when it is necessary to run DOS character-based programs
|
||||
;; in an Emacs window.
|
||||
|
||||
;; I followed the suggestion by AndrewI to look at M-x shell and modify
|
||||
;; it. It turns out not to have been trivial.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'shell); and hence 'comint
|
||||
|
||||
;;; Customization and Buffer Variables
|
||||
|
||||
(defcustom explicit-msdos-shell-file-name "cmdproxy.exe"
|
||||
"*If non-nil, is file name to use for explicitly requested msdos
|
||||
inferior shell."
|
||||
:type '(choice (const :tag "None" nil) file)
|
||||
:group 'shell)
|
||||
|
||||
(defcustom explicit-msdos-comspec-file-name
|
||||
(if (w32-using-nt)
|
||||
"cmd.exe"
|
||||
"command.com")
|
||||
"*If non-nil, is file name to use for explicitly requested COMSPEC
|
||||
environment variable."
|
||||
:type '(choice (const :tag "None" nil) file)
|
||||
:group 'shell)
|
||||
|
||||
(defvar-local msdos-minor-mode nil
|
||||
"Non-nil if using msdos-minor mode as a minor mode of some other mode.")
|
||||
|
||||
(defun msdos ()
|
||||
"Run an inferior msdos shell, with I/O through buffer *msdos*.
|
||||
This function is intended to be used in an Ntemacs session in which
|
||||
bash is the primary shell. But sometimes an MSDOS window, within emacs,
|
||||
is also needed.
|
||||
|
||||
If buffer exists but shell process is not running, make new shell.
|
||||
If buffer exists and shell process is running, just switch to buffer `*msdos*'.
|
||||
Program used comes from variable `explicit-msdos-shell-file-name'.
|
||||
If a file `~/.emacs_SHELLNAME' exists, it is given as initial input
|
||||
(Note that this may lose due to a timing error if the shell
|
||||
discards input when it starts up.)
|
||||
The buffer is put in Shell mode, giving commands for sending input
|
||||
and controlling the subjobs of the shell. See `shell-mode'.
|
||||
See also the variable `shell-prompt-pattern'.
|
||||
|
||||
The buffer is put into \\[msdos-minor-mode]. See `msdos-minor-mode'.
|
||||
|
||||
The COMSPEC environment variable in the inferior shell, but not in the emacs
|
||||
process, is set to `explicit-msdos-comspec-file-name'.
|
||||
The SHELL environment variable in the inferior shell, but not in the emacs
|
||||
process, is set to `explicit-msdos-shell-file-name'.
|
||||
|
||||
The shell file name (sans directories) is used to make a symbol name
|
||||
such as `explicit-csh-args'. If that symbol is a variable,
|
||||
its value is used as a list of arguments when invoking the shell.
|
||||
|
||||
\(Type \\[describe-mode] in the shell buffer for a list of commands.)"
|
||||
(interactive)
|
||||
(if (not (comint-check-proc "*msdos*"))
|
||||
(let* ((prog explicit-msdos-shell-file-name)
|
||||
(name (file-name-nondirectory prog))
|
||||
(startfile (concat "~/.emacs_" name))
|
||||
(xargs-name (intern-soft (concat "explicit-" name "-args")))
|
||||
shell-buffer
|
||||
(comspec (getenv "COMSPEC"))
|
||||
(shell (getenv "SHELL"))
|
||||
)
|
||||
(save-excursion
|
||||
(setenv "COMSPEC" explicit-msdos-comspec-file-name)
|
||||
(setenv "SHELL" explicit-msdos-shell-file-name)
|
||||
(set-buffer (apply 'make-comint "msdos" prog
|
||||
(if (and xargs-name (boundp xargs-name))
|
||||
(symbol-value xargs-name))
|
||||
(if (file-exists-p startfile)
|
||||
(concat "/k " startfile))))
|
||||
(setenv "COMSPEC" comspec)
|
||||
(setenv "SHELL" shell)
|
||||
(setq shell-buffer (current-buffer))
|
||||
(shell-mode)
|
||||
(msdos-minor-mode)
|
||||
(sleep-for 4) ; need to wait, else working too fast!
|
||||
;;; The `exit' warning should precede the "c:\" prompt.
|
||||
;;; If not, then increase the sleep-for time!
|
||||
(goto-char (point-min))
|
||||
(insert
|
||||
"Remember to exit this buffer with `exit'. If you kill the
|
||||
buffer without exiting, you may not be able to shut down Windows cleanly.")
|
||||
(goto-char (point-max)))
|
||||
(pop-to-buffer shell-buffer))
|
||||
(pop-to-buffer "*msdos*")))
|
||||
|
||||
|
||||
(defun msdos-minor-mode ()
|
||||
"Minor mode for running msdos in a shell-mode buffer:
|
||||
a. Uses \\[set-buffer-process-coding-system] to set the coding system
|
||||
to `'raw-text-dos'. The DOS C-m C-l end-of-line is critical. The
|
||||
shell freezes without it.
|
||||
|
||||
b. The variable `comint-completion-addsuffix' is set to `\\' for directories.
|
||||
|
||||
c. Prevents echoing of commands.
|
||||
|
||||
d. strips ctrl-m from output.
|
||||
"
|
||||
(interactive)
|
||||
(setq msdos-minor-mode t)
|
||||
(set (make-local-variable 'comint-completion-addsuffix) '("\\" . " "))
|
||||
(setq comint-process-echoes t)
|
||||
(add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
|
||||
(set-process-coding-system (get-buffer-process (current-buffer)) 'raw-text-dos 'raw-text-dos)
|
||||
;; buffer-process-coding-system is critical.
|
||||
)
|
||||
|
||||
;; Install ourselves:
|
||||
|
||||
|
||||
(put 'msdos-minor-mode 'permanent-local t)
|
||||
(or (assq 'msdos-minor-mode minor-mode-alist)
|
||||
(setq minor-mode-alist
|
||||
(append minor-mode-alist
|
||||
(list '(msdos-minor-mode " msdos")))))
|
||||
|
||||
;; Provide ourselves:
|
||||
|
||||
(provide 'msdos)
|
||||
|
||||
;;; msdos.el ends here
|
||||
1523
lisp/ess/onews.info
Normal file
1523
lisp/ess/onews.info
Normal file
File diff suppressed because it is too large
Load Diff
775
lisp/ess/readme.info
Normal file
775
lisp/ess/readme.info
Normal file
@@ -0,0 +1,775 @@
|
||||
This is readme.info, produced by makeinfo version 6.5 from readme.texi.
|
||||
|
||||
|
||||
File: readme.info, Node: General Information
|
||||
|
||||
1 General Information: README
|
||||
*****************************
|
||||
|
||||
This is the README file for the distribution of ESS version
|
||||
18.10.3snapshot
|
||||
|
||||
ESS is a GNU Emacs package for interactive statistical programming
|
||||
and data analysis. Languages supported: the S family (S, S-PLUS and R),
|
||||
SAS, BUGS/JAGS and Stata. ESS grew out of the desire for bug fixes and
|
||||
extensions to S-mode and SAS-mode as well as a consistent union of their
|
||||
features in one package.
|
||||
|
||||
Installation instructions are provided in sections for both Unix and
|
||||
Windows; see below.
|
||||
|
||||
The current development team is led by Martin Maechler since August
|
||||
2004. Former project leader A.J. (Tony) Rossini
|
||||
(<rossini@blindglobe.net>) did the initial port to XEmacs and has been
|
||||
the primary coder. Martin Maechler (<maechler@stat.math.ethz.ch>) and
|
||||
Kurt Hornik (<Kurt.Hornik@R-project.org>) have assisted with the S
|
||||
family and XLispStat. Stephen Eglen (<stephen@gnu.org>) has worked
|
||||
mostly on R support. Richard M. Heiberger (<rmh@temple.edu>) has
|
||||
assisted with S/S-PLUS development for Windows. Richard and Rodney A.
|
||||
Sparapani (<rsparapa@mcw.edu>) have done much of the work improving SAS
|
||||
batch and interactive support. Rodney has also extended ESS to support
|
||||
BUGS/JAGS and has an interest in improving Stata support.
|
||||
|
||||
We are grateful to the previous developers of S-mode (Doug Bates, Ed
|
||||
Kademan, Frank Ritter, David M. Smith), SAS-mode (Tom Cook) and
|
||||
Stata-mode (Thomas Lumley).
|
||||
|
||||
* Menu:
|
||||
|
||||
* License::
|
||||
* Installation::
|
||||
* Starting up::
|
||||
* Current Features::
|
||||
* New Features::
|
||||
* Reporting Bugs::
|
||||
* Mailing Lists::
|
||||
* Authors::
|
||||
|
||||
|
||||
File: readme.info, Node: License, Next: Installation, Prev: General Information, Up: General Information
|
||||
|
||||
1.1 License
|
||||
===========
|
||||
|
||||
The source and documentation of ESS is free software. You can
|
||||
redistribute it and/or modify it under the terms of the GNU General
|
||||
Public License as published by the Free Software Foundation; either
|
||||
version 2, or (at your option) any later version.
|
||||
|
||||
ESS is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License in
|
||||
the file COPYING in the same directory as this file for more details.
|
||||
|
||||
|
||||
File: readme.info, Node: Installation, Next: Starting up, Prev: License, Up: General Information
|
||||
|
||||
1.2 Installation
|
||||
================
|
||||
|
||||
ESS supports GNU Emacs versions 25.1 and newer.
|
||||
|
||||
ESS is most likely to work with current/recent versions of the
|
||||
following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
|
||||
|
||||
To build the PDF documentation, you will need a version of TeX Live
|
||||
or texinfo that includes texi2dvi.
|
||||
|
||||
There are two main methods used for installing ESS. You may install
|
||||
from a third-party repository or from source code. Once you install it,
|
||||
you must also activate or load ESS in each Emacs session, though
|
||||
installation from a third-party repository likely takes care of that for
|
||||
you. See *note Activating and Loading ESS:: for more details.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Installing from a third-party repository::
|
||||
* Installing from source::
|
||||
* Activating and Loading ESS::
|
||||
* Check Installation::
|
||||
|
||||
|
||||
File: readme.info, Node: Installing from a third-party repository, Next: Installing from source
|
||||
|
||||
1.3 Installing from a third-party repository
|
||||
============================================
|
||||
|
||||
ESS is packaged by many third party repositories. Many GNU/Linux
|
||||
distributions package it, usually with the name "emacs-ess" or similar.
|
||||
|
||||
ESS is also available through Milkypostman’s Emacs Lisp Package
|
||||
Archive (MELPA), a popular repository for Emacs packages. Instructions
|
||||
on how to do so are found on MELPA's website (https://melpa.org/).
|
||||
MELPA also hosts MELPA-stable with stable ESS builds. You may choose
|
||||
between MELPA with the latest and greatest features (and bugs) or
|
||||
MELPA-stable, which may lag a bit behind but should be more stable.
|
||||
|
||||
After installing, users should make sure ESS is activated or loaded
|
||||
in each Emacs session. See *note Activating and Loading ESS::.
|
||||
Depending on install method, this may be taken care of automatically.
|
||||
|
||||
|
||||
File: readme.info, Node: Installing from source, Next: Activating and Loading ESS, Prev: Installing from a third-party repository
|
||||
|
||||
1.4 Installing from source
|
||||
==========================
|
||||
|
||||
Stable versions of ESS are available at the ESS web page
|
||||
(https://ess.r-project.org) as a .tgz file or .zip file. ESS releases
|
||||
are GPG-signed, you should check the signature by downloading the
|
||||
accompanying '.sig' file and doing:
|
||||
|
||||
gpg --verify ess-18.10.tgz.sig
|
||||
|
||||
Alternatively, you may download the git repository. ESS is currently
|
||||
hosted on GitHub: <https://github.com/emacs-ess/ESS>. 'git clone
|
||||
https://github.com/emacs-ess/ESS.git' will download it to a new
|
||||
directory 'ESS' in the current working directory.
|
||||
|
||||
We will refer to the location of the ESS source files as
|
||||
'/path/to/ESS/' hereafter.
|
||||
|
||||
After installing, users should make sure they activate or load ESS in
|
||||
each Emacs session, see *note Activating and Loading ESS::
|
||||
|
||||
Optionally, compile elisp files, build the documentation, and the
|
||||
autoloads:
|
||||
cd /path/to/ESS/
|
||||
make
|
||||
Without this step the documentation, reference card, and autoloads
|
||||
will not be available. Uncompiled ESS will also run slower.
|
||||
|
||||
Optionally, you may make ESS available to all users of a machine by
|
||||
installing it site-wide. To do so, run 'make install'. You might need
|
||||
administrative privileges:
|
||||
|
||||
make install
|
||||
|
||||
The files are installed into '/usr/share/emacs' directory. For this
|
||||
step to run correctly on macOS, you will need to adjust the 'PREFIX'
|
||||
path in 'Makeconf'. The necessary code and instructions are commented
|
||||
in that file.
|
||||
|
||||
|
||||
File: readme.info, Node: Activating and Loading ESS, Next: Check Installation, Prev: Installing from source
|
||||
|
||||
1.5 Activating and Loading ESS
|
||||
==============================
|
||||
|
||||
After installing ESS, you must activate or load it each Emacs session.
|
||||
ESS can be autoloaded, and if you used a third-party repository (such as
|
||||
your Linux distribution or MELPA) to install, you can likely skip this
|
||||
section and proceed directly to *note Check Installation::
|
||||
|
||||
Otherwise, you may need to add the path to ESS to 'load-path' with:
|
||||
|
||||
(add-to-list 'load-path "/path/to/ESS/lisp")
|
||||
|
||||
You then need to decide whether to take advantage of deferred loading
|
||||
(which will result in a faster Emacs startup time) or require ESS when
|
||||
Emacs is loaded. To autoload ESS when needed (note that if installed
|
||||
from source, you must have run 'make'):
|
||||
|
||||
(load "ess-autoloads")
|
||||
|
||||
To require ESS on startup, you can either put
|
||||
|
||||
(require 'ess-site)
|
||||
|
||||
or
|
||||
|
||||
(require 'ess-r-mode)
|
||||
|
||||
In your configuration file, depending on whether you want all ESS
|
||||
features or only R related features.
|
||||
|
||||
|
||||
File: readme.info, Node: Check Installation, Prev: Activating and Loading ESS
|
||||
|
||||
1.6 Check Installation
|
||||
======================
|
||||
|
||||
Restart Emacs and check that ESS was loaded from a correct location with
|
||||
'M-x ess-version'.
|
||||
|
||||
|
||||
File: readme.info, Node: Starting up, Next: Current Features, Prev: Installation, Up: General Information
|
||||
|
||||
1.7 Starting an ESS process
|
||||
===========================
|
||||
|
||||
To start an S session on Unix or on Windows when you use the Cygwin bash
|
||||
shell, simply type 'M-x S RET'.
|
||||
|
||||
To start an S session on Windows when you use the MSDOS prompt shell,
|
||||
simply type 'M-x S+6-msdos RET'.
|
||||
|
||||
|
||||
File: readme.info, Node: Current Features, Next: New Features, Prev: Starting up, Up: General Information
|
||||
|
||||
1.8 Current Features
|
||||
====================
|
||||
|
||||
* Languages Supported:
|
||||
* S family (R, S, and S+ AKA S-PLUS)
|
||||
* SAS
|
||||
* BUGS/JAGS
|
||||
* Stata
|
||||
* Julia
|
||||
* Editing source code (S family, SAS, BUGS/JAGS, Stata, Julia)
|
||||
* Syntactic indentation and highlighting of source code
|
||||
* Partial evaluation of code
|
||||
* Loading and error-checking of code
|
||||
* Source code revision maintenance
|
||||
* Batch execution (SAS, BUGS/JAGS)
|
||||
* Use of imenu to provide links to appropriate functions
|
||||
* Interacting with the process (S family, SAS, Stata, Julia)
|
||||
* Command-line editing
|
||||
* Searchable Command history
|
||||
* Command-line completion of S family object names and file
|
||||
names
|
||||
* Quick access to object lists and search lists
|
||||
* Transcript recording
|
||||
* Interface to the help system
|
||||
* Transcript manipulation (S family, Stata)
|
||||
* Recording and saving transcript files
|
||||
* Manipulating and editing saved transcripts
|
||||
* Re-evaluating commands from transcript files
|
||||
* Interaction with Help Pages and other Documentation (R)
|
||||
* Fast Navigation
|
||||
* Sending Examples to running ESS process.
|
||||
* Fast Transfer to Further Help Pages
|
||||
* Help File Editing (R)
|
||||
* Syntactic indentation and highlighting of source code.
|
||||
* Sending Examples to running ESS process.
|
||||
* Previewing
|
||||
|
||||
|
||||
File: readme.info, Node: New Features, Next: Reporting Bugs, Prev: Current Features, Up: General Information
|
||||
|
||||
1.9 New Features
|
||||
================
|
||||
|
||||
Changes and New Features in 19.04 (unreleased):
|
||||
|
||||
* ESS[R]: Automatic offsetting of R process output is now disabled by
|
||||
default because it produces undesirable output in some situations.
|
||||
To re-enable, set 'inferior-ess-fix-misaligned-output' to t.
|
||||
|
||||
* ESS[R]: Improved 'xref' lookup ('M-.'). Function locations are now
|
||||
always detected for package libraries listed in
|
||||
'ess-r-package-library-paths'.
|
||||
|
||||
* ESS[R]: Evaluated lines starting with the Roxygen prefix are now
|
||||
always stripped from the prefix, so they can be sent to the process
|
||||
easily. Previously, this was only the case inside the 'examples'
|
||||
field. Since roxygen is switching to R markdown, it becomes useful
|
||||
to evaluate chunks of R outside examples.
|
||||
|
||||
* stata support is now obsolete since we were unable to elicit FSF
|
||||
paperwork from some of the original authors: see the lisp/obsolete
|
||||
sub-directory on the ESS github repo
|
||||
|
||||
* 'ess-set-working-directory' no longer changes the active directory
|
||||
(as defined by the buffer-local variable 'default-directory') of
|
||||
the buffer where the command is called. Instead, the active
|
||||
directory of the inferior buffer is updated to the new working
|
||||
directory.
|
||||
|
||||
* The default of ess-eval-visibly is now ''nowait'. With this change
|
||||
you should no longer experience freezes while evaluating code.
|
||||
|
||||
* ESS[R]: There is a new menu entry for reloading the R process. It
|
||||
is otherwise bound to 'C-c C-e C-r'. Reloading now reuses the same
|
||||
process name and start arguments that were used to start the
|
||||
process.
|
||||
|
||||
* iESS: Process runners now return the inferior buffer. Note that
|
||||
callers of inferior runners should not assume that the current
|
||||
buffer has been set to the inferior buffer. Instead, use
|
||||
'with-current-buffer' with the return value of the inferior.
|
||||
|
||||
* iESS[SAS]: The SAS keymap was only set in iESS buffers called
|
||||
'*SAS*'. This is now fixed.
|
||||
|
||||
* ESS[R]: Fixed longstanding indentation issues involving '::' and
|
||||
':::' operators.
|
||||
|
||||
* Implement a more reliable check for the process busy state.
|
||||
Background actions such as completion and directory synchronization
|
||||
should not block the process and should not cause printing of the
|
||||
extraneous output to the interpreter.
|
||||
|
||||
* Activate 'goto-address-mode' for url and email highlighting in
|
||||
inferior buffers.
|
||||
|
||||
* 'smart-underscore' and 'ess-smart-S-assign-key' have been removed.
|
||||
Users who liked the previous behavior (i.e. underscore inserting
|
||||
"<-") should bind 'ess-insert-assign' to the underscore in their
|
||||
Emacs initialization file. For example, '(define-key
|
||||
ess-r-mode-map "_" #'ess-insert-assign)' and '(define-key
|
||||
inferior-ess-r-mode-map "_" #'ess-insert-assign)' will activate it
|
||||
in all ESS R buffers.
|
||||
|
||||
* ESS major modes are now defined using 'define-derived-mode'. This
|
||||
makes ESS major modes respect modern conventions such as having
|
||||
<language>-mode-hook and <language>-mode-map. Users are encouraged
|
||||
to place customizations under the appropriate mode.
|
||||
|
||||
* New option ess-auto-width controls setting the width option on
|
||||
window changes. Users can change it to 'frame, 'window, or an
|
||||
integer. See the documentation for details.
|
||||
'ess-auto-width-visible' controls visibility.
|
||||
|
||||
* ESS now respects 'display-buffer-alist'. Users can now use
|
||||
'display-buffer-alist' to manage how and where windows appear. For
|
||||
more information and examples, see *Note (ess)Controlling buffer
|
||||
display::.
|
||||
|
||||
* 'ess-roxy-mode' can now be enabled in non-R buffers. This is
|
||||
primarily intended to support roxygen documentation for cpp
|
||||
buffers. Preview functionality is not supported outside R buffers.
|
||||
|
||||
* ESS[R]: DESCRIPTION files now open in 'conf-colon-mode'.
|
||||
|
||||
* 'ess-style' now has effects when set as a file or directory local
|
||||
variable.
|
||||
|
||||
* 'ess-default-style' is now obsolete, use 'ess-style' instead.
|
||||
|
||||
* Options for 'ess-gen-proc-buffer-name-function' have been renamed.
|
||||
ess-gen-proc-buffer-name:projectile-or-simple was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-simple and
|
||||
ess-gen-proc-buffer-name:projectile-or-directory was renamed to
|
||||
ess-gen-proc-buffer-name:project-or-directory. As the name
|
||||
suggests, these now rely on project.el (included with Emacs) rather
|
||||
than projectile.el, which is a third-party package.
|
||||
|
||||
* Eldoc fully honors 'eldoc-echo-area-use-multiline-p'
|
||||
|
||||
* ESS[R]: 'ess-r-rhub-check-package' gained new 'RECOMMENDED'.
|
||||
|
||||
* ESS[R]: devtools commands ask about saving modified buffers before
|
||||
running. Users can disable the questioning with
|
||||
'ess-save-silently'.
|
||||
|
||||
* ESS[R] help pages now provide links to other help topics. This is
|
||||
similar with what you would see with, for example
|
||||
'options(help_type = ``html'')' but works with the plain-text
|
||||
version as well. This only works with 'options(useFancyQuotes =
|
||||
TRUE)' (the default).
|
||||
|
||||
* 'ess-rdired' buffers now derive from tabulated-list-mode. They
|
||||
should look better and be a bit faster overall. The size column
|
||||
now displays object sizes in bytes.
|
||||
|
||||
* 'ess-rdired' buffers now auto-update. The frequency is governed by
|
||||
the new option 'ess-rdired-auto-update-interval'.
|
||||
|
||||
* ESS[R]: 'electric-layout-mode' is now supported. This
|
||||
automatically inserts a newline after an opening curly brace in R
|
||||
buffers. To enable it, customize 'ess-r-mode-hook'.
|
||||
|
||||
* ESS[R]: imenu now supports assignment with the equals sign.
|
||||
|
||||
* ESS[Rd]: Rd no longer writes abbrevs to user's abbrev file.
|
||||
|
||||
* ESS removed support for many unused languages. This includes old
|
||||
versions of S+, ARC, OMG, VST, and XLS.
|
||||
|
||||
* ess-r-runner-prefixes was modified to find R-4 and later.
|
||||
|
||||
The following have been made obsolete or removed, see their
|
||||
documentation for more detail:
|
||||
|
||||
* Libraries for literate data analysis are obsolete and not loaded by
|
||||
default. This includes 'ess-noweb', 'ess-swv', and related
|
||||
functionality like 'Rnw-mode'. Users are encouraged to switch to
|
||||
one of several other packages that deal with these modes. For
|
||||
example, polymode <https://github.com/polymode/poly-R/>,
|
||||
<https://polymode.github.io/>, or markdown-mode with edit-indirect
|
||||
<https://jblevins.org/projects/markdown-mode>.
|
||||
|
||||
* Support for 'auto-complete' is obsolete. The 'auto-complete'
|
||||
package is unmaintained and so ESS support is now obsolete. Users
|
||||
are encouraged to switch to 'company-mode' instead.
|
||||
|
||||
* User options for controlling display of buffers. This includes
|
||||
'ess-show-buffer-action', 'inferior-ess-same-window',
|
||||
'inferior-ess-own-frame', and 'inferior-ess-frame-alist'. See
|
||||
above about ESS respecting 'display-buffer-alist'.
|
||||
|
||||
* Variables 'ess-tab-always-indent' and 'ess-tab-complete-in-script'.
|
||||
Use the Emacs-wide setting of 'tab-always-indent' instead.
|
||||
|
||||
* 'inferior-ess-*-start-file' variables. All modes except Stata did
|
||||
not respect customization of this variable. In order to load a
|
||||
file on startup, you should put a function on
|
||||
'ess-*-post-run-hook'.
|
||||
|
||||
Bug Fixes in 18.10.3:
|
||||
* More 'Makefile' fixes, notably installing '*.el's.
|
||||
|
||||
Bug Fixes in 18.10.2:
|
||||
* ESS[R] Fix namespace evaluation in non-installed packages.
|
||||
Evaluation is directed into GlobalEnv as originally intended.
|
||||
* 'Makefile' fixes, notably for 'make install' and including full
|
||||
docs in the tarballs.
|
||||
|
||||
Bug Fixes in 18.10-1:
|
||||
* New functions 'ess-eval-line-visibly-and-step' ('C-c C-n' and
|
||||
'ess-eval-region-or-line-visibly-and-step' ('C-RET') which behave
|
||||
as the old versions of 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step'.
|
||||
|
||||
Changes and New Features in 18.10:
|
||||
|
||||
* This is the last release to support Emacs older than 25.1. Going
|
||||
forward, only GNU Emacs 25.1 and newer will be supported. Soon
|
||||
after this release, support for older Emacs versions will be
|
||||
dropped from the git master branch. Note that MELPA uses the git
|
||||
master branch to produce ESS snapshots, so if you are using Emacs <
|
||||
25.1 from MELPA and are unable to upgrade, you should switch to
|
||||
MELPA-stable.
|
||||
|
||||
* ESS now displays the language dialect in the mode-line. So, for
|
||||
example, R buffers will now show ESS[R] rather than ESS[S].
|
||||
|
||||
* The ESS manual has been updated and revised.
|
||||
|
||||
* The ESS initialization process has been further streamlined. If
|
||||
you update the autoloads (which installation from 'package-install'
|
||||
does), you should not need to '(require 'ess-site)' at all, as
|
||||
autoloads should automatically load ESS when it is needed (e.g.
|
||||
the first time an R buffer is opened). In order to defer loading
|
||||
your ESS config, you may want to do something like
|
||||
'(with-require-after-load "ess" <ess-config-here>)' in your Emacs
|
||||
init file. Users of the popular 'use-package' Emacs package can
|
||||
now do '(use-package ess :defer t)' to take advantage of this
|
||||
behavior. For more information on this feature, see *Note
|
||||
(ess)Activating and Loading ESS::.
|
||||
|
||||
* ESS now respects Emacs conventions for keybindings. This means
|
||||
that The 'C-c [letter]' bindings have been removed. This affects
|
||||
'C-c h', which was bound to 'ess-eval-line-and-step-invisibly' in
|
||||
'sas-mode-local-map'; 'C-c f', which was bound to
|
||||
'ess-insert-function-outline' in 'ess-add-MM-keys'; and 'C-c h',
|
||||
which was bound to 'ess-handy-commands' in 'Rd-mode-map',
|
||||
'ess-noweb-minor-mode-map', and 'ess-help-mode-map'
|
||||
|
||||
* Functions 'ess-eval-line-and-step' and
|
||||
'ess-eval-region-or-line-and-step' now behave consistently with
|
||||
other evaluation function inside a package.
|
||||
|
||||
* ESS[R]: 'ess-r-package-use-dir' now works with any mode. This sets
|
||||
the working directory to the root of the current package including
|
||||
for example C or C++ files within '/src').
|
||||
|
||||
* ESS[R]: Long + + prompts in the inferior no longer offset output.
|
||||
|
||||
* ESS[R]: New option 'strip' for 'inferior-ess-replace-long+'. This
|
||||
strips the entire + + sequence.
|
||||
|
||||
* ESS modes now inherit from 'prog-mode'. In the next release, ESS
|
||||
modes will use 'define-derived-mode' so that each mode will have
|
||||
(for example) its own hooks and keymaps.
|
||||
|
||||
* ESS[R]: Supports flymake in R buffers for Emacs 26 and newer.
|
||||
Users need to install the 'lintr' package to use it. Customizable
|
||||
options include 'ess-use-flymake', 'ess-r-flymake-linters', and
|
||||
'ess-r-flymake-lintr-cache'.
|
||||
|
||||
* ESS[R]: Gained support for xref in Emacs 25+ *Note (emacs)Xref::.
|
||||
|
||||
* ESS[R]: The startup screen is cleaner. It also displays the
|
||||
startup directory with an explicit 'setwd()'.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[R]: 'Makevars' files open with 'makefile-mode'.
|
||||
|
||||
* New variable 'ess-write-to-dribble'. This allows users to disable
|
||||
the dribble ('*ESS*') buffer if they wish.
|
||||
|
||||
* All of the '*-program-name' variables have been renamed to
|
||||
'*-program'. Users who previously customized e.g.
|
||||
'inferior-ess-R-program-name' will need to update their
|
||||
customization to 'inferior-ess-R-program'. These variables are
|
||||
treated as risky variables.
|
||||
|
||||
* 'ess-smart-S-assign' was renamed to 'ess-insert-assign'. It
|
||||
provides similar functionality but for any keybinding, not just
|
||||
'_'. For instance if you bind it to ';', repeated invocations
|
||||
cycle through between assignment and inserting ';'.
|
||||
|
||||
* 'C-c C-=' is now bound to 'ess-cycle-assign' by default. See the
|
||||
documentation for details. New user customization option
|
||||
'ess-assign-list' controls which assignment operators are cycled.
|
||||
|
||||
* ESS[R] In remote sessions, the ESSR package is now fetched from
|
||||
GitHub.
|
||||
|
||||
* Commands that send the region to the inferior process now deal with
|
||||
rectangular regions. See the documentation of 'ess-eval-region'
|
||||
for details. This only works on Emacs 25.1 and newer.
|
||||
|
||||
* ESS[R]: Improvements to interacting with iESS in non-R files.
|
||||
Interaction with inferior process in non-R files within packages
|
||||
(for instance C or C++ files) has been improved. This is a work in
|
||||
progress.
|
||||
|
||||
* ESS[R]: Changing the working directory is now always reflected in
|
||||
the process buffer.
|
||||
|
||||
* ESS[JAGS]: *.jog and *.jmd files no longer automatically open in
|
||||
JAGS mode.
|
||||
|
||||
Many improvements to fontification:
|
||||
|
||||
* Improved customization for faces. ESS now provides custom faces
|
||||
for (nearly) all faces used and places face customization options
|
||||
into their own group. Users can customize these options using 'M-x
|
||||
customize-group RET ess-faces'.
|
||||
|
||||
* Many new keywords were added to 'ess-R-keywords' and
|
||||
'ess-R-modifiers'. See the documentation for details.
|
||||
|
||||
* ESS[R]: 'in' is now only fontified when inside a 'for' construct.
|
||||
This avoids spurious fontification, especially in the output buffer
|
||||
where 'in' is a common English word.
|
||||
|
||||
* ESS: Font-lock keywords are now generated lazily. That means you
|
||||
can now add or remove keywords from variables like 'ess-R-keywords'
|
||||
in your Emacs configuration file after loading ESS (i.e. in the
|
||||
':config' section for 'use-package' users).
|
||||
|
||||
* ESS[R]: Fontification of roxygen '@param' keywords now supports
|
||||
comma-separated parameters.
|
||||
|
||||
* ESS[R]: Certain keywords are only fontified if followed by a
|
||||
parenthesis. Function-like keywords such as 'if ()' or 'stop()'
|
||||
are no longer fontified as keyword if not followed by an opening
|
||||
parenthesis. The same holds for search path modifiers like
|
||||
'library()' or 'require()'.
|
||||
|
||||
* ESS[R]: Fixed fontification toggling. Especially certain syntactic
|
||||
elements such as '%op%' operators and backquoted function
|
||||
definitions.
|
||||
|
||||
* ESS[R]: 'ess-font-lock-toggle-keyword' can be called interactively.
|
||||
This command asks with completion for a font-lock group to toggle.
|
||||
This functionality is equivalent to the font-lock menu.
|
||||
|
||||
Notable bug fixes:
|
||||
|
||||
* 'prettify-symbols-mode' no longer breaks indentation. This is
|
||||
accomplished by having the pretty symbols occupy the same number of
|
||||
characters as their non-pretty cousins. You may customize the new
|
||||
variable 'ess-r-prettify-symbols' to control this behavior.
|
||||
|
||||
* ESS: Inferior process buffers are now always displayed on startup.
|
||||
Additionally, they don't hang Emacs on failures.
|
||||
|
||||
Obsolete libraries, functions, and variables:
|
||||
|
||||
* The 'ess-r-args.el' library has been obsoleted and will be removed
|
||||
in the next release. Use 'eldoc-mode' instead, which is on by
|
||||
default.
|
||||
|
||||
* Functions and options dealing with the smart assign key are
|
||||
obsolete. The following functions have been made obsolete and will
|
||||
be removed in the next release of ESS: 'ess-smart-S-assign',
|
||||
'ess-toggle-S-assign', 'ess-toggle-S-assign-key',
|
||||
'ess-disable-smart-S-assign'.
|
||||
|
||||
The variable 'ess-smart-S-assign-key' is now deprecated and will be
|
||||
removed in the next release. If you would like to continue using
|
||||
'_' for inserting assign in future releases, please bind
|
||||
'ess-insert-assign' in 'ess-mode-map' the normal way.
|
||||
|
||||
* ESS[S]: Variable 'ess-s-versions-list' is obsolete and ignored.
|
||||
Use 'ess-s-versions' instead. You may pass arguments by starting
|
||||
the inferior process with the universal argument.
|
||||
|
||||
Changes and New Features in 17.11:
|
||||
|
||||
* The ESS initialization process has been streamlined. You can now
|
||||
load the R and Stata modes independently from the rest of ESS. Just
|
||||
put '(require 'ess-r-mode)' or '(require 'ess-stata-mode)' in your
|
||||
init file. This is for experienced Emacs users as this requires
|
||||
setting up autoloads for '.R' files manually. We will keep
|
||||
maintaining 'ess-site' for easy loading of all ESS features.
|
||||
|
||||
* Reloading and quitting the process is now more robust. If no
|
||||
process is attached, ESS now switches automatically to one
|
||||
(prompting you for selection if there are several running).
|
||||
Reloading and quitting will now work during a debug session or when
|
||||
R is prompting for input (for instance after a crash). Finally,
|
||||
the window configuration is saved and restored after reloading to
|
||||
prevent the buffer of the new process from capturing the cursor.
|
||||
|
||||
* ESS[R]: New command 'ess-r-package-use-dir'. It sets the working
|
||||
directory of the current process to the current package directory.
|
||||
|
||||
* ESS[R] Lookup for references in inferior buffers has been improved.
|
||||
New variable 'ess-r-package-source-roots' contains package
|
||||
sub-directories which are searched recursively during the file
|
||||
lookup point. Directories in 'ess-tracebug-search-path' are now
|
||||
also searched recursively.
|
||||
|
||||
* ESS[R] Namespaced evaluation is now automatically enabled only in
|
||||
the 'R/' directory. This way ESS will not attempt to update
|
||||
function definitions from a package if you are working from e.g. a
|
||||
test file.
|
||||
|
||||
Changes and New Features in 16.10:
|
||||
|
||||
* ESS[R]: Syntax highlighting is now more consistent. Backquoted
|
||||
names are not fontified as strings (since they really are
|
||||
identifiers). Furthermore they are now correctly recognized when
|
||||
they are function definitions or function calls.
|
||||
* ESS[R]: Backquoted names and '%op%' operators are recognized as
|
||||
sexp. This is useful for code navigation, e.g. with 'C-M-f' and
|
||||
'C-M-b'.
|
||||
* ESS[R]: Integration of outline mode with roxygen examples fields.
|
||||
You can use outline mode's code folding commands to fold the
|
||||
examples field. This is especially nice to use with well
|
||||
documented packages with long examples set. Set
|
||||
'ess-roxy-fold-examples' to non-nil to automatically fold the
|
||||
examples field when you open a buffer.
|
||||
* ESS[R]: New experimental feature: syntax highlighting in roxygen
|
||||
examples fields. This is turned off by default. Set
|
||||
'ess-roxy-fontify-examples' to non-nil to try it out.
|
||||
* ESS[R]: New package development command 'ess-r-devtools-ask' bound
|
||||
to 'C-c C-w C-a'. It asks with completion for any devtools command
|
||||
that takes 'pkg' as argument.
|
||||
* ESS[R]: New command 'C-c C-e C-r' to reload the inferior process.
|
||||
Currently only implemented for R. The R method runs
|
||||
'inferior-ess-r-reload-hook' on reloading.
|
||||
* ESS[R]: 'ess-r-package-mode' is now activated in non-file buffers
|
||||
as well.
|
||||
|
||||
Bug fixes in 16.10:
|
||||
* ESS[R]: Fix broken (un)flagging for debugging inside packages
|
||||
* ESS[R]: Fixes (and improvements) in Package development
|
||||
* ESS[R]: Completion no longer produces '...=' inside 'list( )'.
|
||||
* ESS[R]: Better debugging and tracing in packages.
|
||||
* ESS[R]: Better detection of symbols at point.
|
||||
* ESS[R]: No more spurious warnings on deletion of temporary files.
|
||||
* ESS[julia]: help and completion work (better)
|
||||
* ESS[julia]: available via 'ess-remote'
|
||||
|
||||
Changes and New Features in 16.04:
|
||||
|
||||
* ESS[R]: 'developer' functionality has been refactored. The new
|
||||
user interface consists of a single command
|
||||
'ess-r-set-evaluation-env' bound by default to 'C-c C-t C-s'. Once
|
||||
an evaluation environment has been set with, all subsequent ESS
|
||||
evaluation will source the code into that environment. By default,
|
||||
for file within R packages the evaluation environment is set to the
|
||||
package environment. Set 'ess-r-package-auto-set-evaluation-env'
|
||||
to 'nil' to disable this.
|
||||
* ESS[R]: New 'ess-r-package-mode' This development mode provides
|
||||
features to make package development easier. Currently, most of
|
||||
the commands are based on the 'devtools' packages and are
|
||||
accessible with 'C-c C-w' prefix. See the documentation of
|
||||
'ess-r-package-mode' function for all available commands. With
|
||||
'C-u' prefix each command asks for extra arguments to the
|
||||
underlying devtools function. This mode is automatically enabled
|
||||
in all files within R packages and is indicated with '[pkg:NAME]'
|
||||
in the mode-line.
|
||||
* ESS[R]: Help lookup has been improved. It is now possible to get
|
||||
help for namespaced objects such as pkg::foobar. Furthermore, ESS
|
||||
recognizes more reliably when you change 'options('html_type')'.
|
||||
* ESS[R]: New specialized breakpoints for debugging magrittr pipes
|
||||
* ESS: ESS now implements a simple message passing interface to
|
||||
communicate between ESS and inferior process.
|
||||
|
||||
Bug fixes in 16.04:
|
||||
* ESS[R]: Roxygen blocks with backtics are now correctly filled
|
||||
* ESS[R]: Don't skip breakpoints in magrittr's 'debug_pipe'
|
||||
* ESS[R]: Error highlighting now understands 'testthat' type errors
|
||||
* ESS[Julia]: Added getwd and setwd generic commands
|
||||
|
||||
|
||||
File: readme.info, Node: Reporting Bugs, Next: Mailing Lists, Prev: New Features, Up: General Information
|
||||
|
||||
1.10 Reporting Bugs
|
||||
===================
|
||||
|
||||
Please send bug reports, suggestions etc. to <ESS-bugs@r-project.org>,
|
||||
or post them on our github issue tracker
|
||||
(https://github.com/emacs-ess/ESS/issues)
|
||||
|
||||
The easiest way to do this is within Emacs by typing
|
||||
|
||||
'M-x ess-submit-bug-report'
|
||||
|
||||
This also gives the maintainers valuable information about your
|
||||
installation which may help us to identify or even fix the bug.
|
||||
|
||||
If Emacs reports an error, backtraces can help us debug the problem.
|
||||
Type "M-x set-variable RET debug-on-error RET t RET". Then run the
|
||||
command that causes the error and you should see a *Backtrace* buffer
|
||||
containing debug information; send us that buffer.
|
||||
|
||||
Note that comments, suggestions, words of praise and large cash
|
||||
donations are also more than welcome.
|
||||
|
||||
|
||||
File: readme.info, Node: Mailing Lists, Next: Authors, Prev: Reporting Bugs, Up: General Information
|
||||
|
||||
1.11 Mailing Lists
|
||||
==================
|
||||
|
||||
There is a mailing list for discussions and announcements relating to
|
||||
ESS. Join the list by sending an e-mail with "subscribe ess-help" (or
|
||||
"help") in the body to <ess-help-request@r-project.org>; contributions
|
||||
to the list may be mailed to <ess-help@r-project.org>. Rest assured,
|
||||
this is a fairly low-volume mailing list.
|
||||
|
||||
The purposes of the mailing list include
|
||||
|
||||
* helping users of ESS to get along with it.
|
||||
* discussing aspects of using ESS.
|
||||
* suggestions for improvements.
|
||||
* announcements of new releases of ESS.
|
||||
* posting small patches to ESS.
|
||||
|
||||
|
||||
File: readme.info, Node: Authors, Prev: Mailing Lists, Up: General Information
|
||||
|
||||
1.12 Authors
|
||||
============
|
||||
|
||||
* A.J. Rossini (mailto:blindglobe@gmail.com)
|
||||
* Richard M. Heiberger (mailto:rmh@temple.edu)
|
||||
* Kurt Hornik (mailto:Kurt.Hornik@R-project.org)
|
||||
* Martin Maechler (mailto:maechler@stat.math.ethz.ch)
|
||||
* Rodney A. Sparapani (mailto:rsparapa@mcw.edu)
|
||||
* Stephen Eglen (mailto:stephen@gnu.org)
|
||||
* Sebastian P. Luque (mailto:spluque@gmail.com)
|
||||
* Henning Redestig (mailto:henning.red@googlemail.com)
|
||||
* Vitalie Spinu (mailto:spinuvit@gmail.com)
|
||||
* Lionel Henry (mailto:lionel.hry@gmail.com)
|
||||
* J. Alexander Branham (mailto:alex.branham@gmail.com)
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: General Information73
|
||||
Node: License1711
|
||||
Node: Installation2381
|
||||
Node: Installing from a third-party repository3298
|
||||
Node: Installing from source4248
|
||||
Node: Activating and Loading ESS5843
|
||||
Node: Check Installation6920
|
||||
Node: Starting up7143
|
||||
Node: Current Features7526
|
||||
Node: New Features9076
|
||||
Node: Reporting Bugs30135
|
||||
Node: Mailing Lists31033
|
||||
Node: Authors31749
|
||||
|
||||
End Tag Table
|
||||
15
lisp/ess/requires.info
Normal file
15
lisp/ess/requires.info
Normal file
@@ -0,0 +1,15 @@
|
||||
This is requires.info, produced by makeinfo version 6.5 from
|
||||
requires.texi.
|
||||
|
||||
ESS supports GNU Emacs versions 25.1 and newer.
|
||||
|
||||
ESS is most likely to work with current/recent versions of the
|
||||
following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
|
||||
|
||||
To build the PDF documentation, you will need a version of TeX Live
|
||||
or texinfo that includes texi2dvi.
|
||||
|
||||
|
||||
Tag Table:
|
||||
|
||||
End Tag Table
|
||||
Reference in New Issue
Block a user